#![allow(non_snake_case)]
#![allow(unused)]
use crate::error::Result;
use crate::utils::*;
use super::super::formatter::*;
use super::super::instruction::*;
use super::super::operand::*;
use super::super::consts::*;
use super::super::config::*;
use super::super::decoder::*;
pub(crate) struct IclassMovIA1;
impl IclassMovIA1 {
pub(crate) fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
let imm12 = (data >> 0) & 4095;
let imm12_post = imm12;
let S = (data >> 20) & 1;
let S_post = S;
let opc = (data >> 21) & 3;
let opc_post = opc;
let Rd = (data >> 12) & 15;
let Rd_post = Rd;
let Rn = (data >> 16) & 15;
let Rn_post = Rn;
let field_27 = (data >> 23) & 31;
let field_27_post = field_27;
let cond = (data >> 28) & 15;
let cond_post = cond;
if (S_post == 0) {
return MovIA1::decode(data as u32, decoder);
}
if (S_post == 1) {
return MovsIA1::decode(data as u32, decoder);
}
unreachable!()
}
}
pub struct MovIA1;
impl MovIA1 {
pub fn mnemonic(_instr: &Instruction) -> Mnemonic {
Mnemonic::MOV
}
pub fn condition(_instr: &Instruction) -> ConditionalInstruction {
ConditionalInstruction::Condition(0, false, false)
}
pub fn size(instr: &Instruction) -> usize {
4
}
pub fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
let cond = (data >> 28) & 15;
let cond_post = cond;
let Rd = (data >> 12) & 15;
let Rd_post = Rd;
let imm12 = (data >> 0) & 4095;
let imm12_post = imm12;
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_post = imm12;
let op_2 = ModifiedImmediate::decode(imm12_post);
let mut instr = Instruction::builder(Code::MOV_i_A1)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
Ok(instr)
}
pub fn encode(instr: &Instruction, buf: &mut Vec<u8>) -> Result<usize> {
let cond_pre = instr.op0().as_mnemonic_condition()?.encode();
let Rd_pre = instr.op1().as_register()?.encode();
let imm12_pre = instr.op2().as_modified_immediate()?.encode();
let cond = (cond_pre & 15);
let Rd = (Rd_pre & 15);
let imm12 = (imm12_pre & 4095);
let mut instr: u32 = 0b00000011101000000000000000000000;
instr |= (cond & 15) << 28;
instr |= (Rd & 15) << 12;
instr |= (imm12 & 4095) << 0;
let bytes = instr.to_le_bytes();
let len = bytes.len();
buf.extend(bytes);
Ok(len)
}
pub fn encode_block(instr: &mut Instruction, buf: &mut Vec<u8>, labels: &std::collections::HashMap<u64, u64>) -> Result<usize> {
Self::encode(instr, buf)
}
pub fn check_op0(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::MnemonicCondition(r) = op {
return Ok(())
}
todo!()
}
pub fn check_op1(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::Register(r) = op {
return Ok(())
}
todo!()
}
pub fn check_op2(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::ModifiedImmediate(i) = op {
if i.0 >= 16 {
todo!()
}
if i.1 >= 256 {
todo!()
}
return Ok(())
}
todo!()
}
pub fn check_op3(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op4(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op5(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op6(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn format(instr: &Instruction, fmt: &mut impl Formatter, output: &mut impl FormatterOutput, config: &Config) -> Result<()> {
fmt.format_mnemonic(output, &config.global, &config.instructions.mov_i_a1, &instr)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a1, &instr, 0)?;
fmt.format_qualifier(output, &config.global, &config.instructions.mov_i_a1, &instr, FormatterQualifier::Wide, true, false)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a1, &instr, FormatterTextKind::Space)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a1, &instr, 1)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a1, &instr, FormatterTextKind::Comma)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a1, &instr, FormatterTextKind::NumSign)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a1, &instr, 2)?;
Ok(())
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovIA1Aliases {
None,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovIA1Encodings {
None
}
pub struct MovsIA1;
impl MovsIA1 {
pub fn mnemonic(_instr: &Instruction) -> Mnemonic {
Mnemonic::MOVS
}
pub fn condition(_instr: &Instruction) -> ConditionalInstruction {
ConditionalInstruction::Condition(0, false, false)
}
pub fn size(instr: &Instruction) -> usize {
4
}
pub fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
let cond = (data >> 28) & 15;
let cond_post = cond;
let Rd = (data >> 12) & 15;
let Rd_post = Rd;
let imm12 = (data >> 0) & 4095;
let imm12_post = imm12;
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_post = imm12;
let op_2 = ModifiedImmediate::decode(imm12_post);
let mut instr = Instruction::builder(Code::MOVS_i_A1)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
Ok(instr)
}
pub fn encode(instr: &Instruction, buf: &mut Vec<u8>) -> Result<usize> {
let cond_pre = instr.op0().as_mnemonic_condition()?.encode();
let Rd_pre = instr.op1().as_register()?.encode();
let imm12_pre = instr.op2().as_modified_immediate()?.encode();
let cond = (cond_pre & 15);
let Rd = (Rd_pre & 15);
let imm12 = (imm12_pre & 4095);
let mut instr: u32 = 0b00000011101100000000000000000000;
instr |= (cond & 15) << 28;
instr |= (Rd & 15) << 12;
instr |= (imm12 & 4095) << 0;
let bytes = instr.to_le_bytes();
let len = bytes.len();
buf.extend(bytes);
Ok(len)
}
pub fn encode_block(instr: &mut Instruction, buf: &mut Vec<u8>, labels: &std::collections::HashMap<u64, u64>) -> Result<usize> {
Self::encode(instr, buf)
}
pub fn check_op0(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::MnemonicCondition(r) = op {
return Ok(())
}
todo!()
}
pub fn check_op1(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::Register(r) = op {
return Ok(())
}
todo!()
}
pub fn check_op2(instr: &Instruction, op: &Operand) -> Result<()> {
if let Operand::ModifiedImmediate(i) = op {
if i.0 >= 16 {
todo!()
}
if i.1 >= 256 {
todo!()
}
return Ok(())
}
todo!()
}
pub fn check_op3(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op4(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op5(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn check_op6(instr: &Instruction, op: &Operand) -> Result<()> {
todo!()
}
pub fn format(instr: &Instruction, fmt: &mut impl Formatter, output: &mut impl FormatterOutput, config: &Config) -> Result<()> {
fmt.format_mnemonic(output, &config.global, &config.instructions.movs_i_a1, &instr)?;
fmt.format_operand(output, &config.global, &config.instructions.movs_i_a1, &instr, 0)?;
fmt.format_qualifier(output, &config.global, &config.instructions.movs_i_a1, &instr, FormatterQualifier::Wide, false, false)?;
fmt.format_punctuation(output, &config.global, &config.instructions.movs_i_a1, &instr, FormatterTextKind::Space)?;
fmt.format_operand(output, &config.global, &config.instructions.movs_i_a1, &instr, 1)?;
fmt.format_punctuation(output, &config.global, &config.instructions.movs_i_a1, &instr, FormatterTextKind::Comma)?;
fmt.format_punctuation(output, &config.global, &config.instructions.movs_i_a1, &instr, FormatterTextKind::NumSign)?;
fmt.format_operand(output, &config.global, &config.instructions.movs_i_a1, &instr, 2)?;
Ok(())
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovsIA1Aliases {
None,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovsIA1Encodings {
None
}
pub(crate) struct IclassMovIA2;
impl IclassMovIA2 {
pub(crate) fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
let imm12 = (data >> 0) & 4095;
let imm12_post = imm12;
let field_21 = (data >> 20) & 3;
let field_21_post = field_21;
let Rd = (data >> 12) & 15;
let Rd_post = Rd;
let field_25 = (data >> 25) & 1;
let field_25_post = field_25;
let field_27 = (data >> 26) & 3;
let field_27_post = field_27;
let field_24 = (data >> 23) & 3;
let field_24_post = field_24;
let cond = (data >> 28) & 15;
let cond_post = cond;
let imm4 = (data >> 16) & 15;
let imm4_post = imm4;
let H = (data >> 22) & 1;
let H_post = H;
return MovIA2::decode(data as u32, decoder);
unreachable!()
}
}
pub struct MovIA2;
impl MovIA2 {
pub fn mnemonic(instr: &Instruction) -> Mnemonic {
match instr.encoding {
Encoding::Alt1 => Mnemonic::MOV,
Encoding::Alt2 => Mnemonic::MOVW,
_ => todo!()
}
}
pub fn condition(instr: &Instruction) -> ConditionalInstruction {
match instr.encoding {
Encoding::Alt1 => {
ConditionalInstruction::Condition(0, false, false)
}
Encoding::Alt2 => {
ConditionalInstruction::Condition(0, false, false)
}
_ => todo!()
}
}
pub fn size(instr: &Instruction) -> usize {
match instr.encoding {
Encoding::Alt1 => 4,
Encoding::Alt2 => 4,
_ => todo!()
}
}
pub fn decode(data: u32, decoder: &mut Decoder) -> Result<Instruction> {
let cond = (data >> 28) & 15;
let cond_post = cond;
let imm4 = (data >> 16) & 15;
let imm4_post = imm4;
let Rd = (data >> 12) & 15;
let Rd_post = Rd;
let imm12 = (data >> 0) & 4095;
let imm12_post = imm12;
let cond_post = cond;
let imm12_imm4_post = (imm4 << 12) | imm12;
let Rd_post = Rd;
if let Some(encoding) = decoder.config.instructions.mov_i_a2.encodings {
match encoding {
MovIA2Encodings::Alt1 => {
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_imm4_post = (imm4 << 12) | imm12;
let op_2 = imm12_imm4_post as u32;
let instr = Instruction::builder_multi(Code::MOV_i_A2, Encoding::Alt1)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
return Ok(instr);
}
MovIA2Encodings::Alt2 => {
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_imm4_post = (imm4 << 12) | imm12;
let op_2 = imm12_imm4_post as u32;
let instr = Instruction::builder_multi(Code::MOV_i_A2, Encoding::Alt2)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
return Ok(instr);
}
}
}
if (!((is_modified_immediate(imm12_imm4_post.into())))) {
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_imm4_post = (imm4 << 12) | imm12;
let op_2 = imm12_imm4_post as u32;
let instr = Instruction::builder_multi(Code::MOV_i_A2, Encoding::Alt1)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
return Ok(instr);
}
if ((is_modified_immediate(imm12_imm4_post.into()))) {
let cond_post = cond;
let op_0 = MnemonicCondition::decode(cond_post)?;
let Rd_post = Rd;
let op_1 = Register::decode(Rd_post)?;
let imm12_imm4_post = (imm4 << 12) | imm12;
let op_2 = imm12_imm4_post as u32;
let instr = Instruction::builder_multi(Code::MOV_i_A2, Encoding::Alt2)
.operand(0, op_0)?
.operand(1, op_1)?
.operand(2, op_2)?
.build();
return Ok(instr);
}
unreachable!()
}
pub fn encode(instr: &Instruction, buf: &mut Vec<u8>) -> Result<usize> {
match instr.encoding {
Encoding::Alt1 => {
let cond_pre = instr.op0().as_mnemonic_condition()?.encode();
let Rd_pre = instr.op1().as_register()?.encode();
let imm12_imm4_pre = instr.op2().as_unsigned_immediate()? as u32;
let cond = (cond_pre & 15);
let Rd = (Rd_pre & 15);
let imm12_imm4_pre = imm12_imm4_pre;
let imm12 = (imm12_imm4_pre & 4095);
let imm4 = (imm12_imm4_pre >> 12) & 15;
let mut instr: u32 = 0b00000011000000000000000000000000;
instr |= (cond & 15) << 28;
instr |= (Rd & 15) << 12;
instr |= (imm12 & 4095) << 0;
instr |= (imm4 & 15) << 16;
let bytes = instr.to_le_bytes();
let len = bytes.len();
buf.extend(bytes);
Ok(len)
}
Encoding::Alt2 => {
let cond_pre = instr.op0().as_mnemonic_condition()?.encode();
let Rd_pre = instr.op1().as_register()?.encode();
let imm12_imm4_pre = instr.op2().as_unsigned_immediate()? as u32;
let cond = (cond_pre & 15);
let Rd = (Rd_pre & 15);
let imm12_imm4_pre = imm12_imm4_pre;
let imm12 = (imm12_imm4_pre & 4095);
let imm4 = (imm12_imm4_pre >> 12) & 15;
let mut instr: u32 = 0b00000011000000000000000000000000;
instr |= (cond & 15) << 28;
instr |= (Rd & 15) << 12;
instr |= (imm12 & 4095) << 0;
instr |= (imm4 & 15) << 16;
let bytes = instr.to_le_bytes();
let len = bytes.len();
buf.extend(bytes);
Ok(len)
}
_ => todo!()
}
}
pub fn encode_block(instr: &mut Instruction, buf: &mut Vec<u8>, labels: &std::collections::HashMap<u64, u64>) -> Result<usize> {
Self::encode(instr, buf)
}
pub fn check_op0(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
if let Operand::MnemonicCondition(r) = op {
return Ok(())
}
todo!()
}
Encoding::Alt2 => {
if let Operand::MnemonicCondition(r) = op {
return Ok(())
}
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op1(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
if let Operand::Register(r) = op {
return Ok(())
}
todo!()
}
Encoding::Alt2 => {
if let Operand::Register(r) = op {
return Ok(())
}
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op2(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
if let Operand::SignedImmediate(i) = op {
if !(0..=65535).contains(i) {
todo!()
}
return Ok(())
}
if let Operand::UnsignedImmediate(i) = op {
if !(0..=65535).contains(i) {
todo!()
}
return Ok(())
}
todo!()
}
Encoding::Alt2 => {
if let Operand::SignedImmediate(i) = op {
if !(0..=65535).contains(i) {
todo!()
}
return Ok(())
}
if let Operand::UnsignedImmediate(i) = op {
if !(0..=65535).contains(i) {
todo!()
}
return Ok(())
}
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op3(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
todo!()
}
Encoding::Alt2 => {
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op4(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
todo!()
}
Encoding::Alt2 => {
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op5(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
todo!()
}
Encoding::Alt2 => {
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn check_op6(instr: &Instruction, op: &Operand) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
todo!()
}
Encoding::Alt2 => {
todo!()
}
_ => todo!()
}
unreachable!()
}
pub fn format(instr: &Instruction, fmt: &mut impl Formatter, output: &mut impl FormatterOutput, config: &Config) -> Result<()> {
match instr.encoding {
Encoding::Alt1 => {
fmt.format_mnemonic(output, &config.global, &config.instructions.mov_i_a2, &instr)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 0)?;
fmt.format_qualifier(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterQualifier::Wide, true, false)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::Space)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 1)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::Comma)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::NumSign)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 2)?;
return Ok(());
}
Encoding::Alt2 => {
fmt.format_mnemonic(output, &config.global, &config.instructions.mov_i_a2, &instr)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 0)?;
fmt.format_qualifier(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterQualifier::Wide, false, false)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::Space)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 1)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::Comma)?;
fmt.format_punctuation(output, &config.global, &config.instructions.mov_i_a2, &instr, FormatterTextKind::NumSign)?;
fmt.format_operand(output, &config.global, &config.instructions.mov_i_a2, &instr, 2)?;
return Ok(());
}
_ => todo!()
}
unreachable!()
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovIA2Aliases {
None,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub enum MovIA2Encodings {
Alt1,
Alt2,
}