yaxpeax_core/arch/msp430/
syntaxed_render.rs1use termion::color;
2use yaxpeax_msp430::{Opcode, Operand, Instruction, Width};
3use std::collections::HashMap;
4
5pub fn opcode_color(opcode: Opcode) -> &'static color::Fg<&'static dyn color::Color> {
6 match opcode {
7 Opcode::Invalid(_) => { &color::Fg(&color::Red) }
8 Opcode::CALL |
9 Opcode::RETI => { &color::Fg(&color::LightGreen) }
10 Opcode::JNE |
11 Opcode::JEQ |
12 Opcode::JNC |
13 Opcode::JC |
14 Opcode::JN |
15 Opcode::JGE |
16 Opcode::JL |
17 Opcode::JMP => { &color::Fg(&color::Green) }
18 Opcode::MOV => { &color::Fg(&color::LightMagenta) }
19 Opcode::RRA |
20 Opcode::SXT |
21 Opcode::PUSH |
22 Opcode::AND |
23 Opcode::XOR |
24 Opcode::BIT |
25 Opcode::BIC |
26 Opcode::RRC |
27 Opcode::SWPB |
28 Opcode::BIS => { &color::Fg(&color::LightYellow) }
29 Opcode::ADD |
30 Opcode::ADDC |
31 Opcode::SUBC |
32 Opcode::SUB |
33 Opcode::DADD |
34 Opcode::CMP => { &color::Fg(&color::Yellow) }
35 }
36}
37
38use arch::msp430::PartialInstructionContext;
39impl <T> ::SyntaxedRender<u16, T, ()> for Instruction where T: PartialInstructionContext {
40 fn render(&self, context: Option<&T>, _function_table: &HashMap<u16, ()>) -> String {
41 fn render_operand<T: PartialInstructionContext>(operand: &Operand, context: Option<&T>) -> String {
42 fn signed_hex(num: i16) -> String {
43 if num >= 0 {
44 format!("+{:#x}", num)
45 } else {
46 format!("-{:#x}", -num)
47 }
48 }
49 match operand {
50 Operand::Register(0) => { "pc".to_owned() },
51 Operand::Register(1) => { "sp".to_owned() },
52 Operand::Register(2) => { "sr".to_owned() },
53 Operand::Register(3) => { "cg".to_owned() }, Operand::Register(reg) => {
55 format!("r{}", reg)
56 },
57 Operand::Indexed(0, offset) => {
58 format!("{}(pc)", signed_hex(*offset as i16))
59 },
60 Operand::Indexed(1, offset) => {
61 format!("{}(sp)", signed_hex(*offset as i16))
62 },
63 Operand::Indexed(2, offset) => {
64 format!("{}(sr)", signed_hex(*offset as i16))
65 },
66 Operand::Indexed(3, offset) => {
67 format!("{}(cg)", signed_hex(*offset as i16))
68 },
69 Operand::Indexed(reg, offset) => {
70 format!("{}(r{})", signed_hex(*offset as i16), reg)
71 },
72 Operand::RegisterIndirect(0) => { "@pc".to_owned() }
73 Operand::RegisterIndirect(1) => { "@sp".to_owned() }
74 Operand::RegisterIndirect(2) => { "@sr".to_owned() }
75 Operand::RegisterIndirect(3) => { "@cg".to_owned() }
76 Operand::RegisterIndirect(reg) => {
77 format!("@r{}", reg)
78 },
79 Operand::IndirectAutoinc(0) => { "@pc+".to_owned() }
80 Operand::IndirectAutoinc(1) => { "@sp+".to_owned() }
81 Operand::IndirectAutoinc(2) => { "@sr+".to_owned() }
82 Operand::IndirectAutoinc(3) => { "@cg+".to_owned() } Operand::IndirectAutoinc(reg) => {
84 format!("@r{}+", reg)
85 },
86 Operand::Offset(offset) => {
87 match context.and_then(|ctx| ctx.address()) {
88 Some(address) => {
89 format!("{:#x}", address.wrapping_add((*offset as u16).wrapping_mul(2)).wrapping_add(2))
91 },
92 None => {
93 format!("{}(pc)", signed_hex(*offset as i16))
94 }
95 }
96 },
97 Operand::Symbolic(offset) => {
98 match context.and_then(|ctx| ctx.address()) {
99 Some(address) => {
100 format!("{:#x}", address.wrapping_add(*offset))
101 },
102 None => {
103 format!("{}(pc)", signed_hex(*offset as i16))
104 }
105 }
106 },
107 Operand::Immediate(imm) => {
108 format!("#{:#x}", imm)
109 },
110 Operand::Absolute(offset) => {
111 format!("&{:#x}", offset)
112 },
113 Operand::Const4 => {
114 "4".to_owned()
115 },
116 Operand::Const8 => {
117 "8".to_owned()
118 },
119 Operand::Const0 => {
120 "0".to_owned()
121 },
122 Operand::Const1 => {
123 "1".to_owned()
124 },
125 Operand::Const2 => {
126 "2".to_owned()
127 },
128 Operand::ConstNeg1 => {
129 "-1".to_owned()
130 },
131 Operand::Nothing => {
132 "<No Operand>".to_owned()
133 }
134 }
135 }
136
137 match self {
139 Instruction { opcode: Opcode::MOV, operands: [Operand::Const0, Operand::Const0], op_width: _ } => {
140 format!("{}{}{}", color::Fg(color::Blue), "nop", color::Fg(color::Reset))
141 },
142 Instruction { opcode: Opcode::MOV, operands: [Operand::Const0, dest], op_width: _ } => {
143 let start_color = opcode_color(Opcode::MOV);
144 format!("{}{}{} {}", start_color, "clr", color::Fg(color::Reset), render_operand(&dest, context))
145 },
146 Instruction { opcode: Opcode::MOV, operands: [Operand::IndirectAutoinc(1), Operand::Register(0)], op_width: Width::W } => {
147 let start_color = opcode_color(Opcode::CALL);
149 format!("{}{}{}", start_color, "ret", color::Fg(color::Reset))
150 },
151 Instruction { opcode: Opcode::MOV, operands: [Operand::IndirectAutoinc(1), dest], op_width: Width::W } => {
152 let start_color = opcode_color(Opcode::PUSH);
154 format!("{}{}{} {}", start_color, "pop", color::Fg(color::Reset), render_operand(&dest, context))
155 },
156 Instruction { opcode: Opcode::MOV, operands: [src, Operand::Register(0)], op_width: Width::W } => {
157 let start_color = opcode_color(Opcode::JMP);
159 format!("{}{}{} {}", start_color, "br", color::Fg(color::Reset), render_operand(&src, context))
160 }
161 _ => {
162 let start_color = opcode_color(self.opcode);
163 let mut result = format!("{}{}{}{}", start_color, self.opcode, match self.op_width {
164 Width::W => "",
165 Width::B => ".b"
166 }, color::Fg(color::Reset));
167
168 match self.operands[0] {
169 Operand::Nothing => { return result; },
170 x @ _ => {
171 result.push(' ');
172 result.push_str(&render_operand(&x, context));
173 }
174 };
175 match self.operands[1] {
176 Operand::Nothing => { return result; },
177 x @ _ => {
178 result.push(',');
179 result.push(' ');
180 result.push_str(&render_operand(&x, context));
181 }
182 };
183 result
184 }
185 }
186 }
187}
188