1use std::fmt;
2
3pub fn jxx_fix_offset(offset: u16) -> i16 {
4 if offset & 0b10_0000_0000 > 0 {
5 (offset | 0xfc00) as i16
6 } else {
7 offset as i16
8 }
9}
10
11pub trait Jxx {
14 fn mnemonic(&self) -> &str;
15 fn offset(&self) -> i16;
16 fn size(&self) -> usize;
17}
18
19macro_rules! jxx {
20 ($t:ident, $n:expr) => {
21 #[derive(Debug, Clone, Copy, PartialEq)]
22 pub struct $t {
23 offset: i16,
24 }
25
26 impl $t {
27 pub fn new(offset: i16) -> $t {
28 $t { offset }
29 }
30 }
31
32 impl Jxx for $t {
33 fn mnemonic(&self) -> &str {
34 $n
35 }
36
37 fn offset(&self) -> i16 {
38 self.offset
39 }
40
41 fn size(&self) -> usize {
42 2
43 }
44 }
45
46 impl fmt::Display for $t {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 if self.offset < 0 {
54 write!(f, "{} #-{:#x}", $n, -self.offset)
55 } else {
56 write!(f, "{} #{:#x}", $n, self.offset)
57 }
58 }
59 }
60 };
61}
62
63jxx!(Jnz, "jnz");
64jxx!(Jz, "jz");
65jxx!(Jlo, "jlo");
66jxx!(Jc, "jc");
67jxx!(Jn, "jn");
68jxx!(Jge, "jge");
69jxx!(Jl, "jl");
70jxx!(Jmp, "jmp");