use super::consts::config::ConfigInstructions;
use super::instructions::*;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub struct Config {
pub global: ConfigGlobal,
pub instructions: ConfigInstructions,
}
impl Config {
pub fn new() -> Self {
Self::default()
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub struct ConfigGlobal {
pub syntax: FormatSyntaxGlobal,
pub qualifier: FormatQualifier,
pub aliases: FormatAliasGlobal,
}
impl ConfigGlobal {
pub fn new() -> Self {
Self::default()
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub struct ConfigInstruction<A, E> {
pub syntax: FormatSyntax,
pub qualifier: Option<FormatQualifier>,
pub aliases: Option<FormatAliasInstruction<A>>,
pub encodings: Option<E>,
}
impl<A, E> ConfigInstruction<A, E> {
pub fn new() -> Self {
Self::default()
}
}
impl<A, E> Default for ConfigInstruction<A, E> {
fn default() -> Self {
Self {
syntax: FormatSyntax::default(),
qualifier: None,
aliases: None,
encodings: None,
}
}
}
pub trait HasConfigInstruction {
fn syntax(&self) -> &FormatSyntax;
fn qualifier(&self) -> &Option<FormatQualifier>;
}
impl<A, E> HasConfigInstruction for ConfigInstruction<A, E> {
fn syntax(&self) -> &FormatSyntax {
&self.syntax
}
fn qualifier(&self) -> &Option<FormatQualifier> {
&self.qualifier
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub enum FormatAliasGlobal {
Never,
#[default]
Recommended,
Always,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub enum FormatAliasInstruction<A> {
Never,
#[default]
Recommended,
Preferred(A),
Always(A),
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub enum FormatQualifier {
Always,
WideOnly,
#[default]
Recommended,
Never,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub enum FormatInteger {
#[default]
DecimalSigned,
DecimalUnsigned,
HexadecimalSigned,
HexadecimalUnsigned,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub enum FormatSpecialRegister {
Lowercase,
#[default]
Recommended,
Uppercase,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub struct FormatSyntaxGlobal {
pub omit_src_dst_same_reg: bool,
pub omit_src_dst_diff_reg: bool,
pub omit_address_mode: bool,
pub positive_integer_format: FormatInteger,
pub negative_integer_format: FormatInteger,
pub special_register_format: FormatSpecialRegister,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
pub struct FormatSyntax {
pub omit_src_dst_same_reg: Option<bool>,
pub omit_src_dst_diff_reg: Option<bool>,
pub omit_address_mode: Option<bool>,
pub positive_integer_format: Option<FormatInteger>,
pub negative_integer_format: Option<FormatInteger>,
pub special_register_format: Option<FormatSpecialRegister>,
}
impl FormatSyntax {
pub fn new() -> Self {
Self::default()
}
pub fn get_omit_src_dst_same_reg(&self, global: &FormatSyntaxGlobal) -> bool {
if let Some(value) = self.omit_src_dst_same_reg {
return value;
}
global.omit_src_dst_same_reg
}
pub fn get_omit_src_dst_diff_reg(&self, global: &FormatSyntaxGlobal) -> bool {
if let Some(value) = self.omit_src_dst_diff_reg {
return value;
}
global.omit_src_dst_diff_reg
}
pub fn get_omit_address_mode(&self, global: &FormatSyntaxGlobal) -> bool {
if let Some(value) = self.omit_address_mode {
return value;
}
global.omit_address_mode
}
pub fn get_positive_integer_format(&self, global: &FormatSyntaxGlobal) -> FormatInteger {
if let Some(value) = self.positive_integer_format {
return value;
}
global.positive_integer_format
}
pub fn get_negative_integer_format(&self, global: &FormatSyntaxGlobal) -> FormatInteger {
if let Some(value) = self.negative_integer_format {
return value;
}
global.negative_integer_format
}
pub fn get_special_register_format(
&self,
global: &FormatSyntaxGlobal,
) -> FormatSpecialRegister {
if let Some(value) = self.special_register_format {
return value;
}
global.special_register_format
}
}
pub struct ConfigLLVM {}
impl ConfigLLVM {
pub fn new() -> Config {
let mut config = Config::default();
config.global.qualifier = FormatQualifier::Never;
config.global.syntax.omit_address_mode = true;
config.instructions.adr_a1.aliases =
Some(FormatAliasInstruction::Always(AdrA1Aliases::AddAdrA1));
config.instructions.adr_a2.aliases =
Some(FormatAliasInstruction::Always(AdrA2Aliases::SubAdrA2));
config.instructions.ldr_i_a1_post.aliases = Some(FormatAliasInstruction::Never);
config.instructions.mov_i_a2.encodings = Some(MovIA2Encodings::Alt2);
config.instructions.str_i_a1_pre.aliases = Some(FormatAliasInstruction::Never);
config.instructions.rfeia_a1_as.syntax.omit_address_mode = Some(false);
config.instructions.srsia_a1_as.syntax.omit_address_mode = Some(false);
config.instructions.dmb_a1.syntax.positive_integer_format =
Some(FormatInteger::HexadecimalUnsigned);
config.instructions.dsb_a1.syntax.positive_integer_format =
Some(FormatInteger::HexadecimalUnsigned);
config.instructions.isb_a1.syntax.positive_integer_format =
Some(FormatInteger::HexadecimalUnsigned);
config.instructions.mrs_a1_as.syntax.special_register_format =
Some(FormatSpecialRegister::Lowercase);
config
}
}