1#![no_std]
2
3#![allow(non_snake_case)]
4
5#[cfg(feature="use-serde")]
6#[macro_use]
7extern crate serde_derive;
8
9use core::fmt;
10
11use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, StandardDecodeError};
12
13#[allow(non_camel_case_types)]
14#[derive(Debug, Copy, Clone)]
15pub enum Opcode {
16 ABS,
17 ADC(Size),
18 ADCF(Size),
19 ADD(Size),
20 ADJNZ(Size),
21 AND(Size),
22 BAND,
23 BCLR,
24 BMEQ,
25 BMGEU,
26 BMGT,
27 BMGTU,
28 BMLE,
29 BMLEU,
30 BMLTU,
31 BMLT,
32 BMNO,
33 BMGE,
34 BMN,
35 BMNE,
36 BMO,
37 BMPZ,
38 BNAND,
39 BNOR,
40 BNOT,
41 BNTST,
42 BNXOR,
43 BOR,
44 BRK,
45 BSET,
46 BTST,
47 BTSTC,
48 BTSTS,
49 BXOR,
50 CMP(Size),
51 DADC,
52 DADD,
53 DEC(Size),
54 DIV(Size),
55 DIVU(Size),
56 DIVX(Size),
57 DSBB,
58 DSUB,
59 ENTER,
60 EXITD,
61 EXTS,
62 GE,
63 INC(Size),
64 INT,
65 INTO,
66 JEQ,
67 JGE,
68 JGEU,
69 JGT,
70 JGTU,
71 JLE,
72 JLEU,
73 JLT,
74 JLTU,
75 JMPI,
76 JMPS,
77 JMP(Size),
78 JN,
79 JNE,
80 JNO,
81 JO,
82 JPZ,
83 JSRI,
84 JSRS,
85 JSR(Size),
86 LDC,
87 LDCTX,
88 LDE,
89 LDIPL,
90 LT,
91 MOV(Size),
92 MOVA,
93 MOVHH,
94 MOVHL,
95 MOVLH,
96 MOVLL,
97 MUL,
98 MULU(Size),
99 NEG,
100 NO,
101 NOP,
102 NOT(Size),
103 OR(Size),
104 POP,
105 POPC,
106 POPM,
107 PUSH(Size),
108 PUSHA,
109 PUSHC,
110 PUSHM,
111 REIT,
112 RMPA(Size),
113 ROLC,
114 RORC,
115 ROT(Size),
116 RTS,
117 SBB(Size),
118 SHA(Size),
119 SHL(Size),
120 SMOVB(Size),
121 SMOVF(Size),
122 SSTR(Size),
123 STC,
124 STCTX,
125 STE,
126 STNZ,
127 STX,
128 STZ,
129 STZX,
130 SUB(Size),
131 TST(Size),
132 UND,
133 WAIT,
134 XCHG(Size),
135 XOR(Size),
136}
137
138impl fmt::Display for Opcode {
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 match self {
141 Opcode::ABS => write!(f, "abs"),
142 Opcode::ADC(size) => write!(f, "adc.{}", size),
143 Opcode::ADCF(size) => write!(f, "adcf.{}", size),
144 Opcode::ADD(size) => write!(f, "add.{}", size),
145 Opcode::ADJNZ(size) => write!(f, "adjnz.{}", size),
146 Opcode::AND(size) => write!(f, "and.{}", size),
147 Opcode::BAND => write!(f, "band"),
148 Opcode::BCLR => write!(f, "bclr"),
149 Opcode::BMEQ => write!(f, "bmeq"),
150 Opcode::BMGEU => write!(f, "bmgeu"),
151 Opcode::BMGT => write!(f, "bmgt"),
152 Opcode::BMGTU => write!(f, "bmgtu"),
153 Opcode::BMLE => write!(f, "bmle"),
154 Opcode::BMLEU => write!(f, "bmleu"),
155 Opcode::BMLTU => write!(f, "bmltu"),
156 Opcode::BMLT => write!(f, "bmlt"),
157 Opcode::BMNO => write!(f, "bmno"),
158 Opcode::BMGE => write!(f, "bmge"),
159 Opcode::BMN => write!(f, "bmn"),
160 Opcode::BMNE => write!(f, "bmne"),
161 Opcode::BMO => write!(f, "bmo"),
162 Opcode::BMPZ => write!(f, "bmpz"),
163 Opcode::BNAND => write!(f, "bnand"),
164 Opcode::BNOR => write!(f, "bnor"),
165 Opcode::BNOT => write!(f, "bnot"),
166 Opcode::BNTST => write!(f, "bntst"),
167 Opcode::BNXOR => write!(f, "bnxor"),
168 Opcode::BOR => write!(f, "bor"),
169 Opcode::BRK => write!(f, "brk"),
170 Opcode::BSET => write!(f, "bset"),
171 Opcode::BTST => write!(f, "btst"),
172 Opcode::BTSTC => write!(f, "btstc"),
173 Opcode::BTSTS => write!(f, "btsts"),
174 Opcode::BXOR => write!(f, "bxor"),
175 Opcode::CMP(size) => write!(f, "cmp.{}", size),
176 Opcode::DADC => write!(f, "dadc"),
177 Opcode::DADD => write!(f, "dadd"),
178 Opcode::DEC(size) => write!(f, "dec.{}", size),
179 Opcode::DIV(size) => write!(f, "div.{}", size),
180 Opcode::DIVU(size) => write!(f, "divu.{}", size),
181 Opcode::DIVX(size) => write!(f, "divx.{}", size),
182 Opcode::DSBB => write!(f, "dsbb"),
183 Opcode::DSUB => write!(f, "dsub"),
184 Opcode::ENTER => write!(f, "enter"),
185 Opcode::EXITD => write!(f, "exitd"),
186 Opcode::EXTS => write!(f, "exts"),
187 Opcode::GE => write!(f, "ge"),
188 Opcode::INC(size) => write!(f, "inc.{}", size),
189 Opcode::INT => write!(f, "int"),
190 Opcode::INTO => write!(f, "into"),
191 Opcode::JEQ => write!(f, "jeq"),
192 Opcode::JGE => write!(f, "jge"),
193 Opcode::JGEU => write!(f, "jgeu"),
194 Opcode::JGT => write!(f, "jgt"),
195 Opcode::JGTU => write!(f, "jgtu"),
196 Opcode::JLE => write!(f, "jle"),
197 Opcode::JLEU => write!(f, "jleu"),
198 Opcode::JLT => write!(f, "jlt"),
199 Opcode::JLTU => write!(f, "jltu"),
200 Opcode::JMPI => write!(f, "jmpi"),
201 Opcode::JMPS => write!(f, "jmps"),
202 Opcode::JMP(size) => write!(f, "jmp.{}", size),
203 Opcode::JN => write!(f, "jn"),
204 Opcode::JNE => write!(f, "jne"),
205 Opcode::JNO => write!(f, "jno"),
206 Opcode::JO => write!(f, "jo"),
207 Opcode::JPZ => write!(f, "jpz"),
208 Opcode::JSRI => write!(f, "jsri"),
209 Opcode::JSRS => write!(f, "jsrs"),
210 Opcode::JSR(size) => write!(f, "jsr.{}", size),
211 Opcode::LDC => write!(f, "ldc"),
212 Opcode::LDCTX => write!(f, "ldctx"),
213 Opcode::LDE => write!(f, "lde"),
214 Opcode::LDIPL => write!(f, "ldipl"),
215 Opcode::LT => write!(f, "lt"),
216 Opcode::MOV(size) => write!(f, "mov.{}", size),
217 Opcode::MOVA => write!(f, "mova"),
218 Opcode::MOVHH => write!(f, "movhh"),
219 Opcode::MOVHL => write!(f, "movhl"),
220 Opcode::MOVLH => write!(f, "movlh"),
221 Opcode::MOVLL => write!(f, "movll"),
222 Opcode::MUL => write!(f, "mul"),
223 Opcode::MULU(size) => write!(f, "mulu.{}", size),
224 Opcode::NEG => write!(f, "neg"),
225 Opcode::NO => write!(f, "no"),
226 Opcode::NOP => write!(f, "nop"),
227 Opcode::NOT(size) => write!(f, "not.{}", size),
228 Opcode::OR(size) => write!(f, "or.{}", size),
229 Opcode::POP => write!(f, "pop"),
230 Opcode::POPC => write!(f, "popc"),
231 Opcode::POPM => write!(f, "popm"),
232 Opcode::PUSH(size) => write!(f, "push.{}", size),
233 Opcode::PUSHA => write!(f, "pusha"),
234 Opcode::PUSHC => write!(f, "pushc"),
235 Opcode::PUSHM => write!(f, "pushm"),
236 Opcode::REIT => write!(f, "reit"),
237 Opcode::RMPA(size) => write!(f, "rmpa.{}", size),
238 Opcode::ROLC => write!(f, "rolc"),
239 Opcode::RORC => write!(f, "rorc"),
240 Opcode::ROT(size) => write!(f, "rot.{}", size),
241 Opcode::RTS => write!(f, "rts"),
242 Opcode::SBB(size) => write!(f, "sbb.{}", size),
243 Opcode::SHA(size) => write!(f, "sha.{}", size),
244 Opcode::SHL(size) => write!(f, "shl.{}", size),
245 Opcode::SMOVB(size) => write!(f, "smovb.{}", size),
246 Opcode::SMOVF(size) => write!(f, "smovf.{}", size),
247 Opcode::SSTR(size) => write!(f, "sstr.{}", size),
248 Opcode::STC => write!(f, "stc"),
249 Opcode::STCTX => write!(f, "stctx"),
250 Opcode::STE => write!(f, "ste"),
251 Opcode::STNZ => write!(f, "stnz"),
252 Opcode::STX => write!(f, "stx"),
253 Opcode::STZ => write!(f, "stz"),
254 Opcode::STZX => write!(f, "stzx"),
255 Opcode::SUB(size) => write!(f, "sub.{}", size),
256 Opcode::TST(size) => write!(f, "tst.{}", size),
257 Opcode::UND => write!(f, "und"),
258 Opcode::WAIT => write!(f, "wait"),
259 Opcode::XCHG(size) => write!(f, "xchg.{}", size),
260 Opcode::XOR(size) => write!(f, "xor.{}", size),
261 }
262 }
263}
264
265#[derive(Debug, Copy, Clone)]
266pub enum Register {
267 R0L,
268 R0H,
269 R1L,
270 R1H,
271 R0,
272 R1,
273 R2,
274 R3,
275 R2R0,
276 R3R1,
277 A0,
278 A1,
279 A1A0,
280 FB,
281 SB,
282 SP,
283 INTBL,
284 INTBH,
285 FLG,
286 ISP,
287}
288
289impl fmt::Display for Register {
290 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
291 use Register::*;
292 match self {
293 R0L => write!(f, "r0l"),
294 R0H => write!(f, "r0h"),
295 R1L => write!(f, "r1l"),
296 R1H => write!(f, "r1h"),
297 R0 => write!(f, "r0"),
298 R1 => write!(f, "r1"),
299 R2 => write!(f, "r2"),
300 R3 => write!(f, "r3"),
301 R2R0 => write!(f, "r2r0"),
302 R3R1 => write!(f, "r3r1"),
303 A0 => write!(f, "a0"),
304 A1 => write!(f, "a1"),
305 A1A0 => write!(f, "a1a0"),
306 FB => write!(f, "fb"),
307 SB => write!(f, "sb"),
308 SP => write!(f, "sp"),
309 INTBL => write!(f, "intbl"),
310 INTBH => write!(f, "intbh"),
311 FLG => write!(f, "flg"),
312 ISP => write!(f, "isp"),
313 }
314 }
315}
316
317#[derive(Debug, Copy, Clone)]
318pub enum Operand {
319 Register(Register),
320 RegisterBit(Register, u8),
321 ImmediateI16(i16),
322 ImmediateU16(u16),
323 RegDerefBit(Register),
324 A0A1DispBit(Register, u16),
325 RegDispBit(Register, u16, u8),
326 RegDeref(Register, i16),
327 AbsoluteBit(u16),
328 Absolute(u32),
329 JmpAbsolute(u32),
330 Displacement(i16),
331 JmpDisplacement(i16),
332 RegList(u8),
333}
334
335impl fmt::Display for Operand {
336 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
337 match self {
338 Operand::RegList(list) => {
339 let regs = [
340 Register::FB,
341 Register::SB,
342 Register::A1,
343 Register::A0,
344 Register::R3,
345 Register::R2,
346 Register::R1,
347 Register::R0,
348 ];
349
350 let mut printed = false;
351
352 for i in 0..8 {
353 if list & (1 << i) != 0 {
354 if printed {
355 write!(f, ", ")?;
356 } else {
357 printed = true;
358 }
359 write!(f, "{}", regs[i as usize])?;
360 }
361 }
362
363 Ok(())
364 }
365 Operand::Register(reg) => write!(f, "{}", reg),
366 Operand::ImmediateI16(imm) => {
367 if *imm == core::i16::MIN {
368 write!(f, "#-8000h")
369 } else if *imm < 0 {
370 write!(f, "#-{:02x}h", -*imm)
371 } else {
372 write!(f, "#{:02x}h", *imm)
373 }
374 },
375 Operand::ImmediateU16(imm) => write!(f, "#{:02x}h", imm),
376 Operand::RegDerefBit(reg) => {
377 write!(f, "bit,[{}]", reg)
378 }
379 Operand::A0A1DispBit(reg, offset) => {
380 write!(f, "{}[{}]", offset, reg)
381 }
382 Operand::RegDispBit(reg, offset, bit) => {
383 write!(f, "{},{}[{}]", bit, offset, reg)
384 }
385 Operand::RegDeref(reg, offset) => {
386 if *offset == core::i16::MIN {
387 write!(f, "#-8000h")
388 } else if *offset == 0 {
389 write!(f, "[{}]", reg)
390 } else if *offset < 0 {
391 write!(f, "-{}[{}]", -offset, reg)
392 } else {
393 write!(f, "{}[{}]", offset, reg)
394 }
395 }
396 Operand::JmpDisplacement(offset) => {
397 if *offset == core::i16::MIN {
398 write!(f, "$-32768")
399 } else if *offset < 0 {
400 write!(f, "$-{}", -*offset)
401 } else {
402 write!(f, "$+{}", *offset)
403 }
404 }
405 Operand::Displacement(offset) => {
406 if *offset == core::i16::MIN {
407 write!(f, "[$-32768]")
408 } else if *offset < 0 {
409 write!(f, "[$-{}]", -*offset)
410 } else {
411 write!(f, "[$+{}]", *offset)
412 }
413 }
414 Operand::AbsoluteBit(addr) => {
415 write!(f, "[#{:x}h]", addr)
416 }
417 Operand::Absolute(addr) => {
419 write!(f, "[#{:x}h]", addr)
420 }
421 Operand::JmpAbsolute(addr) => {
422 write!(f, "#{:x}h", addr)
423 }
424 Operand::RegisterBit(reg, bit) => {
425 write!(f, "{},{}", bit, reg)
426 }
427 }
428 }
429}
430
431#[allow(non_camel_case_types)]
432#[derive(Debug, Copy, Clone, PartialEq)]
433enum OperandSpec {
434 Nothing,
435 Zero,
436 Imm4,
437 Imm8,
438 Imm82, Imm16,
440 Label8,
441 Bit0,
442 Bit1,
443 Bit2,
444 Bit3,
445 Bit4,
446 Bit5,
447 Bit6,
448 Bit7,
449 R0L,
450 R0H,
451 R1L,
452 R1H,
453 R0,
454 R1,
455 R2,
456 R3,
457 R2R0,
458 R3R1,
459 A0,
460 A1,
461 A1A0,
462 Bit_R0,
463 Bit_R1,
464 Bit_R2,
465 Bit_R3,
466 Bit_A0,
467 Bit_A1,
468 Bit_Deref_A0,
469 Bit_Deref_A1,
470 Bit_Disp8_A0,
471 Bit_Disp8_A1,
472 Bit_Disp8_SB,
473 Bit_Disp8_FB,
474 Bit_Disp16_A0,
475 Bit_Disp16_A1,
476 Bit_Disp16_SB,
477 Bit_Abs16,
478 Disp8_A0,
479 Disp8_A1,
480 Disp8_SB,
481 Disp8_FB,
482 Disp8_SP,
483 Disp16_A0,
484 Disp16_A1,
485 Disp16_SB,
486 Disp20_A0,
487 Disp20_A1,
488 Deref_A0,
489 Deref_A1,
490 Deref_A1A0,
491 Abs16,
492 Disp2_8_A0,
493 Disp2_8_A1,
494 Disp2_8_SB,
495 Disp2_8_FB,
496 Disp2_16_A0,
497 Disp2_16_A1,
498 Disp2_16_SB,
499 Abs2_16,
500 Abs20,
501 JmpAbs20,
502 Disp8,
503 JmpDisp8,
504 JmpDisp16,
505 RegList,
506 INTBL,
507 INTBH,
508 FLG,
509 ISP,
510 SP,
511 SB,
512 FB,
513}
514
515#[derive(Debug, Copy, Clone, PartialEq)]
516pub enum Size {
517 B, W, L, S, A, }
523
524impl fmt::Display for Size {
525 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
526 match self {
527 Size::B => write!(f, "b"),
528 Size::W => write!(f, "w"),
529 Size::L => write!(f, "l"),
530 Size::S => write!(f, "s"),
531 Size::A => write!(f, "a"),
532 }
533 }
534}
535
536impl Size {
537 fn as_bytes(&self) -> u8 {
538 match self {
539 Size::B => 1,
540 Size::W => 2,
541 Size::L => { panic!("should not have to get number of bytes for L"); },
542 Size::S => { panic!("should not have to get number of bytes for S"); },
543 Size::A => { panic!("should not have to get number of bytes for A"); },
544 }
545 }
546}
547
548#[derive(Debug, Copy, Clone)]
549pub struct Instruction {
550 pub opcode: Opcode,
551 operands: [OperandSpec; 3],
552 imm_wide: u32,
559 dispabs: u16, length: u8,
561}
562
563impl Instruction {
564 pub fn operand(&self, idx: u8) -> Option<Operand> {
565 use OperandSpec::*;
566 let operand = match self.operands[idx as usize] {
567 Nothing => { return None; },
568 Zero => Operand::ImmediateU16(0),
569 Imm4 => Operand::ImmediateI16(self.imm_wide as u8 as i8 as i16),
570 Imm8 => Operand::ImmediateI16(self.imm_wide as u8 as i8 as i16),
571 Imm16 => Operand::ImmediateI16(self.imm_wide as i16),
572 Imm82 |
574 Label8 => Operand::ImmediateI16((self.imm_wide as i16) >> 8),
576 Bit0 => Operand::ImmediateU16(0),
577 Bit1 => Operand::ImmediateU16(1),
578 Bit2 => Operand::ImmediateU16(2),
579 Bit3 => Operand::ImmediateU16(3),
580 Bit4 => Operand::ImmediateU16(4),
581 Bit5 => Operand::ImmediateU16(5),
582 Bit6 => Operand::ImmediateU16(6),
583 Bit7 => Operand::ImmediateU16(7),
584 R0L => Operand::Register(Register::R0L),
585 R0H => Operand::Register(Register::R0H),
586 R1L => Operand::Register(Register::R1L),
587 R1H => Operand::Register(Register::R1H),
588 R0 => Operand::Register(Register::R0),
589 R1 => Operand::Register(Register::R1),
590 R2 => Operand::Register(Register::R2),
591 R3 => Operand::Register(Register::R3),
592 R2R0 => Operand::Register(Register::R2R0),
593 R3R1 => Operand::Register(Register::R3R1),
594 A0 => Operand::Register(Register::A0),
595 A1 => Operand::Register(Register::A1),
596 A1A0 => Operand::Register(Register::A1A0),
597 Bit_R0 => Operand::RegisterBit(Register::R0, self.dispabs as u8),
598 Bit_R1 => Operand::RegisterBit(Register::R1, self.dispabs as u8),
599 Bit_R2 => Operand::RegisterBit(Register::R2, self.dispabs as u8),
600 Bit_R3 => Operand::RegisterBit(Register::R3, self.dispabs as u8),
601 Bit_A0 => Operand::RegisterBit(Register::A0, self.dispabs as u8),
602 Bit_A1 => Operand::RegisterBit(Register::A1, self.dispabs as u8),
603 Bit_Deref_A0 => Operand::RegDerefBit(Register::A0),
604 Bit_Deref_A1 => Operand::RegDerefBit(Register::A1),
605 Bit_Disp8_A0 => Operand::A0A1DispBit(Register::A0, self.dispabs as u8 as u16),
606 Bit_Disp8_A1 => Operand::A0A1DispBit(Register::A1, self.dispabs as u8 as u16),
607 Bit_Disp8_SB => Operand::RegDispBit(Register::SB, (self.dispabs as u8 >> 3) as u16, self.dispabs as u8 & 0b111),
608 Bit_Disp8_FB => Operand::RegDispBit(Register::FB, (self.dispabs as u8 >> 3) as u16, self.dispabs as u8 & 0b111),
609 Bit_Disp16_A0 => Operand::A0A1DispBit(Register::A0, self.dispabs as u16),
610 Bit_Disp16_A1 => Operand::A0A1DispBit(Register::A1, self.dispabs as u16),
611 Bit_Disp16_SB => Operand::RegDispBit(Register::SB, self.dispabs as u16 >> 4, self.dispabs as u8 & 0b1111),
612 Bit_Abs16 => Operand::AbsoluteBit(self.dispabs),
613 Disp8_A0 => Operand::RegDeref(Register::A0, self.dispabs as i8 as i16),
614 Disp8_A1 => Operand::RegDeref(Register::A1, self.dispabs as i8 as i16),
615 Disp8_SB => Operand::RegDeref(Register::SB, self.dispabs as i8 as i16),
616 Disp8_FB => Operand::RegDeref(Register::FB, self.dispabs as i8 as i16),
617 Disp8_SP => Operand::RegDeref(Register::SP, self.dispabs as i8 as i16),
618 Disp16_A0 => Operand::RegDeref(Register::A0, self.dispabs as i16),
619 Disp16_A1 => Operand::RegDeref(Register::A1, self.dispabs as i16),
620 Disp16_SB => Operand::RegDeref(Register::SB, self.dispabs as i16),
621 Disp20_A0 => Operand::RegDeref(Register::A0, self.imm_wide as i16),
622 Disp20_A1 => Operand::RegDeref(Register::A1, self.imm_wide as i16),
623 Deref_A0 => Operand::RegDeref(Register::A0, self.dispabs as i16),
624 Deref_A1 => Operand::RegDeref(Register::A1, self.dispabs as i16),
625 Deref_A1A0 => Operand::RegDeref(Register::A1A0, self.dispabs as i16),
626 Abs16 => Operand::Absolute(self.dispabs as u32),
627 Disp2_8_A0 => Operand::RegDeref(Register::A0, self.imm_wide as i8 as i16),
628 Disp2_8_A1 => Operand::RegDeref(Register::A1, self.imm_wide as i8 as i16),
629 Disp2_8_SB => Operand::RegDeref(Register::SB, self.imm_wide as i8 as i16),
630 Disp2_8_FB => Operand::RegDeref(Register::FB, self.imm_wide as i8 as i16),
631 Disp2_16_A0 => Operand::RegDeref(Register::A0, self.imm_wide as i16),
632 Disp2_16_A1 => Operand::RegDeref(Register::A1, self.imm_wide as i16),
633 Disp2_16_SB => Operand::RegDeref(Register::SB, self.imm_wide as i16),
634 Abs2_16 => Operand::Absolute(self.imm_wide),
635 Abs20 => Operand::Absolute(self.imm_wide),
636 JmpAbs20 => Operand::JmpAbsolute(self.imm_wide),
637 Disp8 => Operand::Displacement(self.dispabs as u8 as i8 as i16),
638 JmpDisp8 => Operand::JmpDisplacement(self.dispabs as u8 as i8 as i16),
639 JmpDisp16 => Operand::JmpDisplacement(self.dispabs as i16),
640 RegList => Operand::RegList(self.imm_wide as u8),
641 INTBL => Operand::Register(Register::INTBL),
642 INTBH => Operand::Register(Register::INTBH),
643 FLG => Operand::Register(Register::FLG),
644 ISP => Operand::Register(Register::ISP),
645 SP => Operand::Register(Register::SP),
646 SB => Operand::Register(Register::SB),
647 FB => Operand::Register(Register::FB),
648 };
649 Some(operand)
650 }
651}
652
653#[cfg_attr(feature="use-serde", derive(Serialize, Deserialize))]
654#[derive(Debug)]
655pub struct M16C;
656
657impl Arch for M16C {
658 type Address = u32;
659 type Word = u8;
660 type Instruction = Instruction;
661 type DecodeError = StandardDecodeError;
662 type Decoder = InstDecoder;
663 type Operand = Operand;
664}
665
666impl fmt::Display for Instruction {
667 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
668 write!(f, "{}", self.opcode)?;
669 match self.operand(0) {
670 None => return Ok(()),
671 Some(op) => { write!(f, " {}", op)?; }
672 }
673 match self.operand(1) {
674 None => return Ok(()),
675 Some(op) => { write!(f, ", {}", op)?; }
676 }
677 Ok(())
678 }
679}
680
681impl LengthedInstruction for Instruction {
682 type Unit = AddressDiff<<M16C as Arch>::Address>;
683
684 fn min_size() -> Self::Unit {
685 AddressDiff::from_const(1)
686 }
687 fn len(&self) -> Self::Unit {
688 AddressDiff::from_const(self.length as u32)
689 }
690}
691
692impl Default for Instruction {
693 fn default() -> Self {
694 Instruction {
695 opcode: Opcode::NOP,
696 operands: [OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing],
697 imm_wide: 0,
698 dispabs: 0,
699 length: 0
700 }
701 }
702}
703
704impl yaxpeax_arch::Instruction for Instruction {
705 fn well_defined(&self) -> bool { true }
707}
708
709#[derive(Default, Debug)]
710pub struct InstDecoder {}
711
712impl fmt::Display for InstDecoder {
713 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
714 write!(f, "m16c")
715 }
716}
717
718impl Decoder<M16C> for InstDecoder {
719 fn decode_into<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(&self, inst: &mut Instruction, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
720 decode(self, inst, words)
721 }
722}
723
724enum OperandCategory {
725 ADJNZ,
726 Op74,
727 Op76,
728 Op78,
729 Op7A,
730 Op7B,
731 Op7C,
732 Op7D,
733 Op7E,
734 OpEB,
735 SrcDestRegOrDeref,
736 Imm4Dest,
737 JmpDispOpcodeLow3,
738}
739
740enum OperandInterpretation {
741 Just([OperandSpec; 3]),
742 Reinterpret(OperandCategory)
743}
744
745fn decode<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(_decoder: &InstDecoder, inst: &mut Instruction, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
746 let byte = words.next()?;
747 inst.length += 1;
748 let size = if byte & 1 == 0 {
750 Size::B
751 } else {
752 Size::W
753 };
754 use OperandInterpretation::*;
755 let (opcode, interpretation) = match byte {
756 0b0000_0000 => (Opcode::BRK, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
757 0b0000_0001 => (Opcode::MOV(Size::B), Just([OperandSpec::R0L, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
758 0b0000_0010 => (Opcode::MOV(Size::B), Just([OperandSpec::R0L, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
759 0b0000_0011 => (Opcode::MOV(Size::B), Just([OperandSpec::R0L, OperandSpec::Abs16, OperandSpec::Nothing])),
760 0b0000_0100 => (Opcode::NOP, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
761 0b0000_0101 => (Opcode::MOV(Size::B), Just([OperandSpec::R0H, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
762 0b0000_0110 => (Opcode::MOV(Size::B), Just([OperandSpec::R0H, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
763 0b0000_0111 => (Opcode::MOV(Size::B), Just([OperandSpec::R0H, OperandSpec::Abs16, OperandSpec::Nothing])),
764 0b0000_1000 => (Opcode::MOV(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])),
765 0b0000_1001 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
766 0b0000_1010 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
767 0b0000_1011 => (Opcode::MOV(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
768 0b0000_1100 => (Opcode::MOV(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])),
769 0b0000_1101 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
770 0b0000_1110 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
771 0b0000_1111 => (Opcode::MOV(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
772 0b0001_0000 => (Opcode::AND(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])), 0b0001_0001 => (Opcode::AND(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
774 0b0001_0010 => (Opcode::AND(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
775 0b0001_0011 => (Opcode::AND(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
776 0b0001_0100 => (Opcode::AND(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])), 0b0001_0101 => (Opcode::AND(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
778 0b0001_0110 => (Opcode::AND(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
779 0b0001_0111 => (Opcode::AND(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
780 0b0001_1000 => (Opcode::OR(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])), 0b0001_1001 => (Opcode::OR(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
782 0b0001_1010 => (Opcode::OR(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
783 0b0001_1011 => (Opcode::OR(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
784 0b0001_1100 => (Opcode::OR(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])), 0b0001_1101 => (Opcode::OR(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
786 0b0001_1110 => (Opcode::OR(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
787 0b0001_1111 => (Opcode::OR(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
788 0b0010_0000 => (Opcode::ADD(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])), 0b0010_0001 => (Opcode::ADD(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
790 0b0010_0010 => (Opcode::ADD(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
791 0b0010_0011 => (Opcode::ADD(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
792 0b0010_0100 => (Opcode::ADD(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])), 0b0010_0101 => (Opcode::ADD(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
794 0b0010_0110 => (Opcode::ADD(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
795 0b0010_0111 => (Opcode::ADD(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
796 0b0010_1000 => (Opcode::SUB(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])), 0b0010_1001 => (Opcode::SUB(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
798 0b0010_1010 => (Opcode::SUB(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
799 0b0010_1011 => (Opcode::SUB(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
800 0b0010_1100 => (Opcode::SUB(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])), 0b0010_1101 => (Opcode::SUB(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
802 0b0010_1110 => (Opcode::SUB(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
803 0b0010_1111 => (Opcode::SUB(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
804 0b0011_0000 => (Opcode::MOV(Size::B), Just([OperandSpec::R0H, OperandSpec::A0, OperandSpec::Nothing])), 0b0011_0001 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::A0, OperandSpec::Nothing])),
806 0b0011_0010 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::A0, OperandSpec::Nothing])),
807 0b0011_0011 => (Opcode::MOV(Size::B), Just([OperandSpec::Abs16, OperandSpec::A0, OperandSpec::Nothing])),
808 0b0011_0100 => (Opcode::MOV(Size::B), Just([OperandSpec::R0L, OperandSpec::A1, OperandSpec::Nothing])), 0b0011_0101 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::A1, OperandSpec::Nothing])),
810 0b0011_0110 => (Opcode::MOV(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::A1, OperandSpec::Nothing])),
811 0b0011_0111 => (Opcode::MOV(Size::B), Just([OperandSpec::Abs16, OperandSpec::A1, OperandSpec::Nothing])),
812 0b0011_1000 => (Opcode::CMP(Size::B), Just([OperandSpec::R0H, OperandSpec::R0L, OperandSpec::Nothing])), 0b0011_1001 => (Opcode::CMP(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0L, OperandSpec::Nothing])),
814 0b0011_1010 => (Opcode::CMP(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0L, OperandSpec::Nothing])),
815 0b0011_1011 => (Opcode::CMP(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0L, OperandSpec::Nothing])),
816 0b0011_1100 => (Opcode::CMP(Size::B), Just([OperandSpec::R0L, OperandSpec::R0H, OperandSpec::Nothing])), 0b0011_1101 => (Opcode::CMP(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::R0H, OperandSpec::Nothing])),
818 0b0011_1110 => (Opcode::CMP(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::R0H, OperandSpec::Nothing])),
819 0b0011_1111 => (Opcode::CMP(Size::B), Just([OperandSpec::Abs16, OperandSpec::R0H, OperandSpec::Nothing])),
820 0b0100_0000 => (Opcode::BCLR, Just([OperandSpec::Bit0, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
821 0b0100_0001 => (Opcode::BCLR, Just([OperandSpec::Bit1, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
822 0b0100_0010 => (Opcode::BCLR, Just([OperandSpec::Bit2, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
823 0b0100_0011 => (Opcode::BCLR, Just([OperandSpec::Bit3, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
824 0b0100_0100 => (Opcode::BCLR, Just([OperandSpec::Bit4, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
825 0b0100_0101 => (Opcode::BCLR, Just([OperandSpec::Bit5, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
826 0b0100_0110 => (Opcode::BCLR, Just([OperandSpec::Bit6, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
827 0b0100_0111 => (Opcode::BCLR, Just([OperandSpec::Bit7, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
828 0b0100_1000 => (Opcode::BSET, Just([OperandSpec::Bit0, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
829 0b0100_1001 => (Opcode::BSET, Just([OperandSpec::Bit1, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
830 0b0100_1010 => (Opcode::BSET, Just([OperandSpec::Bit2, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
831 0b0100_1011 => (Opcode::BSET, Just([OperandSpec::Bit3, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
832 0b0100_1100 => (Opcode::BSET, Just([OperandSpec::Bit4, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
833 0b0100_1101 => (Opcode::BSET, Just([OperandSpec::Bit5, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
834 0b0100_1110 => (Opcode::BSET, Just([OperandSpec::Bit6, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
835 0b0100_1111 => (Opcode::BSET, Just([OperandSpec::Bit7, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
836 0b0101_0000 => (Opcode::BNOT, Just([OperandSpec::Bit0, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
837 0b0101_0001 => (Opcode::BNOT, Just([OperandSpec::Bit1, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
838 0b0101_0010 => (Opcode::BNOT, Just([OperandSpec::Bit2, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
839 0b0101_0011 => (Opcode::BNOT, Just([OperandSpec::Bit3, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
840 0b0101_0100 => (Opcode::BNOT, Just([OperandSpec::Bit4, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
841 0b0101_0101 => (Opcode::BNOT, Just([OperandSpec::Bit5, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
842 0b0101_0110 => (Opcode::BNOT, Just([OperandSpec::Bit6, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
843 0b0101_0111 => (Opcode::BNOT, Just([OperandSpec::Bit7, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
844 0b0101_1000 => (Opcode::BTST, Just([OperandSpec::Bit0, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
845 0b0101_1001 => (Opcode::BTST, Just([OperandSpec::Bit1, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
846 0b0101_1010 => (Opcode::BTST, Just([OperandSpec::Bit2, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
847 0b0101_1011 => (Opcode::BTST, Just([OperandSpec::Bit3, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
848 0b0101_1100 => (Opcode::BTST, Just([OperandSpec::Bit4, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
849 0b0101_1101 => (Opcode::BTST, Just([OperandSpec::Bit5, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
850 0b0101_1110 => (Opcode::BTST, Just([OperandSpec::Bit6, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
851 0b0101_1111 => (Opcode::BTST, Just([OperandSpec::Bit7, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
852 0b0110_0000 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
853 0b0110_0001 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
854 0b0110_0010 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
855 0b0110_0011 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
856 0b0110_0100 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
857 0b0110_0101 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
858 0b0110_0110 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
859 0b0110_0111 => (Opcode::JMP(Size::S), Reinterpret(OperandCategory::JmpDispOpcodeLow3)),
860 0b0110_1000 => (Opcode::JGEU, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
861 0b0110_1001 => (Opcode::JGTU, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
862 0b0110_1010 => (Opcode::JEQ, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
863 0b0110_1011 => (Opcode::JN, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
864 0b0110_1100 => (Opcode::JLTU, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
865 0b0110_1101 => (Opcode::JLEU, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
866 0b0110_1110 => (Opcode::JNE, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
867 0b0110_1111 => (Opcode::JPZ, Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
868 0b0111_0000 => (Opcode::MULU(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
869 0b0111_0001 => (Opcode::MULU(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
870 0b0111_0010 => (Opcode::MOV(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
871 0b0111_0011 => (Opcode::MOV(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
872 0b0111_0100 => (Opcode::NOP, Reinterpret(OperandCategory::Op74)),
873 0b0111_0101 => (Opcode::NOP, Reinterpret(OperandCategory::Op74)),
874 0b0111_0110 => (Opcode::NOP, Reinterpret(OperandCategory::Op76)),
875 0b0111_0111 => (Opcode::NOP, Reinterpret(OperandCategory::Op76)),
876 0b0111_1000 => (Opcode::NOP, Reinterpret(OperandCategory::Op78)),
877 0b0111_1001 => (Opcode::NOP, Reinterpret(OperandCategory::Op78)),
878 0b0111_1010 => (Opcode::NOP, Reinterpret(OperandCategory::Op7A)),
879 0b0111_1011 => (Opcode::NOP, Reinterpret(OperandCategory::Op7B)),
880 0b0111_1100 => (Opcode::NOP, Reinterpret(OperandCategory::Op7C)),
881 0b0111_1101 => (Opcode::NOP, Reinterpret(OperandCategory::Op7D)),
882 0b0111_1110 => (Opcode::NOP, Reinterpret(OperandCategory::Op7E)),
883 0b0111_1111 => { return Err(StandardDecodeError::InvalidOperand); },
884 0b1000_0000 => (Opcode::TST(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
885 0b1000_0001 => (Opcode::TST(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
886 0b1000_0010 => (Opcode::PUSH(Size::B), Just([OperandSpec::R0L, OperandSpec::Nothing, OperandSpec::Nothing])),
887 0b1000_0011 => (Opcode::ADD(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
888 0b1000_0100 => (Opcode::ADD(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
889 0b1000_0101 => (Opcode::ADD(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
890 0b1000_0110 => (Opcode::ADD(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
891 0b1000_0111 => (Opcode::ADD(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
892 0b1000_1000 => (Opcode::XOR(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
893 0b1000_1001 => (Opcode::XOR(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
894 0b1000_1010 => (Opcode::PUSH(Size::B), Just([OperandSpec::R0H, OperandSpec::Nothing, OperandSpec::Nothing])),
895 0b1000_1011 => (Opcode::SUB(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
896 0b1000_1100 => (Opcode::SUB(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
897 0b1000_1101 => (Opcode::SUB(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
898 0b1000_1110 => (Opcode::SUB(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
899 0b1000_1111 => (Opcode::SUB(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
900 0b1001_0000 => (Opcode::AND(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
901 0b1001_0001 => (Opcode::AND(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
902 0b1001_0010 => (Opcode::POP, Just([OperandSpec::R0L, OperandSpec::Nothing, OperandSpec::Nothing])),
903 0b1001_0011 => (Opcode::AND(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
904 0b1001_0100 => (Opcode::AND(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
905 0b1001_0101 => (Opcode::AND(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
906 0b1001_0110 => (Opcode::AND(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
907 0b1001_0111 => (Opcode::AND(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
908 0b1001_1000 => (Opcode::OR(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
909 0b1001_1001 => (Opcode::OR(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
910 0b1001_1010 => (Opcode::POP, Just([OperandSpec::R0H, OperandSpec::Nothing, OperandSpec::Nothing])),
911 0b1001_1011 => (Opcode::OR(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
912 0b1001_1100 => (Opcode::OR(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
913 0b1001_1101 => (Opcode::OR(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
914 0b1001_1110 => (Opcode::OR(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
915 0b1001_1111 => (Opcode::OR(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
916 0b1010_0000 => (Opcode::ADD(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
917 0b1010_0001 => (Opcode::ADD(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
918 0b1010_0010 => (Opcode::MOV(Size::W), Just([OperandSpec::Imm16, OperandSpec::A0, OperandSpec::Nothing])),
919 0b1010_0011 => (Opcode::INC(Size::B), Just([OperandSpec::R0H, OperandSpec::Nothing, OperandSpec::Nothing])),
920 0b1010_0100 => (Opcode::INC(Size::B), Just([OperandSpec::R0L, OperandSpec::Nothing, OperandSpec::Nothing])),
921 0b1010_0101 => (Opcode::INC(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::Nothing, OperandSpec::Nothing])),
922 0b1010_0110 => (Opcode::INC(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::Nothing, OperandSpec::Nothing])),
923 0b1010_0111 => (Opcode::INC(Size::B), Just([OperandSpec::Abs16, OperandSpec::Nothing, OperandSpec::Nothing])),
924 0b1010_1000 => (Opcode::SUB(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
925 0b1010_1001 => (Opcode::SUB(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
926 0b1010_1010 => (Opcode::MOV(Size::W), Just([OperandSpec::Imm16, OperandSpec::A1, OperandSpec::Nothing])),
927 0b1010_1011 => (Opcode::DEC(Size::B), Just([OperandSpec::R0H, OperandSpec::Nothing, OperandSpec::Nothing])),
928 0b1010_1100 => (Opcode::DEC(Size::B), Just([OperandSpec::R0L, OperandSpec::Nothing, OperandSpec::Nothing])),
929 0b1010_1101 => (Opcode::DEC(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::Nothing, OperandSpec::Nothing])),
930 0b1010_1110 => (Opcode::DEC(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::Nothing, OperandSpec::Nothing])),
931 0b1010_1111 => (Opcode::DEC(Size::B), Just([OperandSpec::Abs16, OperandSpec::Nothing, OperandSpec::Nothing])),
932 0b1011_0000 => (Opcode::ADC(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
933 0b1011_0001 => (Opcode::ADC(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
934 0b1011_0010 => (Opcode::INC(Size::W), Just([OperandSpec::A0, OperandSpec::Nothing, OperandSpec::Nothing])),
935 0b1011_0011 => (Opcode::MOV(Size::B), Just([OperandSpec::Zero, OperandSpec::R0H, OperandSpec::Nothing])),
936 0b1011_0100 => (Opcode::MOV(Size::B), Just([OperandSpec::Zero, OperandSpec::R0L, OperandSpec::Nothing])),
937 0b1011_0101 => (Opcode::MOV(Size::B), Just([OperandSpec::Zero, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
938 0b1011_0110 => (Opcode::MOV(Size::B), Just([OperandSpec::Zero, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
939 0b1011_0111 => (Opcode::MOV(Size::B), Just([OperandSpec::Zero, OperandSpec::Abs16, OperandSpec::Nothing])),
940 0b1011_1000 => (Opcode::SBB(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
941 0b1011_1001 => (Opcode::SBB(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
942 0b1011_1010 => (Opcode::INC(Size::W), Just([OperandSpec::A1, OperandSpec::Nothing, OperandSpec::Nothing])),
943 0b1011_1011 => (Opcode::NOT(Size::B), Just([OperandSpec::R0H, OperandSpec::Nothing, OperandSpec::Nothing])),
944 0b1011_1100 => (Opcode::NOT(Size::B), Just([OperandSpec::R0L, OperandSpec::Nothing, OperandSpec::Nothing])),
945 0b1011_1101 => (Opcode::NOT(Size::B), Just([OperandSpec::Disp8_SB, OperandSpec::Nothing, OperandSpec::Nothing])),
946 0b1011_1110 => (Opcode::NOT(Size::B), Just([OperandSpec::Disp8_FB, OperandSpec::Nothing, OperandSpec::Nothing])),
947 0b1011_1111 => (Opcode::NOT(Size::B), Just([OperandSpec::Abs16, OperandSpec::Nothing, OperandSpec::Nothing])),
948 0b1100_0000 => (Opcode::CMP(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
949 0b1100_0001 => (Opcode::CMP(size), Reinterpret(OperandCategory::SrcDestRegOrDeref)),
950 0b1100_0010 => (Opcode::PUSH(Size::W), Just([OperandSpec::A0, OperandSpec::Nothing, OperandSpec::Nothing])),
951 0b1100_0011 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
952 0b1100_0100 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
953 0b1100_0101 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
954 0b1100_0110 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
955 0b1100_0111 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
956 0b1100_1000 => (Opcode::ADD(size), Reinterpret(OperandCategory::Imm4Dest)),
957 0b1100_1001 => (Opcode::ADD(size), Reinterpret(OperandCategory::Imm4Dest)),
958 0b1100_1010 => (Opcode::PUSH(Size::W), Just([OperandSpec::A1, OperandSpec::Nothing, OperandSpec::Nothing])),
959 0b1100_1011 => (Opcode::STZ, Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
960 0b1100_1100 => (Opcode::STZ, Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
961 0b1100_1101 => (Opcode::STZ, Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
962 0b1100_1110 => (Opcode::STX, Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
963 0b1100_1111 => (Opcode::STZ, Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
964 0b1101_0000 => (Opcode::CMP(size), Reinterpret(OperandCategory::Imm4Dest)),
965 0b1101_0001 => (Opcode::CMP(size), Reinterpret(OperandCategory::Imm4Dest)),
966 0b1101_0010 => (Opcode::POP, Just([OperandSpec::A0, OperandSpec::Nothing, OperandSpec::Nothing])),
967 0b1101_0011 => (Opcode::STNZ, Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
968 0b1101_0100 => (Opcode::STNZ, Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
969 0b1101_0101 => (Opcode::STNZ, Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
970 0b1101_0110 => (Opcode::STNZ, Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
971 0b1101_0111 => (Opcode::STNZ, Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
972 0b1101_1000 => (Opcode::MOV(size), Reinterpret(OperandCategory::Imm4Dest)),
973 0b1101_1001 => (Opcode::MOV(size), Reinterpret(OperandCategory::Imm4Dest)),
974 0b1101_1010 => (Opcode::POP, Just([OperandSpec::A1, OperandSpec::Nothing, OperandSpec::Nothing])),
975 0b1101_1011 => (Opcode::STZX, Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Imm82])),
976 0b1101_1100 => (Opcode::STZX, Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Imm82])),
977 0b1101_1101 => (Opcode::STZX, Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Imm82])),
978 0b1101_1110 => (Opcode::STZX, Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Imm82])),
979 0b1101_1111 => (Opcode::STZX, Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Imm82])),
980 0b1110_0000 => (Opcode::ROT(size), Reinterpret(OperandCategory::Imm4Dest)),
981 0b1110_0001 => (Opcode::ROT(size), Reinterpret(OperandCategory::Imm4Dest)),
982 0b1110_0010 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::A0, OperandSpec::Nothing])),
983 0b1110_0011 => (Opcode::CMP(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0H, OperandSpec::Nothing])),
984 0b1110_0100 => (Opcode::CMP(Size::B), Just([OperandSpec::Imm8, OperandSpec::R0L, OperandSpec::Nothing])),
985 0b1110_0101 => (Opcode::CMP(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_SB, OperandSpec::Nothing])),
986 0b1110_0110 => (Opcode::CMP(Size::B), Just([OperandSpec::Imm8, OperandSpec::Disp8_FB, OperandSpec::Nothing])),
987 0b1110_0111 => (Opcode::CMP(Size::B), Just([OperandSpec::Imm8, OperandSpec::Abs16, OperandSpec::Nothing])),
988 0b1110_1000 => (Opcode::SHA(size), Reinterpret(OperandCategory::Imm4Dest)),
989 0b1110_1001 => (Opcode::SHA(size), Reinterpret(OperandCategory::Imm4Dest)),
990 0b1110_1010 => (Opcode::MOV(Size::B), Just([OperandSpec::Imm8, OperandSpec::A1, OperandSpec::Nothing])),
991 0b1110_1011 => (Opcode::NOP, Reinterpret(OperandCategory::OpEB)), 0b1110_1100 => (Opcode::PUSHM, Just([OperandSpec::RegList, OperandSpec::Nothing, OperandSpec::Nothing])),
993 0b1110_1101 => (Opcode::POPM, Just([OperandSpec::RegList, OperandSpec::Nothing, OperandSpec::Nothing])),
994 0b1110_1110 => (Opcode::JMPS, Just([OperandSpec::Imm8, OperandSpec::Nothing, OperandSpec::Nothing])),
995 0b1110_1111 => (Opcode::JSRS, Just([OperandSpec::Imm8, OperandSpec::Nothing, OperandSpec::Nothing])),
996 0b1111_0000 => (Opcode::SHA(size), Reinterpret(OperandCategory::Imm4Dest)),
997 0b1111_0001 => (Opcode::SHA(size), Reinterpret(OperandCategory::Imm4Dest)),
998 0b1111_0010 => (Opcode::DEC(Size::W), Just([OperandSpec::A0, OperandSpec::Nothing, OperandSpec::Nothing])),
999 0b1111_0011 => (Opcode::RTS, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
1000 0b1111_0100 => (Opcode::JMP(Size::W), Just([OperandSpec::JmpDisp16, OperandSpec::Nothing, OperandSpec::Nothing])),
1001 0b1111_0101 => (Opcode::JSR(Size::W), Just([OperandSpec::JmpDisp16, OperandSpec::Nothing, OperandSpec::Nothing])),
1002 0b1111_0110 => (Opcode::INTO, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
1003 0b1111_0111 => { return Err(StandardDecodeError::InvalidOperand); },
1004 0b1111_1000 => (Opcode::ADJNZ(size), Reinterpret(OperandCategory::ADJNZ)),
1005 0b1111_1001 => (Opcode::ADJNZ(size), Reinterpret(OperandCategory::ADJNZ)),
1006 0b1111_1010 => (Opcode::DEC(Size::W), Just([OperandSpec::A1, OperandSpec::Nothing, OperandSpec::Nothing])),
1007 0b1111_1011 => (Opcode::REIT, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
1008 0b1111_1100 => (Opcode::JMP(Size::A), Just([OperandSpec::JmpAbs20, OperandSpec::Nothing, OperandSpec::Nothing])),
1009 0b1111_1101 => (Opcode::JSR(Size::A), Just([OperandSpec::JmpAbs20, OperandSpec::Nothing, OperandSpec::Nothing])),
1010 0b1111_1110 => (Opcode::JMP(Size::B), Just([OperandSpec::JmpDisp8, OperandSpec::Nothing, OperandSpec::Nothing])),
1011 0b1111_1111 => (Opcode::UND, Just([OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing])),
1012 };
1013 inst.opcode = opcode;
1014 match interpretation {
1015 Just(operands) => {
1016 inst.operands = operands;
1017
1018 if let OperandSpec::Imm8 = inst.operands[0] {
1024 inst.imm_wide = read_imm(words, 1)? as u32;
1025 inst.length += 1;
1026 }
1027
1028 for op in inst.operands.iter() {
1031 use OperandSpec::*;
1032 match op {
1033 RegList => {
1034 inst.imm_wide = read_imm(words, 1)? as u32;
1035 inst.length += 1;
1036
1037 if let Opcode::POPM = inst.opcode {
1042 let mut replacement_imm = 0u8;
1043 for i in 0..8 {
1044 if inst.imm_wide & (1 << i) != 0 {
1045 replacement_imm |= 1 << (7 - i);
1046 }
1047 }
1048 inst.imm_wide = replacement_imm as u32;
1049 }
1050 },
1051 JmpDisp8 |
1052 Disp8 |
1053 Disp8_FB |
1054 Disp8_SB => {
1055 inst.dispabs = read_imm(words, 1)? as i8 as i16 as u16;
1057 inst.length += 1;
1058 }
1059 JmpDisp16 |
1060 Abs16 => {
1061 inst.dispabs = read_imm(words, 2)? as u16;
1062 inst.length += 2;
1063 }
1064 JmpAbs20 |
1065 Abs20 => {
1066 inst.imm_wide = read_imm(words, 3)? as u32 & 0x0f_ff_ff;
1067 inst.length += 3;
1068 }
1069 Disp8_A0 |
1070 Disp8_A1 |
1071 Disp8_SP |
1072 Disp16_A0 |
1073 Disp16_A1 |
1074 Disp16_SB |
1075 Disp20_A0 |
1076 Disp20_A1 |
1077 Deref_A0 |
1078 Deref_A1 |
1079 Deref_A1A0 |
1080 Disp2_8_A0 |
1081 Disp2_8_A1 |
1082 Disp2_8_SB |
1083 Disp2_8_FB |
1084 Disp2_16_A0 |
1085 Disp2_16_A1 |
1086 Disp2_16_SB |
1087 Abs2_16 |
1088 Bit_Disp8_A0 |
1089 Bit_Disp8_A1 |
1090 Bit_Disp8_SB |
1091 Bit_Disp8_FB |
1092 Bit_Disp16_A0 |
1093 Bit_Disp16_A1 |
1094 Bit_Disp16_SB |
1095 Bit_Abs16 => {
1096 panic!("unexpected operand spec for Just set of operands: {:?}", op);
1097 }
1098 _ => {}
1100 }
1101 }
1102
1103 if let OperandSpec::Imm82 = inst.operands[2] {
1105 inst.imm_wide |= (words.next()? as u32) << 8;
1106 inst.length += 1;
1107 }
1108
1109 return Ok(());
1110 },
1111 Reinterpret(OperandCategory::Op74) => {
1112 return decode_op74(inst, size, words);
1113 },
1114 Reinterpret(OperandCategory::Op76) => {
1115 return decode_op76(inst, size, words);
1116 },
1117 Reinterpret(OperandCategory::Op78) => {
1118 return decode_op78(inst, size, words);
1119 },
1120 Reinterpret(OperandCategory::Op7A) => {
1121 return decode_op7A(inst, size, words);
1122 },
1123 Reinterpret(OperandCategory::Op7B) => {
1124 return decode_op7B(inst, size, words);
1125 },
1126 Reinterpret(OperandCategory::Op7C) => {
1127 return decode_op7C(inst, size, words);
1128 },
1129 Reinterpret(OperandCategory::Op7D) => {
1130 return decode_op7D(inst, size, words);
1131 },
1132 Reinterpret(OperandCategory::Op7E) => {
1133 return decode_op7E(inst, size, words);
1134 },
1135 Reinterpret(OperandCategory::OpEB) => {
1136 return decode_opEB(inst, size, words);
1137 },
1138 Reinterpret(OperandCategory::Imm4Dest) => {
1139 let operands = words.next()?;
1140 inst.length += 1;
1141 inst.imm_wide = (operands as i8 >> 4) as i32 as u32;
1142 inst.operands[0] = OperandSpec::Imm4;
1143 inst.operands[1] = Operand_RegDerefDispAbs(operands & 0b1111, size, inst, words)?;
1144 inst.operands[2] = OperandSpec::Nothing;
1145 }
1146 Reinterpret(OperandCategory::JmpDispOpcodeLow3) => {
1147 inst.dispabs = (byte & 0b111) as u16;
1148 inst.operands[0] = OperandSpec::Disp8;
1149 inst.operands[1] = OperandSpec::Nothing;
1150 inst.operands[2] = OperandSpec::Nothing;
1151 }
1152 Reinterpret(OperandCategory::ADJNZ) => {
1153 let operands = words.next()?;
1156 inst.length += 1;
1157 inst.imm_wide = ((operands as i8) >> 4) as u32;
1158 inst.operands[0] = OperandSpec::Imm4;
1159 inst.operands[1] = Operand_RegDerefDispAbs(operands & 0b1111, size, inst, words)?;
1160 inst.operands[2] = OperandSpec::Label8;
1161 }
1162 Reinterpret(OperandCategory::SrcDestRegOrDeref) => {
1163 let operands = words.next()?;
1166 inst.length += 1;
1167 inst.operands[0] = Operand_RegDerefDispAbs(operands >> 4, size, inst, words)?;
1168 inst.operands[1] = Operand_second_RegDerefDispAbs(operands & 0b1111, size, inst, words)?;
1169 inst.operands[2] = OperandSpec::Nothing;
1170 }
1171 }
1172 Ok(())
1173}
1174
1175fn decode_op74<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1176 let byte = words.next()?;
1177 inst.length += 1;
1178 match byte >> 4 {
1179 0b0000 => {
1180 inst.opcode = Opcode::STE;
1181 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1182 inst.operands[1] = OperandSpec::Abs20;
1183 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1184 inst.length += 3;
1185 }
1186 0b0001 => {
1187 inst.opcode = Opcode::STE;
1188 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1189 inst.operands[1] = OperandSpec::Disp20_A0;
1190 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1191 inst.length += 3;
1192 }
1193 0b0010 => {
1194 inst.opcode = Opcode::STE;
1195 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1196 inst.operands[1] = OperandSpec::Deref_A1A0;
1197 }
1198 0b0011 => {
1199 inst.opcode = Opcode::MOV(size);
1200 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1201 inst.operands[1] = OperandSpec::Disp8_SP;
1202 }
1203 0b0100 => {
1204 inst.opcode = Opcode::PUSH(size);
1205 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1206 inst.operands[1] = OperandSpec::Nothing;
1207 }
1208 0b0101 => {
1209 inst.opcode = Opcode::NEG;
1210 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1211 inst.operands[1] = OperandSpec::Nothing;
1212 }
1213 0b0110 => {
1214 inst.opcode = Opcode::ROT(size);
1215 if size == Size::W && byte & 0b1111 == 0b0001 {
1216 return Err(StandardDecodeError::InvalidOperand);
1218 } else if size == Size::B && byte & 0b1111 == 0b0011 {
1219 return Err(StandardDecodeError::InvalidOperand);
1221 }
1222
1223 inst.operands[0] = OperandSpec::R1H;
1224 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1225 }
1226 0b0111 => {
1227 inst.opcode = Opcode::NOT(size);
1228 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1229 inst.operands[1] = OperandSpec::Nothing;
1230 }
1231 0b1000 => {
1232 inst.opcode = Opcode::LDE;
1233 inst.operands[0] = OperandSpec::Abs20;
1234 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1235 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1237 inst.length += 3;
1238 }
1239 0b1001 => {
1240 inst.opcode = Opcode::LDE;
1241 inst.operands[0] = OperandSpec::Disp20_A0;
1242 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1243 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1245 inst.length += 3;
1246 }
1247 0b1010 => {
1248 inst.opcode = Opcode::LDE;
1249 inst.operands[0] = OperandSpec::Deref_A1A0;
1250 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1251 }
1252 0b1011 => {
1253 inst.opcode = Opcode::MOV(size);
1254 inst.operands[0] = OperandSpec::Disp8_SP;
1255 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1256 inst.dispabs = read_imm(words, 1)? as u16;
1258 inst.length += 1;
1259 }
1260 0b1100 => {
1261 inst.opcode = Opcode::MOV(size);
1262 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1263 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1264 inst.imm_wide = read_imm(words, size.as_bytes())? as u32;
1266 inst.length += size.as_bytes();
1267 }
1268 0b1101 => {
1269 inst.opcode = Opcode::POP;
1270 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1271 inst.operands[1] = OperandSpec::Nothing;
1272 }
1273 0b1110 => {
1274 inst.opcode = Opcode::SHL(size);
1275 if size == Size::W && byte & 0b1111 == 0b0001 {
1276 return Err(StandardDecodeError::InvalidOperand);
1278 } else if size == Size::B && byte & 0b1111 == 0b0011 {
1279 return Err(StandardDecodeError::InvalidOperand);
1281 }
1282
1283 inst.operands[0] = OperandSpec::R1H;
1284 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1285 }
1286 0b1111 => {
1287 inst.opcode = Opcode::SHA(size);
1288 if size == Size::W && byte & 0b1111 == 0b0001 {
1289 return Err(StandardDecodeError::InvalidOperand);
1291 } else if size == Size::B && byte & 0b1111 == 0b0011 {
1292 return Err(StandardDecodeError::InvalidOperand);
1294 }
1295
1296 inst.operands[0] = OperandSpec::R1H;
1297 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1298 }
1299 _ => {
1300 unreachable!("opcode selector is four bits");
1301 }
1302 }
1303
1304 Ok(())
1305}
1306
1307fn decode_op76<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1308 let byte = words.next()?;
1309 inst.length += 1;
1310 let opc_selector = byte >> 4;
1311 if opc_selector < 0b1001 {
1312 inst.opcode = [
1313 Opcode::TST(size), Opcode::XOR(size), Opcode::AND(size),
1314 Opcode::OR(size), Opcode::ADD(size), Opcode::SUB(size),
1315 Opcode::ADC(size), Opcode::SBB(size), Opcode::CMP(size)
1316 ][opc_selector as usize];
1317 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1318 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1319 inst.imm_wide = read_imm(words, size.as_bytes())?;
1320 inst.length += size.as_bytes();
1321 } else {
1322 match opc_selector {
1323 0b1001 => {
1324 inst.opcode = Opcode::DIVX(size);
1325 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1326 inst.imm_wide = read_imm(words, size.as_bytes())?;
1327 inst.length += size.as_bytes();
1328 }
1329 0b1010 => {
1330 inst.opcode = Opcode::ROLC;
1331 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1332 inst.operands[1] = OperandSpec::Nothing;
1333 }
1334 0b1011 => {
1335 inst.opcode = Opcode::RORC;
1336 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1337 inst.operands[1] = OperandSpec::Nothing;
1338 }
1339 0b1100 => {
1340 inst.opcode = Opcode::DIVU(size);
1341 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1342 inst.imm_wide = read_imm(words, size.as_bytes())?;
1343 inst.length += size.as_bytes();
1344 }
1345 0b1101 => {
1346 inst.opcode = Opcode::DIV(size);
1347 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1348 inst.operands[1] = OperandSpec::Nothing;
1349 }
1350 0b1110 => {
1351 inst.opcode = Opcode::ADCF(size);
1352 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1353 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1354 inst.imm_wide = read_imm(words, size.as_bytes())?;
1355 inst.length += size.as_bytes();
1356 }
1357 0b1111 => {
1358 inst.opcode = Opcode::ABS;
1359 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1360 inst.operands[1] = OperandSpec::Nothing;
1361 }
1362 _ => {
1363 unreachable!("opcode selector is four bits");
1364 }
1365 }
1366 }
1367
1368 Ok(())
1369}
1370
1371fn decode_op78<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1372 let byte = words.next()?;
1373 inst.length += 1;
1374 inst.opcode = Opcode::MUL;
1375 inst.operands[0] = Operand_RegDerefDispAbs(byte >> 4, size, inst, words)?;
1376 let dest_code = byte & 0b1111;
1377 match (size, dest_code) {
1378 (Size::B, 0b0001) |
1379 (Size::W, 0b0010) |
1380 (_, 0b0011) |
1381 (_, 0b0101) => {
1382 return Err(StandardDecodeError::InvalidOperand);
1383 }
1384 _ => {}
1385 }
1386 inst.operands[1] = Operand_RegDerefDispAbs(dest_code, size, inst, words)?;
1387
1388 Ok(())
1389}
1390
1391fn decode_op7A<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1392 let byte = words.next()?;
1393 inst.length += 1;
1394 if byte >= 0b10000000 {
1395 inst.opcode = Opcode::LDC;
1396 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1397 inst.operands[1] = Operand_IntFlgSpSbFb((byte >> 4) & 0b111)?;
1398 } else {
1399 inst.opcode = Opcode::XCHG(size);
1400 assert_eq!(size, Size::B);
1401 if byte >= 0b01000000 {
1402 return Err(StandardDecodeError::InvalidOperand);
1403 }
1404 inst.operands[0] = [
1405 OperandSpec::R0L, OperandSpec::R0H,
1406 OperandSpec::R1L, OperandSpec::R1H,
1407 ][(byte >> 4) as usize];
1408 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1409 }
1410
1411 Ok(())
1412}
1413
1414fn decode_op7B<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1415 let byte = words.next()?;
1416 inst.length += 1;
1417 if byte >= 0b10000000 {
1418 inst.opcode = Opcode::STC;
1419 inst.operands[1] = Operand_IntFlgSpSbFb((byte >> 4) & 0b111)?;
1420 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1421 } else {
1422 inst.opcode = Opcode::XCHG(size);
1423 assert_eq!(size, Size::W);
1424 if byte >= 0b01000000 {
1425 return Err(StandardDecodeError::InvalidOperand);
1426 }
1427 inst.operands[0] = [
1428 OperandSpec::R0, OperandSpec::R1,
1429 OperandSpec::R2, OperandSpec::R3,
1430 ][(byte >> 4) as usize];
1431 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1432 }
1433
1434 Ok(())
1435}
1436
1437fn decode_op7C<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1438 let byte = words.next()?;
1439 inst.length += 1;
1440 match byte >> 4 {
1441 op @ 0b0000 |
1442 op @ 0b0001 |
1443 op @ 0b0010 |
1444 op @ 0b0011 => {
1445 inst.opcode = [
1446 Opcode::MOVLL, Opcode::MOVLH,
1447 Opcode::MOVHL, Opcode::MOVHH,
1448 ][op as usize];
1449 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1450 inst.operands[1] = OperandSpec::R0L;
1451 },
1452 0b0100 => {
1453 inst.opcode = Opcode::MULU(size);
1454 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1455 inst.operands[1] = Operand_RegDerefDispAbs(byte >> 4, size, inst, words)?;
1456 let dest_code = byte & 0b1111;
1457 match (size, dest_code) {
1458 (Size::B, 0b0001) |
1459 (Size::W, 0b0010) |
1460 (_, 0b0011) |
1461 (_, 0b0101) => {
1462 return Err(StandardDecodeError::InvalidOperand);
1463 }
1464 _ => {}
1465 }
1466 inst.imm_wide = read_imm(words, size.as_bytes())?;
1468 inst.length += size.as_bytes();
1469 },
1470 0b0101 => {
1471 inst.opcode = Opcode::MUL;
1472 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1473 inst.operands[1] = Operand_RegDerefDispAbs(byte >> 4, size, inst, words)?;
1474 let dest_code = byte & 0b1111;
1475 match (size, dest_code) {
1476 (Size::B, 0b0001) |
1477 (Size::W, 0b0010) |
1478 (_, 0b0011) |
1479 (_, 0b0101) => {
1480 return Err(StandardDecodeError::InvalidOperand);
1481 }
1482 _ => {}
1483 }
1484 inst.imm_wide = read_imm(words, size.as_bytes())?;
1486 inst.length += size.as_bytes();
1487 }
1488 0b0110 => {
1489 inst.opcode = Opcode::EXTS;
1491 match byte & 0b1111 {
1492 0b0001 |
1493 0b0011 |
1494 0b0100 |
1495 0b0101 => {
1496 return Err(StandardDecodeError::InvalidOperand);
1497 }
1498 _ => {}
1499 }
1500 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1501 inst.operands[1] = OperandSpec::Nothing;
1502 }
1503 op @ 0b1000 |
1504 op @ 0b1001 |
1505 op @ 0b1010 |
1506 op @ 0b1011 => {
1507 inst.opcode = [
1508 Opcode::MOVLL, Opcode::MOVLH,
1509 Opcode::MOVHL, Opcode::MOVHH,
1510 ][(op & 0b11) as usize];
1511 inst.operands[0] = OperandSpec::R0L;
1512 inst.operands[1] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1513 }
1514 0b1100 => {
1515 inst.opcode = Opcode::EXTS;
1516 let dest = match byte & 0b1111 {
1517 0b0010 |
1518 0b0011 |
1519 0b0101 => {
1520 return Err(StandardDecodeError::InvalidOperand);
1521 }
1522 0b0000 => OperandSpec::R2R0,
1523 0b0001 => OperandSpec::R3R1,
1524 0b0100 => OperandSpec::A1A0,
1525 code => {
1526 Operand_RegDerefDispAbs(code, size, inst, words)?
1527 }
1528 };
1529 inst.operands[0] = dest;
1530 inst.operands[1] = OperandSpec::Nothing;
1531 }
1532 0b1110 => {
1533 let code = byte & 0b1111;
1534 if code & 0b111 < 0b100 {
1535 match code {
1536 op @ 0b0000 |
1537 op @ 0b0001 |
1538 op @ 0b0010 |
1539 op @ 0b0011 => {
1540 inst.opcode = [
1541 Opcode::DIVU(size), Opcode::DIV(size),
1542 Opcode::PUSH(size), Opcode::DIVX(size),
1543 ][op as usize];
1544 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1545 inst.operands[1] = OperandSpec::Nothing;
1546 inst.operands[2] = OperandSpec::Nothing;
1547 inst.imm_wide = read_imm(words, size.as_bytes())?;
1548 inst.length += size.as_bytes();
1549 }
1550 op @ 0b1000 |
1551 op @ 0b1001 |
1552 op @ 0b1010 => {
1553 inst.opcode = [
1554 Opcode::SMOVF(size), Opcode::SMOVB(size),
1555 Opcode::SSTR(size),
1556 ][(op & 0b11) as usize];
1557 inst.operands = [OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing];
1558 }
1559 0b1011 => {
1560 inst.opcode = Opcode::ADD(size);
1561 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1562 inst.operands[1] = OperandSpec::SP;
1563 inst.operands[2] = OperandSpec::Nothing;
1564 inst.imm_wide = read_imm(words, size.as_bytes())?;
1565 inst.length += size.as_bytes();
1566 }
1567 _ => { unreachable!("this should be an invalid bit pattern"); }
1568 }
1569 } else {
1570 inst.opcode = [
1571 Opcode::DADD, Opcode::DSUB,
1572 Opcode::DADC, Opcode::DSBB,
1573 ][(code & 0b11) as usize];
1574 if code < 0b1000 {
1575 inst.operands[0] = OperandSpec::R0H;
1577 inst.operands[1] = OperandSpec::R0L;
1578 } else {
1579 inst.operands[0] = OperandSpec::Imm8;
1581 inst.operands[1] = OperandSpec::R0L;
1582 assert_eq!(size, Size::B);
1583 inst.imm_wide = read_imm(words, size.as_bytes())?;
1584 inst.length += size.as_bytes();
1585 }
1586 }
1587 }
1588 0b1111 => {
1589 match byte & 0b1111 {
1590 0b0000 => {
1591 inst.opcode = Opcode::LDCTX;
1592 inst.operands[0] = OperandSpec::Abs16;
1593 inst.dispabs = read_imm(words, 2)? as u16;
1594 inst.length += 2;
1595 inst.operands[1] = OperandSpec::Abs20;
1596 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1597 inst.length += 3;
1598 }
1599 0b0001 => {
1600 inst.opcode = Opcode::RMPA(size);
1601 inst.operands[0] = OperandSpec::Nothing;
1602 inst.operands[1] = OperandSpec::Nothing;
1603 }
1604 0b0010 => {
1605 inst.opcode = Opcode::ENTER;
1606 inst.operands[0] = OperandSpec::Imm8;
1607 inst.imm_wide = read_imm(words, 1)?;
1608 inst.length += 1;
1609 inst.operands[1] = OperandSpec::Nothing;
1610 }
1611 0b0011 => {
1612 inst.opcode = Opcode::EXTS;
1613 inst.operands[0] = OperandSpec::R0;
1614 inst.operands[1] = OperandSpec::Nothing;
1615 }
1616 _ => {
1617 return Err(StandardDecodeError::InvalidOpcode);
1618 }
1619 }
1620 }
1621 _ => {
1622 return Err(StandardDecodeError::InvalidOpcode);
1623 }
1624 }
1625
1626 Ok(())
1627}
1628
1629fn decode_op7D<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1630 let byte = words.next()?;
1631 inst.length += 1;
1632 match byte >> 4 {
1633 op @ 0b0000 |
1634 op @ 0b0001 |
1635 op @ 0b0010 |
1636 op @ 0b0011 => {
1637 inst.opcode = [
1638 Opcode::JMPI, Opcode::JSRI,
1639 Opcode::JMPI, Opcode::JSRI,
1640 ][op as usize];
1641 inst.operands[0] = Operand_RegDerefDisp20Abs(byte & 0b1111, inst, words)?;
1642 inst.operands[1] = OperandSpec::Nothing;
1643 }
1644 0b0100 => {
1645 inst.opcode = Opcode::MULU(size);
1646 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1647 inst.operands[1] = Operand_RegDerefDispAbs(byte >> 4, size, inst, words)?;
1648 let dest_code = byte & 0b1111;
1649 match (size, dest_code) {
1650 (Size::B, 0b0001) |
1651 (Size::W, 0b0010) |
1652 (_, 0b0011) |
1653 (_, 0b0101) => {
1654 return Err(StandardDecodeError::InvalidOperand);
1655 }
1656 _ => {}
1657 }
1658 inst.imm_wide = read_imm(words, size.as_bytes())?;
1660 inst.length += size.as_bytes();
1661 },
1662 0b0101 => {
1663 inst.opcode = Opcode::MUL;
1664 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1665 inst.operands[1] = Operand_RegDerefDispAbs(byte >> 4, size, inst, words)?;
1666 let dest_code = byte & 0b1111;
1667 match (size, dest_code) {
1668 (Size::B, 0b0001) |
1669 (Size::W, 0b0010) |
1670 (_, 0b0011) |
1671 (_, 0b0101) => {
1672 return Err(StandardDecodeError::InvalidOperand);
1673 }
1674 _ => {}
1675 }
1676 inst.imm_wide = read_imm(words, size.as_bytes())?;
1678 inst.length += size.as_bytes();
1679 }
1680 0b1001 => {
1681 if byte < 0b1001_1000 {
1683 return Err(StandardDecodeError::InvalidOperand);
1684 }
1685 inst.opcode = Opcode::PUSHA;
1688 inst.operands[0] = Operand_RegDerefDispAbs(byte & 0b1111, size, inst, words)?;
1690 inst.operands[1] = OperandSpec::Nothing;
1691 }
1692 0b1010 => {
1693 if byte >= 0b1010_1000 {
1694 return Err(StandardDecodeError::InvalidOperand);
1695 }
1696 inst.opcode = Opcode::LDIPL;
1697 inst.operands[0] = OperandSpec::Imm8;
1698 inst.operands[1] = OperandSpec::Nothing;
1699 inst.imm_wide = ((((byte & 0b111) as i8) << 5) >> 5) as i32 as u32;
1700 }
1701 0b1011 => {
1702 inst.opcode = Opcode::ADD(size);
1704 inst.operands[0] = OperandSpec::Imm8;
1705 inst.operands[1] = OperandSpec::SP;
1706 inst.imm_wide = ((((byte & 0b111) as i8) << 4) >> 4) as i32 as u32;
1707 }
1708 0b1100 => {
1709 inst.opcode = match byte & 0b1111 {
1710 0b1000 => Opcode::JLE,
1711 0b1001 => Opcode::JO,
1712 0b1010 => Opcode::JGE,
1713 0b1100 => Opcode::JGT,
1714 0b1101 => Opcode::JNO,
1715 0b1110 => Opcode::JLT,
1716 _ => {
1717 return Err(StandardDecodeError::InvalidOpcode);
1718 }
1719 };
1720 inst.operands[0] = OperandSpec::Disp8;
1721 inst.operands[1] = OperandSpec::Nothing;
1722 inst.imm_wide = read_imm(words, 1)?;
1723 inst.length += 1;
1724 }
1725 0b1101 => {
1726 let code = byte & 0b1111;
1727 if code == 0b1011 || code == 0b1111 {
1728 return Err(StandardDecodeError::InvalidOpcode);
1729 }
1730 inst.opcode = [
1732 Opcode::BMGEU, Opcode::BMGTU, Opcode::BMEQ, Opcode::BMN,
1733 Opcode::BMLTU, Opcode::BMLEU, Opcode::BMNE, Opcode::BMPZ,
1734 Opcode::BMLE, Opcode::BMO, Opcode::GE, Opcode::NOP,
1735 Opcode::BMGT, Opcode::NO, Opcode::LT, Opcode::NOP,
1736 ][code as usize];
1737 inst.operands[0] = OperandSpec::Nothing;
1738 inst.operands[1] = OperandSpec::Nothing;
1739 }
1740 0b1110 => {
1741 let code = byte & 0b1111;
1742 if code & 0b111 < 0b100 {
1743 match code {
1744 op @ 0b0000 |
1745 op @ 0b0001 |
1746 op @ 0b0010 |
1747 op @ 0b0011 => {
1748 inst.opcode = [
1749 Opcode::DIVU(size), Opcode::DIV(size),
1750 Opcode::PUSH(size), Opcode::DIVX(size),
1751 ][op as usize];
1752 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1753 inst.operands[1] = OperandSpec::Nothing;
1754 inst.operands[2] = OperandSpec::Nothing;
1755 inst.imm_wide = read_imm(words, size.as_bytes())?;
1756 inst.length += size.as_bytes();
1757 }
1758 op @ 0b1000 |
1759 op @ 0b1001 |
1760 op @ 0b1010 => {
1761 inst.opcode = [
1762 Opcode::SMOVF(size), Opcode::SMOVB(size),
1763 Opcode::SSTR(size),
1764 ][(op & 0b11) as usize];
1765 inst.operands = [OperandSpec::Nothing, OperandSpec::Nothing, OperandSpec::Nothing];
1766 }
1767 0b1011 => {
1768 inst.opcode = Opcode::ADD(size);
1769 inst.operands[0] = if size == Size::W { OperandSpec::Imm16 } else { OperandSpec::Imm8 };
1770 inst.operands[1] = OperandSpec::SP;
1771 inst.operands[2] = OperandSpec::Nothing;
1772 inst.imm_wide = read_imm(words, size.as_bytes())?;
1773 inst.length += size.as_bytes();
1774 }
1775 _ => { unreachable!("this should be an invalid bit pattern"); }
1776 }
1777 } else {
1778 inst.opcode = [
1779 Opcode::DADD, Opcode::DSUB,
1780 Opcode::DADC, Opcode::DSBB,
1781 ][(code & 0b11) as usize];
1782 if code < 0b1000 {
1783 inst.operands[0] = OperandSpec::R1;
1785 inst.operands[1] = OperandSpec::R0;
1786 } else {
1787 inst.operands[0] = OperandSpec::Imm16;
1789 inst.operands[1] = OperandSpec::R0;
1790 assert_eq!(size, Size::W);
1791 inst.imm_wide = read_imm(words, size.as_bytes())?;
1792 inst.length += size.as_bytes();
1793 }
1794 }
1795 }
1796 0b1111 => {
1797 match byte & 0b1111 {
1799 0b0000 => {
1800 inst.opcode = Opcode::STCTX;
1801 inst.operands[0] = OperandSpec::Abs16;
1802 inst.dispabs = read_imm(words, 2)? as u16;
1803 inst.length += 2;
1804 inst.operands[1] = OperandSpec::Abs20;
1805 inst.imm_wide = read_imm(words, 3)? & 0x0f_ff_ff;
1806 inst.length += 3;
1807 }
1808 0b0001 => {
1809 inst.opcode = Opcode::RMPA(size);
1810 inst.operands[0] = OperandSpec::Nothing;
1811 inst.operands[1] = OperandSpec::Nothing;
1812 }
1813 0b0010 => {
1814 inst.opcode = Opcode::EXITD;
1815 inst.operands[0] = OperandSpec::Nothing;
1816 inst.operands[1] = OperandSpec::Nothing;
1817 }
1818 0b0011 => {
1819 inst.opcode = Opcode::WAIT;
1820 inst.operands[0] = OperandSpec::Nothing;
1821 inst.operands[1] = OperandSpec::Nothing;
1822 }
1823 _ => {
1824 return Err(StandardDecodeError::InvalidOpcode);
1825 }
1826 }
1827 }
1828 _ => {
1829 return Err(StandardDecodeError::InvalidOpcode);
1830 }
1831 }
1832
1833 Ok(())
1834}
1835
1836fn decode_op7E<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, _size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1837 let byte = words.next()?;
1838 inst.length += 1;
1839 let op = byte >> 4;
1840 let code = byte & 0b1111;
1841 if op > 0b1101 {
1842 return Err(StandardDecodeError::InvalidOpcode);
1843 }
1844 if op == 0b0010 {
1845 inst.operands[0] = Operand_BitRegDerefDispAbs(code, inst, words)?;
1847 inst.operands[1] = OperandSpec::Nothing;
1848 let cnd = read_imm(words, 1)? as u8;
1849 inst.length += 1;
1850 inst.opcode = match cnd {
1851 0b0000_0000 => Opcode::BMGEU,
1852 0b0000_0001 => Opcode::BMGTU,
1853 0b0000_0010 => Opcode::BMEQ,
1854 0b0000_0011 => Opcode::BMN,
1855 0b0000_0100 => Opcode::BMLE,
1856 0b0000_0101 => Opcode::BMO,
1857 0b0000_0110 => Opcode::BMGE,
1858 0b1111_1000 => Opcode::BMLTU,
1859 0b1111_1001 => Opcode::BMLEU,
1860 0b1111_1010 => Opcode::BMNE,
1861 0b1111_1011 => Opcode::BMPZ,
1862 0b1111_1100 => Opcode::BMGT,
1863 0b1111_1101 => Opcode::BMNO,
1864 0b1111_1110 => Opcode::BMLT,
1865 _ => {
1866 return Err(StandardDecodeError::InvalidOpcode);
1867 }
1868 };
1869 } else {
1870 inst.opcode = [
1871 Opcode::BTSTC, Opcode::BTSTS, Opcode::NOP, Opcode::BNTST, Opcode::BAND, Opcode::BNAND,
1873 Opcode::BOR, Opcode::BNOR, Opcode::BCLR,
1874 Opcode::BSET, Opcode::BNOT, Opcode::BTST,
1875 Opcode::BXOR, Opcode::BNXOR,
1876 ][op as usize];
1877 inst.operands[0] = Operand_BitRegDerefDispAbs(code, inst, words)?;
1878 inst.operands[1] = OperandSpec::Nothing;
1879 }
1880
1881 Ok(())
1882}
1883
1884fn decode_opEB<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(inst: &mut Instruction, _size: Size, words: &mut T) -> Result<(), <M16C as Arch>::DecodeError> {
1885 let byte = words.next()?;
1886 inst.length += 1;
1887 let upper = byte >> 4;
1888 let lower = byte & 0b1111;
1889 if upper < 0b1000 {
1890 match lower {
1892 0b0000 => {
1893 inst.opcode = Opcode::LDC;
1895 inst.operands[0] = OperandSpec::Imm16;
1896 inst.operands[1] = Operand_IntFlgSpSbFb((byte >> 4) & 0b111)?;
1897 inst.imm_wide = read_imm(words, 2)?;
1898 inst.length += 2;
1899 }
1900 0b0001 => {
1901 inst.opcode = if upper & 2 == 0 { Opcode::SHL(Size::L) } else { Opcode::SHA(Size::L) };
1903 inst.operands[0] = OperandSpec::R1H;
1904 inst.operands[1] = if upper & 1 == 0 { OperandSpec::R2R0 } else { OperandSpec::R3R1 };
1905 }
1906 0b0010 => {
1907 inst.opcode = Opcode::PUSHC;
1909 inst.operands[0] = Operand_IntFlgSpSbFb((byte >> 4) & 0b111)?;
1910 inst.operands[1] = OperandSpec::Nothing;
1911 },
1912 0b0011 => {
1913 inst.opcode = Opcode::POPC;
1915 inst.operands[0] = Operand_IntFlgSpSbFb((byte >> 4) & 0b111)?;
1916 inst.operands[1] = OperandSpec::Nothing;
1917 }
1918 0b0100 => {
1919 }
1921 0b0101 => {
1922 }
1924 _ => {
1925 inst.opcode = Opcode::MOVA;
1927 let src = byte & 0b1111;
1928 if src < 0b1000 {
1929 return Err(StandardDecodeError::InvalidOperand);
1930 }
1931 inst.operands[0] = Operand_RegDerefDispAbs(src, Size::W, inst, words)?;
1932 let dest = byte >> 4;
1933 if dest >= 0b1000 {
1934 return Err(StandardDecodeError::InvalidOperand);
1935 }
1936 inst.operands[1] = Operand_RegDerefDispAbs(dest, Size::W, inst, words)?;
1937 }
1938 }
1939 } else {
1940 if upper >= 0b1100 {
1942 inst.opcode = Opcode::INT;
1943 inst.operands[0] = OperandSpec::Imm8;
1944 inst.operands[1] = OperandSpec::Nothing;
1945 inst.imm_wide = (byte & 0b0011_1111) as u32;
1946 } else {
1947 inst.opcode = if upper & 2 == 0 { Opcode::SHL(Size::L) } else { Opcode::SHA(Size::L) };
1948 inst.operands[0] = OperandSpec::Imm4;
1949 inst.imm_wide = lower as u32;
1950 inst.operands[1] = if upper & 1 == 0 { OperandSpec::R2R0 } else { OperandSpec::R3R1 };
1951 }
1952 }
1953
1954 Ok(())
1955}
1956
1957fn read_imm<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(words: &mut T, mut size: u8) -> Result<u32, <M16C as Arch>::DecodeError> {
1958 let mut imm: u32 = 0;
1959 let mut offset = 0;
1960
1961 while size > 0 {
1962 imm |= (words.next()? as u32) << (8 * offset);
1963 offset += 1;
1964 size -= 1;
1965 }
1966
1967 Ok(imm)
1968}
1969
1970
1971fn Operand_BitRegDerefDispAbs<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(code: u8, inst: &mut Instruction, words: &mut T) -> Result<OperandSpec, <M16C as Arch>::DecodeError> {
1972 use OperandSpec::*;
1973 let (imm_size, spec) = match code {
1976 0b0000 => (1, Bit_R0),
1977 0b0001 => (1, Bit_R1),
1978 0b0010 => (1, Bit_R2),
1979 0b0011 => (1, Bit_R3),
1980 0b0100 => (1, Bit_A0),
1981 0b0101 => (1, Bit_A1),
1982 0b0110 => (0, Bit_Deref_A0),
1983 0b0111 => (0, Bit_Deref_A1),
1984 0b1000 => (1, Bit_Disp8_A0),
1985 0b1001 => (1, Bit_Disp8_A1),
1986 0b1010 => (1, Bit_Disp8_SB),
1987 0b1011 => (1, Bit_Disp8_FB),
1988 0b1100 => (2, Bit_Disp16_A0),
1989 0b1101 => (2, Bit_Disp16_A1),
1990 0b1110 => (2, Bit_Disp16_SB),
1991 0b1111 => (2, Bit_Abs16),
1992 _ => { unreachable!("invalid code provided, >0b1111"); }
1993 };
1994
1995 if imm_size > 0 {
1996 inst.dispabs = words.next()? as u16;
1997 inst.length += 1;
1998
1999 if imm_size == 2 {
2000 inst.dispabs |= (words.next()? as u16) << 8;
2001 inst.length += 1;
2002 }
2003 }
2004
2005 Ok(spec)
2006
2007}
2008
2009fn Operand_RegDerefDispAbs<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(code: u8, size: Size, inst: &mut Instruction, words: &mut T) -> Result<OperandSpec, <M16C as Arch>::DecodeError> {
2010 use OperandSpec::*;
2011 let (imm_size, spec) = match code {
2012 0b0000 => (0, { if size == Size::B { R0L } else { R0 } }),
2013 0b0001 => (0, { if size == Size::B { R0H } else { R1 } }),
2014 0b0010 => (0, { if size == Size::B { R1L } else { R2 } }),
2015 0b0011 => (0, { if size == Size::B { R1H } else { R3 } }),
2016 0b0100 => (0, A0),
2017 0b0101 => (0, A1),
2018 0b0110 => (0, Deref_A0),
2019 0b0111 => (0, Deref_A1),
2020 0b1000 => (1, Disp8_A0),
2021 0b1001 => (1, Disp8_A1),
2022 0b1010 => (1, Disp8_SB),
2023 0b1011 => (1, Disp8_FB),
2024 0b1100 => (2, Disp16_A0),
2025 0b1101 => (2, Disp16_A1),
2026 0b1110 => (2, Disp16_SB),
2027 0b1111 => (2, Abs16),
2028 _ => { unreachable!("invalid code provided, >0b1111"); }
2029 };
2030
2031 if imm_size > 0 {
2032 inst.dispabs = words.next()? as u16;
2033 inst.length += 1;
2034
2035 if imm_size == 2 {
2036 inst.dispabs |= (words.next()? as u16) << 8;
2037 inst.length += 1;
2038 }
2039 }
2040
2041 Ok(spec)
2042}
2043
2044fn Operand_second_RegDerefDispAbs<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(code: u8, size: Size, inst: &mut Instruction, words: &mut T) -> Result<OperandSpec, <M16C as Arch>::DecodeError> {
2045 use OperandSpec::*;
2046 let (imm_size, spec) = match code {
2047 0b0000 => (0, { if size == Size::B { R0L } else { R0 } }),
2048 0b0001 => (0, { if size == Size::B { R0H } else { R1 } }),
2049 0b0010 => (0, { if size == Size::B { R1L } else { R2 } }),
2050 0b0011 => (0, { if size == Size::B { R1H } else { R3 } }),
2051 0b0100 => (0, A0),
2052 0b0101 => (0, A1),
2053 0b0110 => (0, Deref_A0),
2054 0b0111 => (0, Deref_A1),
2055 0b1000 => (1, Disp2_8_A0),
2056 0b1001 => (1, Disp2_8_A1),
2057 0b1010 => (1, Disp2_8_SB),
2058 0b1011 => (1, Disp2_8_FB),
2059 0b1100 => (2, Disp2_16_A0),
2060 0b1101 => (2, Disp2_16_A1),
2061 0b1110 => (2, Disp2_16_SB),
2062 0b1111 => (2, Abs2_16),
2063 _ => { unreachable!("invalid code provided, >0b1111"); }
2064 };
2065
2066 if imm_size > 0 {
2067 inst.imm_wide = words.next()? as u32;
2068 inst.length += 1;
2069
2070 if imm_size == 2 {
2071 inst.imm_wide |= (words.next()? as u32) << 8;
2072 inst.length += 1;
2073 }
2074 }
2075
2076 Ok(spec)
2077}
2078
2079fn Operand_RegDerefDisp20Abs<T: Reader<<M16C as Arch>::Address, <M16C as Arch>::Word>>(code: u8, inst: &mut Instruction, words: &mut T) -> Result<OperandSpec, <M16C as Arch>::DecodeError> {
2080 use OperandSpec::*;
2081 let (imm_size, spec) = match code {
2082 0b0000 => (0, R2R0),
2083 0b0001 => (0, R3R1),
2084 0b0010 => { return Err(StandardDecodeError::InvalidOperand); },
2085 0b0011 => { return Err(StandardDecodeError::InvalidOperand); },
2086 0b0100 => (0, A1A0),
2087 0b0101 => { return Err(StandardDecodeError::InvalidOperand); },
2088 0b0110 => (0, Deref_A0),
2089 0b0111 => (0, Deref_A1),
2090 0b1000 => (1, Disp8_A0),
2091 0b1001 => (1, Disp8_A1),
2092 0b1010 => (1, Disp8_SB),
2093 0b1011 => (1, Disp8_FB),
2094 0b1100 => (3, Disp20_A0),
2095 0b1101 => (3, Disp20_A1),
2096 0b1110 => (2, Disp16_SB),
2097 0b1111 => (2, Abs16),
2098 _ => { unreachable!("invalid code provided, >0b1111"); }
2099 };
2100
2101 match imm_size {
2102 0 => {}
2103 1 => {
2104 inst.dispabs = words.next()? as u16;
2105 inst.length += 1;
2106 }
2107 2 => {
2108 inst.dispabs = words.next()? as u16;
2109 inst.dispabs |= (words.next()? as u16) << 8;
2110 inst.length += 2;
2111 }
2112 3 => {
2113 inst.imm_wide = words.next()? as u32;
2114 inst.imm_wide |= (words.next()? as u32) << 8;
2115 inst.imm_wide |= ((words.next()? & 0x0f) as u32) << 16;
2116 inst.length += 3;
2117 }
2118 _ => {
2119 unreachable!();
2120 }
2121 }
2122
2123 Ok(spec)
2124}
2125
2126fn Operand_IntFlgSpSbFb(code: u8) -> Result<OperandSpec, <M16C as Arch>::DecodeError> {
2127 use OperandSpec::*;
2128
2129 match code {
2130 0b001 => Ok(INTBL),
2131 0b010 => Ok(INTBH),
2132 0b011 => Ok(FLG),
2133 0b100 => Ok(ISP),
2134 0b101 => Ok(SP),
2135 0b110 => Ok(SB),
2136 0b111 => Ok(FB),
2137 _ => Err(StandardDecodeError::InvalidOperand)
2138 }
2139}