1extern crate yaxpeax_arch;
24
25use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, StandardDecodeError};
26
27use std::fmt;
28
29#[derive(Debug, Copy, Clone, PartialEq)]
30pub enum SREGBit {
31 C, Z, N, V, S, H, T, I
32}
33
34impl SREGBit {
35 fn from_bit_index(idx: u8) -> SREGBit {
36 use SREGBit::*;
37 match idx {
38 0 => C,
39 1 => Z,
40 2 => N,
41 3 => V,
42 4 => S,
43 5 => H,
44 6 => T,
45 7 => I,
46 _ => panic!("invalid sreg bit index"),
47 }
48 }
49}
50
51impl fmt::Display for SREGBit {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 use SREGBit::*;
54 write!(f, "{}", match self {
55 C => 'c',
56 Z => 'z',
57 N => 'n',
58 V => 'v',
59 S => 's',
60 H => 'h',
61 T => 't',
62 I => 'i',
63 })
64 }
65}
66
67#[derive(Debug, Copy, Clone, PartialEq)]
68pub enum Opcode {
69 ADC,
70 ADD,
71 ADIW,
72 AND,
73 ANDI,
74 ASR,
75 BCLR(SREGBit),
76 BLD,
77 BRBC(SREGBit),
78 BRBS(SREGBit),
79 BREAK,
80 BSET(SREGBit),
81 BST,
82 CALL,
83 CBI,
84 COM,
85 CP,
86 CPC,
87 CPI,
88 CPSE,
89 DEC,
90 DES,
91 EICALL,
92 EIJMP,
93 ELPM,
94 EOR,
95 FMUL,
96 FMULS,
97 FMULSU,
98 ICALL,
99 IJMP,
100 IN,
101 INC,
102 JMP,
103 LAC,
104 LAS,
105 LAT,
106 LD,
107 LDD,
108 LDI,
109 LDS,
110 LPM,
111 LSR,
112 MOV,
113 MOVW,
114 MUL,
115 MULS,
116 MULSU,
117 NEG,
118 NOP,
119 OR,
120 ORI,
121 OUT,
122 POP,
123 PUSH,
124 RCALL,
125 RET,
126 RETI,
127 RJMP,
128 ROR,
129 SBC,
130 SBCI,
131 SBI,
132 SBIC,
133 SBIS,
134 SBIW,
135 SBRC,
136 SBRS,
137 SLEEP,
138 SPM,
139 ST,
140 STD,
141 STS,
142 SUB,
143 SUBI,
144 SWAP,
145 WDR,
146 XCH,
147}
148
149impl fmt::Display for Opcode {
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151 match self {
152 Opcode::ADC => write!(f, "adc"),
153 Opcode::ADD => write!(f, "add"),
154 Opcode::ADIW => write!(f, "adiw"),
155 Opcode::AND => write!(f, "and"),
156 Opcode::ANDI => write!(f, "andi"),
157 Opcode::ASR => write!(f, "asr"),
158 Opcode::BCLR(bit) => write!(f, "cl{}", bit),
159 Opcode::BLD => write!(f, "bld"),
160 Opcode::BRBC(_) | Opcode::BRBS(_) => {
161 let (bit, is_clear) = match self {
162 Opcode::BRBC(bit) => (bit, true),
163 Opcode::BRBS(bit) => (bit, false),
164 _ => unreachable!(),
165 };
166
167 let (suffix_clear, suffix_set) = match bit {
168 SREGBit::C => ("sh", "lo"),
169 SREGBit::Z => ("ne", "eq"),
170 SREGBit::N => ("pl", "mi"),
171 SREGBit::V => ("vc", "vs"),
172 SREGBit::S => ("ge", "lt"),
173 SREGBit::H => ("hc", "hs"),
174 SREGBit::T => ("tc", "ts"),
175 SREGBit::I => ("id", "ie"),
176 };
177 let suffix = if is_clear {
178 suffix_clear
179 } else {
180 suffix_set
181 };
182
183 write!(f, "br{}", suffix)
184 },
185 Opcode::BREAK => write!(f, "break"),
186 Opcode::BSET(bit) => write!(f, "se{}", bit),
187 Opcode::BST => write!(f, "bst"),
188 Opcode::CALL => write!(f, "call"),
189 Opcode::CBI => write!(f, "cbi"),
190 Opcode::COM => write!(f, "com"),
191 Opcode::CP => write!(f, "cp"),
192 Opcode::CPC => write!(f, "cpc"),
193 Opcode::CPI => write!(f, "cpi"),
194 Opcode::CPSE => write!(f, "cpse"),
195 Opcode::DEC => write!(f, "dec"),
196 Opcode::DES => write!(f, "des"),
197 Opcode::EICALL => write!(f, "eicall"),
198 Opcode::EIJMP => write!(f, "eijmp"),
199 Opcode::ELPM => write!(f, "elpm"),
200 Opcode::EOR => write!(f, "eor"),
201 Opcode::FMUL => write!(f, "fmul"),
202 Opcode::FMULS => write!(f, "fmuls"),
203 Opcode::FMULSU => write!(f, "fmulsu"),
204 Opcode::ICALL => write!(f, "icall"),
205 Opcode::IJMP => write!(f, "ijmp"),
206 Opcode::IN => write!(f, "in"),
207 Opcode::INC => write!(f, "inc"),
208 Opcode::JMP => write!(f, "jmp"),
209 Opcode::LAC => write!(f, "lac"),
210 Opcode::LAS => write!(f, "las"),
211 Opcode::LAT => write!(f, "lat"),
212 Opcode::LD => write!(f, "ld"),
213 Opcode::LDD => write!(f, "ldd"),
214 Opcode::LDI => write!(f, "ldi"),
215 Opcode::LDS => write!(f, "lds"),
216 Opcode::LPM => write!(f, "lpm"),
217 Opcode::LSR => write!(f, "lsr"),
218 Opcode::MOV => write!(f, "mov"),
219 Opcode::MOVW => write!(f, "movw"),
220 Opcode::MUL => write!(f, "mul"),
221 Opcode::MULS => write!(f, "muls"),
222 Opcode::MULSU => write!(f, "mulsu"),
223 Opcode::NEG => write!(f, "neg"),
224 Opcode::NOP => write!(f, "nop"),
225 Opcode::OR => write!(f, "or"),
226 Opcode::ORI => write!(f, "ori"),
227 Opcode::OUT => write!(f, "out"),
228 Opcode::POP => write!(f, "pop"),
229 Opcode::PUSH => write!(f, "push"),
230 Opcode::RCALL => write!(f, "rcall"),
231 Opcode::RET => write!(f, "ret"),
232 Opcode::RETI => write!(f, "reti"),
233 Opcode::RJMP => write!(f, "rjmp"),
234 Opcode::ROR => write!(f, "ror"),
235 Opcode::SBC => write!(f, "sbc"),
236 Opcode::SBCI => write!(f, "sbci"),
237 Opcode::SBI => write!(f, "sbi"),
238 Opcode::SBIC => write!(f, "sbic"),
239 Opcode::SBIS => write!(f, "sbis"),
240 Opcode::SBIW => write!(f, "sbiw"),
241 Opcode::SBRC => write!(f, "sbrc"),
242 Opcode::SBRS => write!(f, "sbrs"),
243 Opcode::SLEEP => write!(f, "sleep"),
244 Opcode::SPM => write!(f, "spm"),
245 Opcode::ST => write!(f, "st"),
246 Opcode::STD => write!(f, "std"),
247 Opcode::STS => write!(f, "sts"),
248 Opcode::SUB => write!(f, "sub"),
249 Opcode::SUBI => write!(f, "subi"),
250 Opcode::SWAP => write!(f, "swap"),
251 Opcode::WDR => write!(f, "wdr"),
252 Opcode::XCH => write!(f, "xch"),
253 }
254 }
255}
256
257#[derive(Debug, Copy, Clone, PartialEq)]
258pub enum IndexRegister {
259 X,
260 Y,
261 Z
262}
263
264#[derive(Debug, Copy, Clone, PartialEq)]
265pub enum IndexRegisterModifier {
266 Unchanged,
267 PostIncrement,
268 PreDecrement,
269 Displacement(u8),
270}
271
272#[derive(Debug, Copy, Clone, PartialEq)]
273pub enum Register {
274 Register(u8),
275 RegisterPair { low: u8 },
277 IndexRegister(IndexRegister, IndexRegisterModifier)
278}
279
280#[derive(Debug, Copy, Clone)]
281enum OperandSpec {
282 Nothing,
283 ImpliedRegister(Register),
284 DestRegister,
286 SrcRegister,
288 DestRegister16_31,
290 SrcRegister16_31,
292 RegisterPair24_26_28_30,
295 DestRegister16_23,
297 SrcRegister16_23,
299 DestRegisterPair,
301 SrcRegisterPair,
303 Imm3,
305 Imm4,
307 Imm6,
309 Imm8,
311 RegDisp6(IndexRegister),
313 BranchDisp7,
315 RCALLJMPDisp12,
317 Addr5,
319 Addr6,
321 Addr7,
323 Addr16,
325 Addr22,
327}
328
329#[derive(Debug, Copy, Clone, PartialEq)]
330pub enum Operand {
331 Nothing,
332 Register(Register),
333 ImmediateU8(u8),
334 AddrPCRelative(i16),
335 AddrAbsolute(u32),
336 BitIndex(u8),
337}
338
339impl fmt::Display for Operand {
340 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 match self {
342 Operand::Nothing => panic!("can't display empty operand"),
343 Operand::Register(r) => match r {
344 Register::Register(i) => write!(f, "r{}", i),
345 Register::RegisterPair { low } => {
346 let base = low * 2;
347 write!(f, "r{}:r{}", base + 1, base)
348 },
349 Register::IndexRegister(r, modifier) => {
350 let reg_name = match r {
351 IndexRegister::X => "x",
352 IndexRegister::Y => "y",
353 IndexRegister::Z => "z",
354 };
355
356 match modifier {
357 IndexRegisterModifier::Unchanged => write!(f, "{}", reg_name),
358 IndexRegisterModifier::PostIncrement => write!(f, "{}+", reg_name),
359 IndexRegisterModifier::PreDecrement => write!(f, "-{}", reg_name),
360 IndexRegisterModifier::Displacement(d) => write!(f, "{}+{}", reg_name, d),
361 }
362 }
363 }
364 Operand::ImmediateU8(v) => write!(f, "${:02X}", v),
365 Operand::AddrPCRelative(v) => if *v == 0 {
366 write!(f, "pc")
367 } else {
368 write!(f, "pc{:+}", v)
369 },
370 Operand::AddrAbsolute(v) => write!(f, "${:X}", v),
371 Operand::BitIndex(i) => write!(f, "{}", i),
372 }
373 }
374}
375
376#[derive(Debug, Copy, Clone, PartialEq)]
377pub struct Instruction {
378 pub opcode: Opcode,
379 pub operands: [Operand; 2],
380 length: u8,
381}
382
383impl Default for Instruction {
384 fn default() -> Self {
385 Instruction {
386 opcode: Opcode::NOP,
387 operands: [Operand::Nothing, Operand::Nothing],
388 length: 2,
389 }
390 }
391}
392
393impl fmt::Display for Instruction {
394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 write!(f, "{}", self.opcode)?;
396 match &self.operands[0] {
397 Operand::Nothing => return Ok(()),
398 operand => write!(f, " {}", operand)?,
399 }
400 match &self.operands[1] {
401 Operand::Nothing => return Ok(()),
402 operand => write!(f, ", {}", operand)?,
403 }
404
405 Ok(())
406 }
407}
408
409impl yaxpeax_arch::Instruction for Instruction {
410 fn well_defined(&self) -> bool {
412 true
413 }
414}
415
416impl LengthedInstruction for Instruction {
417 type Unit = AddressDiff<<AVR as Arch>::Address>;
418
419 fn min_size() -> Self::Unit {
420 AddressDiff::from_const(2)
421 }
422
423 fn len(&self) -> Self::Unit {
424 AddressDiff::from_const(self.length as <AVR as Arch>::Address)
425 }
426}
427
428#[derive(Debug, Copy, Clone, PartialEq)]
429pub struct Target {
430 pub has_16_bit_lds_sts: bool
433}
434
435fn decode_opcode(fullword: u16, target: &Target) -> Option<(Opcode, [OperandSpec; 2])> {
436 let prefix4 = fullword >> (16 - 4);
440 let prefix5 = fullword >> (16 - 5);
441 let prefix6 = fullword >> (16 - 6);
442 let prefix7 = fullword >> (16 - 7);
443 let prefix8 = fullword >> (16 - 8);
444 let prefix9 = fullword >> (16 - 9);
445
446 let suffix4 = fullword & 0b1111;
451 let suffix4_3 = suffix4 >> 1;
452 let suffix4_1 = suffix4 & 0b1;
453
454 match fullword {
455 0b1001_0101_1001_1000 => return Some((Opcode::BREAK, [OperandSpec::Nothing, OperandSpec::Nothing])),
456 0b1001_0101_0001_1001 => return Some((Opcode::EICALL, [OperandSpec::Nothing, OperandSpec::Nothing])),
457 0b1001_0100_0001_1001 => return Some((Opcode::EIJMP, [OperandSpec::Nothing, OperandSpec::Nothing])),
458 0b1001_0101_1101_1000 => return Some((Opcode::ELPM, [OperandSpec::Nothing, OperandSpec::Nothing])),
459 0b1001_0101_0000_1001 => return Some((Opcode::ICALL, [OperandSpec::Nothing, OperandSpec::Nothing])),
460 0b1001_0100_0000_1001 => return Some((Opcode::IJMP, [OperandSpec::Nothing, OperandSpec::Nothing])),
461 0b1001_0101_1100_1000 => return Some((Opcode::LPM, [OperandSpec::Nothing, OperandSpec::Nothing])),
462 0b0000_0000_0000_0000 => return Some((Opcode::NOP, [OperandSpec::Nothing, OperandSpec::Nothing])),
463 0b1001_0101_0000_1000 => return Some((Opcode::RET, [OperandSpec::Nothing, OperandSpec::Nothing])),
464 0b1001_0101_0001_1000 => return Some((Opcode::RETI, [OperandSpec::Nothing, OperandSpec::Nothing])),
465 0b1001_0101_1000_1000 => return Some((Opcode::SLEEP, [OperandSpec::Nothing, OperandSpec::Nothing])),
466 0b1001_0101_1110_1000 => return Some((Opcode::SPM, [OperandSpec::Nothing, OperandSpec::Nothing])),
475 0b1001_0101_1111_1000 => return Some((Opcode::SPM, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PostIncrement)), OperandSpec::Nothing])),
476 0b1001_0101_1010_1000 => return Some((Opcode::WDR, [OperandSpec::Nothing, OperandSpec::Nothing])),
477 _ => {},
478 }
479
480 match prefix4 {
481 0b0111 => return Some((Opcode::ANDI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
482 0b0011 => return Some((Opcode::CPI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
483 0b1110 => return Some((Opcode::LDI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
484 0b0110 => return Some((Opcode::ORI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
485 0b1101 => return Some((Opcode::RCALL, [OperandSpec::RCALLJMPDisp12, OperandSpec::Nothing])),
486 0b1100 => return Some((Opcode::RJMP, [OperandSpec::RCALLJMPDisp12, OperandSpec::Nothing])),
487 0b0100 => return Some((Opcode::SBCI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
488 0b0101 => return Some((Opcode::SUBI, [OperandSpec::DestRegister16_31, OperandSpec::Imm8])),
489 _ => {},
490 }
491
492 match prefix5 {
493 0b1011_0 => return Some((Opcode::IN, [OperandSpec::DestRegister, OperandSpec::Addr6])),
494 0b1011_1 => return Some((Opcode::OUT, [OperandSpec::Addr6, OperandSpec::DestRegister])),
495 _ => {},
496 }
497
498 match prefix6 {
499 0b0001_11 => return Some((Opcode::ADC, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
500 0b0000_11 => return Some((Opcode::ADD, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
501 0b0010_00 => return Some((Opcode::AND, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
502 0b1111_01 | 0b1111_00 => {
503 let bit = SREGBit::from_bit_index((fullword & 0b111) as u8);
507 return Some((
508 if prefix6 & 1 != 0 { Opcode::BRBC(bit) } else { Opcode::BRBS(bit) },
509 [OperandSpec::BranchDisp7, OperandSpec::Nothing],
510 ))
511 },
512 0b0001_01 => return Some((Opcode::CP, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
513 0b0000_01 => return Some((Opcode::CPC, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
514 0b0001_00 => return Some((Opcode::CPSE, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
515 0b0010_01 => return Some((Opcode::EOR, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
516 0b0010_11 => return Some((Opcode::MOV, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
517 0b1001_11 => return Some((Opcode::MUL, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
518 0b0010_10 => return Some((Opcode::OR, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
519 0b0000_10 => return Some((Opcode::SBC, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
520 0b0001_10 => return Some((Opcode::SUB, [OperandSpec::DestRegister, OperandSpec::SrcRegister])),
521 _ => {},
522 }
523
524 match (prefix7, suffix4_3, suffix4_1) {
525 (0b1001_010, 0b010, 0b1) => return Some((Opcode::ASR, [OperandSpec::DestRegister, OperandSpec::Nothing])),
526 (0b1111_100, _, _) => return Some((Opcode::BLD, [OperandSpec::DestRegister, OperandSpec::Imm3])),
527 (0b1111_101, _, _) => return Some((Opcode::BST, [OperandSpec::DestRegister, OperandSpec::Imm3])),
528 (0b1001_010, 0b111, _) => return Some((Opcode::CALL, [OperandSpec::Addr22, OperandSpec::Nothing])),
529 (0b1001_010, 0b000, 0b0) => return Some((Opcode::COM, [OperandSpec::DestRegister, OperandSpec::Nothing])),
530 (0b1001_010, 0b101, 0b0) => return Some((Opcode::DEC, [OperandSpec::DestRegister, OperandSpec::Nothing])),
531 (0b1001_000, 0b011, 0b0) => return Some((Opcode::ELPM, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged))])),
532 (0b1001_000, 0b011, 0b1) => return Some((Opcode::ELPM, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PostIncrement))])),
533 (0b1001_010, 0b001, 0b1) => return Some((Opcode::INC, [OperandSpec::DestRegister, OperandSpec::Nothing])),
534 (0b1001_010, 0b110, _) => return Some((Opcode::JMP, [OperandSpec::Addr22, OperandSpec::Nothing])),
535 (0b1001_001, 0b011, 0b0) => return Some((Opcode::LAC, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
536 (0b1001_001, 0b010, 0b1) => return Some((Opcode::LAS, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
537 (0b1001_001, 0b011, 0b1) => return Some((Opcode::LAT, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
538 (0b1001_000, 0b110, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::Unchanged))])),
539 (0b1001_000, 0b110, 0b1) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::PostIncrement))])),
540 (0b1001_000, 0b111, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::PreDecrement))])),
541 (0b1000_000, 0b100, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::Unchanged))])),
542 (0b1001_000, 0b100, 0b1) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::PostIncrement))])),
543 (0b1001_000, 0b101, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::PreDecrement))])),
544 (0b1000_000, 0b000, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged))])),
545 (0b1001_000, 0b000, 0b1) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PostIncrement))])),
546 (0b1001_000, 0b001, 0b0) => return Some((Opcode::LD, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PreDecrement))])),
547 (0b1001_000, 0b010, 0b0) => return Some((Opcode::LPM, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged))])),
548 (0b1001_000, 0b010, 0b1) => return Some((Opcode::LPM, [OperandSpec::DestRegister, OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PostIncrement))])),
549 (0b1111_110, r, _) => {
553 if (r & 0b100) == 0b000 {
554 return Some((Opcode::SBRC, [OperandSpec::DestRegister, OperandSpec::Imm3]));
555 }
556 },
557 (0b1111_111, r, _) => {
558 if (r & 0b100) == 0b000 {
559 return Some((Opcode::SBRS, [OperandSpec::DestRegister, OperandSpec::Imm3]));
560 }
561 },
562 (0b1001_001, 0b110, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
563 (0b1001_001, 0b110, 0b1) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::PostIncrement)), OperandSpec::DestRegister])),
564 (0b1001_001, 0b111, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::X, IndexRegisterModifier::PreDecrement)), OperandSpec::DestRegister])),
565 (0b1000_001, 0b100, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
566 (0b1001_001, 0b100, 0b1) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::PostIncrement)), OperandSpec::DestRegister])),
567 (0b1001_001, 0b101, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Y, IndexRegisterModifier::PreDecrement)), OperandSpec::DestRegister])),
568 (0b1000_001, 0b000, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
569 (0b1001_001, 0b000, 0b1) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PostIncrement)), OperandSpec::DestRegister])),
570 (0b1001_001, 0b001, 0b0) => return Some((Opcode::ST, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::PreDecrement)), OperandSpec::DestRegister])),
571 (0b1001_000, 0b000, 0b0) => return Some((Opcode::LDS, [OperandSpec::DestRegister, OperandSpec::Addr16])),
572 (0b1001_010, 0b011, 0b0) => return Some((Opcode::LSR, [OperandSpec::DestRegister, OperandSpec::Nothing])),
573 (0b1001_010, 0b000, 0b1) => return Some((Opcode::NEG, [OperandSpec::DestRegister, OperandSpec::Nothing])),
574 (0b1001_000, 0b111, 0b1) => return Some((Opcode::POP, [OperandSpec::DestRegister, OperandSpec::Nothing])),
575 (0b1001_001, 0b111, 0b1) => return Some((Opcode::PUSH, [OperandSpec::DestRegister, OperandSpec::Nothing])),
576 (0b1001_010, 0b011, 0b1) => return Some((Opcode::ROR, [OperandSpec::DestRegister, OperandSpec::Nothing])),
577 (0b1001_001, 0b000, 0b0) => return Some((Opcode::STS, [OperandSpec::Addr16, OperandSpec::DestRegister])),
578 (0b1001_010, 0b001, 0b0) => return Some((Opcode::SWAP, [OperandSpec::DestRegister, OperandSpec::Nothing])),
579 (0b1001_001, 0b010, 0b0) => return Some((Opcode::XCH, [OperandSpec::ImpliedRegister(Register::IndexRegister(IndexRegister::Z, IndexRegisterModifier::Unchanged)), OperandSpec::DestRegister])),
580 _ => {},
581 };
582
583 match (prefix8, suffix4) {
584 (0b1001_0110, _) => return Some((Opcode::ADIW, [OperandSpec::RegisterPair24_26_28_30, OperandSpec::Imm6])),
585 (0b1001_1000, _) => return Some((Opcode::CBI, [OperandSpec::Addr5, OperandSpec::Imm3])),
586 (0b1001_0100, 0b1011) => return Some((Opcode::DES, [OperandSpec::Imm4, OperandSpec::Nothing])),
587 (0b0000_0001, _) => return Some((Opcode::MOVW, [OperandSpec::DestRegisterPair, OperandSpec::SrcRegisterPair])),
588 (0b0000_0010, _) => return Some((Opcode::MULS, [OperandSpec::DestRegister16_31, OperandSpec::SrcRegister16_31])),
589 (0b1001_1010, _) => return Some((Opcode::SBI, [OperandSpec::Addr5, OperandSpec::Imm3])),
590 (0b1001_1001, _) => return Some((Opcode::SBIC, [OperandSpec::Addr5, OperandSpec::Imm3])),
591 (0b1001_1011, _) => return Some((Opcode::SBIS, [OperandSpec::Addr5, OperandSpec::Imm3])),
592 (0b1001_0111, _) => return Some((Opcode::SBIW, [OperandSpec::RegisterPair24_26_28_30, OperandSpec::Imm6])),
593 _ => {},
594 }
595
596 match (prefix9, suffix4) {
597 (0b1001_0100_1, 0b1000) | (0b1001_0100_0, 0b1000) => return Some((
598 {
599 let bit = (fullword >> 4) & 0b111;
600 let bit = SREGBit::from_bit_index(bit as u8);
601
602 match prefix9 & 1 {
603 0 => Opcode::BSET(bit),
604 1 => Opcode::BCLR(bit),
605 _ => unreachable!(),
606 }
607 },
608 [OperandSpec::Nothing, OperandSpec::Nothing]
609 )),
610 (0b0000_0011_0, _) | (0b0000_0011_1, _) => return Some((
611 match (prefix9 & 1, suffix4 >> 3) {
612 (0, 0) => Opcode::MULSU,
613 (0, 1) => Opcode::FMUL,
614 (1, 0) => Opcode::FMULS,
615 (1, 1) => Opcode::FMULSU,
616 _ => unreachable!(),
617 },
618 [OperandSpec::DestRegister16_23, OperandSpec::SrcRegister16_23]
619 )),
620 _ => {},
621 }
622
623 if target.has_16_bit_lds_sts {
624 match prefix5 {
625 0b1010_0 => return Some((Opcode::LDS, [OperandSpec::DestRegister16_31, OperandSpec::Addr7])),
626 0b1010_1 => return Some((Opcode::STS, [OperandSpec::Addr7, OperandSpec::DestRegister16_31])),
627 _ => {},
628 }
629 } else {
630 match fullword & 0b1101_0010_0000_1000 {
631 0b1000_0000_0000_1000 => return Some((Opcode::LDD, [OperandSpec::DestRegister, OperandSpec::RegDisp6(IndexRegister::Y)])),
633 0b1000_0000_0000_0000 => return Some((Opcode::LDD, [OperandSpec::DestRegister, OperandSpec::RegDisp6(IndexRegister::Z)])),
634 0b1000_0010_0000_1000 => return Some((Opcode::STD, [OperandSpec::RegDisp6(IndexRegister::Y), OperandSpec::DestRegister])),
635 0b1000_0010_0000_0000 => return Some((Opcode::STD, [OperandSpec::RegDisp6(IndexRegister::Z), OperandSpec::DestRegister])),
636 _ => {},
637 }
638 }
639
640 None
641}
642
643#[derive(Debug)]
644pub struct InstDecoder {
645 target: Target,
646}
647
648impl InstDecoder {
649 pub fn new(target: Target) -> InstDecoder {
650 InstDecoder { target }
651 }
652}
653
654impl Default for InstDecoder {
655 fn default() -> Self {
656 InstDecoder {
657 target: Target { has_16_bit_lds_sts: false }
660 }
661 }
662}
663
664impl Decoder<AVR> for InstDecoder {
665 #[allow(non_snake_case)]
669 fn decode_into<T: Reader<<AVR as Arch>::Address, <AVR as Arch>::Word>>(
670 &self,
671 instr: &mut Instruction,
672 words: &mut T,
673 ) -> Result<(), <AVR as Arch>::DecodeError> {
674 words.mark();
675 let fullword = (words.next()? as u16) | ((words.next()? as u16) << 8);
676
677 let (opcode, interpretation) = decode_opcode(fullword, &self.target)
678 .ok_or(StandardDecodeError::InvalidOpcode)?;
679 instr.opcode = opcode;
680
681 for (interp, operand) in interpretation.iter().zip(instr.operands.iter_mut()) {
682 *operand = match interp {
683 OperandSpec::Nothing => { return Ok(()) },
684 OperandSpec::ImpliedRegister(r) => Operand::Register(*r),
685 OperandSpec::DestRegister => {
686 let d = (fullword >> 4) & 0b1_1111;
687 Operand::Register(Register::Register(d as u8))
688 },
689 OperandSpec::SrcRegister => {
690 let r = ((fullword >> 5) & 0b1_0000) | (fullword & 0b1111);
691 Operand::Register(Register::Register(r as u8))
692 },
693 OperandSpec::DestRegister16_31 => {
694 let d = (fullword >> 4) & 0b1111;
695 Operand::Register(Register::Register((d + 16) as u8))
696 },
697 OperandSpec::SrcRegister16_31 => {
698 let r = fullword & 0b1111;
699 Operand::Register(Register::Register((r + 16) as u8))
700 },
701 OperandSpec::RegisterPair24_26_28_30 => {
702 let d = (fullword >> 4) & 0b11;
703
704 Operand::Register(Register::RegisterPair { low: [12, 13, 14, 15][d as usize] })
709 },
710 OperandSpec::DestRegister16_23 => {
711 let d = (fullword >> 4) & 0b111;
712 Operand::Register(Register::Register((d + 16) as u8))
713 },
714 OperandSpec::SrcRegister16_23 => {
715 let r = fullword & 0b111;
716 Operand::Register(Register::Register((r + 16) as u8))
717 },
718 OperandSpec::DestRegisterPair => {
719 let d = (fullword >> 4) & 0b1111;
720 Operand::Register(Register::RegisterPair { low: d as u8 })
721 },
722 OperandSpec::SrcRegisterPair => {
723 let r = fullword & 0b1111;
724 Operand::Register(Register::RegisterPair { low: r as u8 })
725 },
726 OperandSpec::Imm3 => {
727 let K = fullword & 0b111;
728 Operand::BitIndex(K as u8)
729 },
730 OperandSpec::Imm4 => {
731 let K = (fullword >> 4) & 0b1111;
732 Operand::ImmediateU8(K as u8)
733 },
734 OperandSpec::Imm6 => {
735 let K = ((fullword >> 2) & 0b11_0000) | (fullword & 0b1111);
736 Operand::ImmediateU8(K as u8)
737 },
738 OperandSpec::Imm8 => {
739 let K = ((fullword >> 4) & 0b1111_0000) | (fullword & 0b1111);
740 Operand::ImmediateU8(K as u8)
741 },
742 OperandSpec::RegDisp6(r) => {
743 let q = ((fullword >> 8) & 0b10_0000) | ((fullword >> 7) & 0b1_1000) | (fullword & 0b111);
744 Operand::Register(Register::IndexRegister(*r, IndexRegisterModifier::Displacement(q as u8)))
745 },
746 OperandSpec::BranchDisp7 => {
747 let k = (fullword >> 3) & 0b111_1111;
752 let k = ((k | ((k & 0b100_0000) << 1)) as i8) as i16 + 1;
755
756 Operand::AddrPCRelative(k as i16)
757 },
758 OperandSpec::RCALLJMPDisp12 => {
759 let k = fullword & 0b1111_1111_1111;
760 let signbit = fullword & 0b1000_0000_0000;
763 let signext = (signbit << 4) | (signbit << 3) | (signbit << 2) | (signbit << 1);
764 let k = (signext | k) as i16 + 1;
767
768 Operand::AddrPCRelative(k)
769 },
770 OperandSpec::Addr5 => {
771 let A = (fullword >> 3) & 0b1_1111;
772
773 Operand::AddrAbsolute(A as u32)
774 },
775 OperandSpec::Addr6 => {
776 let A = ((fullword >> 5) & 0b11_0000) | (fullword & 0b1111);
777
778 Operand::AddrAbsolute(A as u32)
779 },
780 OperandSpec::Addr7 => {
781 let inst8 = (fullword >> 8) & 0b1;
788 let ninst8 = inst8 ^ 1;
789 let k = (ninst8 << 7) | (inst8 << 6) | ((fullword >> 5) & 0b11_0000) | (fullword & 0b1111);
790
791 Operand::AddrAbsolute(k as u32)
792 },
793 OperandSpec::Addr16 => {
794 let k = (words.next()? as u16) | ((words.next()? as u16) << 8);
795
796 Operand::AddrAbsolute(k as u32)
797 },
798 OperandSpec::Addr22 => {
799 let A_high = ((fullword >> 3) & 0b11_1110) | (fullword & 0b1);
800 let A_low = (words.next()? as u16) | ((words.next()? as u16) << 8);
801
802 let A = ((A_high as u32) << 16) | (A_low as u32);
803 let A = A * 2;
805
806 Operand::AddrAbsolute(A)
807 }
808 }
809 }
810
811 instr.length = words.offset() as u8;
812 Ok(())
813 }
814}
815
816#[derive(Debug)]
817pub struct AVR;
818
819impl Arch for AVR {
820 type Address = u32;
823 type Word = u8;
824 type Instruction = Instruction;
825 type DecodeError = StandardDecodeError;
826 type Decoder = InstDecoder;
827 type Operand = Operand;
828}