use super::msp430_register_info::*;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum Msp430Opcode {
RRC = 0,
SWPB,
RRA,
SXT,
PUSH,
POP,
CALL,
RETI,
MOV = 10,
ADD,
ADDC,
SUBC,
SUB,
CMP,
DADD,
BIT,
BIC,
BIS,
XOR,
AND,
JNE = 30,
JEQ,
JNC,
JC,
JN,
JGE,
JL,
JMP,
CLR = 40,
CLRC,
SETC,
CLRZ,
SETZ,
CLRN,
SETN,
DINT,
EINT,
NOP,
BR,
RET,
TST,
INV,
RLA,
RLC,
ADC,
DADC,
MOVA = 60,
CMPA,
ADDA,
SUBA,
BRA,
RETA,
PUSHM,
POPM,
CALLA,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Msp430OperandType {
RegDef,
RegUse1,
RegUse2,
RegBase,
RegStore,
Imm16,
UImm16,
BranchOffset,
CallTarget,
}
#[derive(Debug, Clone)]
pub struct Msp430InstrDesc {
pub opcode: Msp430Opcode,
pub mnemonic: String,
pub is_terminator: bool,
pub is_branch: bool,
pub is_call: bool,
pub is_return: bool,
pub may_load: bool,
pub may_store: bool,
pub has_side_effects: bool,
pub is_compare: bool,
pub is_commutative: bool,
pub is_cond_branch: bool,
pub operand_types: Vec<Msp430OperandType>,
pub instr_size: u8, }
pub struct Msp430InstrInfo {
pub desc_map: HashMap<Msp430Opcode, Msp430InstrDesc>,
}
impl Msp430InstrInfo {
pub fn new() -> Self {
let mut info = Msp430InstrInfo {
desc_map: HashMap::new(),
};
info.register_all();
info
}
pub fn get_desc(&self, opcode: Msp430Opcode) -> Option<&Msp430InstrDesc> {
self.desc_map.get(&opcode)
}
pub fn get_mnemonic(&self, opcode: Msp430Opcode) -> String {
self.desc_map
.get(&opcode)
.map(|d| d.mnemonic.clone())
.unwrap_or_else(|| "INVALID".into())
}
fn add(
&mut self,
opcode: Msp430Opcode,
mnemonic: &str,
is_terminator: bool,
is_branch: bool,
is_call: bool,
is_return: bool,
may_load: bool,
may_store: bool,
has_side_effects: bool,
is_compare: bool,
is_commutative: bool,
is_cond_branch: bool,
operand_types: Vec<Msp430OperandType>,
instr_size: u8,
) {
self.desc_map.insert(
opcode,
Msp430InstrDesc {
opcode,
mnemonic: mnemonic.to_string(),
is_terminator,
is_branch,
is_call,
is_return,
may_load,
may_store,
has_side_effects,
is_compare,
is_commutative,
is_cond_branch,
operand_types,
instr_size,
},
);
}
fn register_all(&mut self) {
use Msp430OperandType::*;
let s1 = vec![RegDef];
self.add(
Msp430Opcode::RRC,
"rrc",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
s1.clone(),
2,
);
self.add(
Msp430Opcode::SWPB,
"swpb",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
s1.clone(),
2,
);
self.add(
Msp430Opcode::RRA,
"rra",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
s1.clone(),
2,
);
self.add(
Msp430Opcode::SXT,
"sxt",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
s1.clone(),
2,
);
self.add(
Msp430Opcode::PUSH,
"push",
false,
false,
false,
false,
false,
true,
false,
false,
false,
false,
vec![RegUse1],
2,
);
self.add(
Msp430Opcode::POP,
"pop",
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
vec![RegDef],
2,
);
self.add(
Msp430Opcode::CALL,
"call",
false,
false,
true,
false,
false,
false,
false,
false,
false,
false,
vec![CallTarget],
2,
);
self.add(
Msp430Opcode::RETI,
"reti",
true,
false,
false,
true,
false,
false,
false,
false,
false,
false,
vec![],
2,
);
let d2 = vec![RegDef, RegUse1];
self.add(
Msp430Opcode::MOV,
"mov",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::ADD,
"add",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::ADDC,
"addc",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::SUBC,
"subc",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::SUB,
"sub",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::CMP,
"cmp",
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::DADD,
"dadd",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::BIT,
"bit",
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::BIC,
"bic",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::BIS,
"bis",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::XOR,
"xor",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::AND,
"and",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
2,
);
self.add(
Msp430Opcode::JNE,
"jne",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JEQ,
"jeq",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JNC,
"jnc",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JC,
"jc",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JN,
"jn",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JGE,
"jge",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JL,
"jl",
true,
true,
false,
false,
false,
false,
false,
false,
false,
true,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::JMP,
"jmp",
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::CLR,
"clr",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
vec![RegDef],
2,
);
self.add(
Msp430Opcode::NOP,
"nop",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
vec![],
2,
);
self.add(
Msp430Opcode::BR,
"br",
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
vec![BranchOffset],
2,
);
self.add(
Msp430Opcode::RET,
"ret",
true,
false,
false,
true,
false,
false,
false,
false,
false,
false,
vec![],
2,
);
self.add(
Msp430Opcode::TST,
"tst",
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
vec![RegUse1],
2,
);
self.add(
Msp430Opcode::INV,
"inv",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
vec![RegDef],
2,
);
self.add(
Msp430Opcode::MOVA,
"mova",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
4,
);
self.add(
Msp430Opcode::CMPA,
"cmpa",
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
d2.clone(),
4,
);
self.add(
Msp430Opcode::ADDA,
"adda",
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
d2.clone(),
4,
);
self.add(
Msp430Opcode::SUBA,
"suba",
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
d2.clone(),
4,
);
self.add(
Msp430Opcode::BRA,
"bra",
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
vec![BranchOffset],
4,
);
self.add(
Msp430Opcode::RETA,
"reta",
true,
false,
false,
true,
false,
false,
false,
false,
false,
false,
vec![],
4,
);
self.add(
Msp430Opcode::PUSHM,
"pushm",
false,
false,
false,
false,
false,
true,
false,
false,
false,
false,
vec![RegUse1, Imm16],
4,
);
self.add(
Msp430Opcode::POPM,
"popm",
false,
false,
false,
false,
true,
false,
false,
false,
false,
false,
vec![RegDef, Imm16],
4,
);
self.add(
Msp430Opcode::CALLA,
"calla",
false,
false,
true,
false,
false,
false,
false,
false,
false,
false,
vec![CallTarget],
4,
);
}
}