1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::resources::{GeneralPurposeRegister, Operand};
use fmt::Formatter;
use std::fmt;
#[derive(Eq, Ord, PartialOrd, PartialEq, Clone, Copy)]
pub struct REXPrefix {
pub w_bit: bool,
pub r_bit: bool,
pub x_bit: bool,
pub b_bit: bool,
}
impl REXPrefix {
pub const BASE: u8 = 0x40;
pub const W_BIT: u8 = 0x08;
pub const R_BIT: u8 = 0x04;
pub const X_BIT: u8 = 0x02;
pub const B_BIT: u8 = 0x01;
pub fn new(w: bool, r: bool, x: bool, b: bool) -> Self {
Self {
w_bit: w,
r_bit: r,
x_bit: x,
b_bit: b,
}
}
pub fn new_from_mem(is_64bit: bool, rm: &Operand) -> Self{
Self{
w_bit: is_64bit,
r_bit: rm.is_expanded(),
x_bit: rm.req_sib_byte() && rm.index_reg_is_expanded(),
b_bit: false,
}
}
pub fn new_from_mem_and_reg(is_64bit: bool, reg: &GeneralPurposeRegister, rm: &Operand) -> Self {
Self {
w_bit: is_64bit,
r_bit: rm.is_expanded(),
x_bit: rm.req_sib_byte() && rm.index_reg_is_expanded(),
b_bit: reg.is_expanded(),
}
}
pub fn to_byte(&self) -> u8 {
let base = Self::BASE;
let f = |bit: bool, byte: u8| -> u8 {
if bit {
byte
} else {
0b0
}
};
base | f(self.w_bit, Self::W_BIT)
| f(self.r_bit, Self::W_BIT)
| f(self.x_bit, Self::X_BIT)
| f(self.b_bit, Self::B_BIT)
}
pub fn b_bit_from_reg(reg: &GeneralPurposeRegister) -> u8 {
if reg.is_expanded() {
Self::B_BIT
} else {
0b0
}
}
pub fn r_bit_from_reg(reg: &GeneralPurposeRegister) -> u8 {
if reg.is_expanded() {
Self::R_BIT
} else {
0b0
}
}
}
impl fmt::Display for REXPrefix {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "REX(0b{:b})", self.to_byte())
}
}
impl fmt::Debug for REXPrefix {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let func = |b: bool, c: char| -> char {
if b {
c
} else {
'-'
}
};
let w_bit = func(self.w_bit, 'W');
let r_bit = func(self.r_bit, 'R');
let x_bit = func(self.x_bit, 'X');
let b_bit = func(self.b_bit, 'B');
write!(f, "0100{}{}{}{}", w_bit, r_bit, x_bit, b_bit)
}
}