dynasm\arch\x64/
x64data.rs1use std::collections::{HashMap, hash_map};
2
3use super::compiler::Opdata;
4use std::fmt::{self, Display};
5
6use lazy_static::lazy_static;
7use bitflags::bitflags;
8
9macro_rules! constify {
10 ($t:ty, $e:expr) => { {const C: &$t = &$e; C} }
11}
12
13macro_rules! OpInner {
14 ($fmt:expr, $ops:expr, $reg:expr) => { Opdata {args: $fmt, ops: constify!([u8], $ops), reg: $reg, flags: Flags::DEFAULT, features: Features::X64_IMPLICIT} };
15 ($fmt:expr, $ops:expr, $reg:expr, $f:expr) => { Opdata {args: $fmt, ops: constify!([u8], $ops), reg: $reg, flags: Flags::make($f), features: Features::X64_IMPLICIT} };
16 ($fmt:expr, $ops:expr, $reg:expr, $f:expr, $ft:expr) => { Opdata {args: $fmt, ops: constify!([u8], $ops), reg: $reg, flags: Flags::make($f), features: Features::make($ft)} };
17
18}
19
20macro_rules! Ops {
21 ( $( $name:tt = [ $( $( $e:expr ),+ ; )+ ] )* ) => {
22 [ $(
23 (
24 $name,
25 {
26 const OPDATA: &[Opdata] = &[$( OpInner!($( $e ),*) ,)+];
27 OPDATA
28 }
29 )
30 ),* ]
31 };
32}
33
34pub fn get_mnemnonic_data(name: &str) -> Option<&'static [Opdata]> {
35 OPMAP.get(&name).cloned()
36}
37
38bitflags! {
39 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
40 pub struct Flags: u32 {
41 const DEFAULT = 0x0000_0000; const VEX_OP = 0x0000_0001; const XOP_OP = 0x0000_0002; const IMM_OP = 0x0000_0004; const AUTO_SIZE = 0x0000_0008; const AUTO_NO32 = 0x0000_0010; const AUTO_REXW = 0x0000_0020; const AUTO_VEXL = 0x0000_0040; const WORD_SIZE = 0x0000_0080; const WITH_REXW = 0x0000_0100; const WITH_VEXL = 0x0000_0200; const EXACT_SIZE= 0x0000_0400; const PREF_66 = WORD_SIZE; const PREF_67 = 0x0000_0800; const PREF_F0 = 0x0000_1000; const PREF_F2 = 0x0000_2000; const PREF_F3 = 0x0000_4000; const LOCK = 0x0000_8000; const REP = 0x0001_0000; const REPE = 0x0002_0000;
65
66 const SHORT_ARG = 0x0004_0000; const ENC_MR = 0x0008_0000; const ENC_VM = 0x0010_0000; const ENC_MIB = 0x0020_0000; const X86_ONLY = 0x0040_0000; }
72}
73
74impl Flags {
75 const fn make(bits: u32) -> Flags {
76 Flags::from_bits_truncate(bits)
77 }
78}
79
80bitflags! {
81 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
82 pub struct Features: u32 {
83 const X64_IMPLICIT = 0x0000_0000;
84 const FPU = 0x0000_0001;
85 const MMX = 0x0000_0002;
86 const TDNOW = 0x0000_0004;
87 const SSE = 0x0000_0008;
88 const SSE2 = 0x0000_0010;
89 const SSE3 = 0x0000_0020;
90 const VMX = 0x0000_0040;
91 const SSSE3 = 0x0000_0080;
92 const SSE4A = 0x0000_0100;
93 const SSE41 = 0x0000_0200;
94 const SSE42 = 0x0000_0400;
95 const SSE5 = 0x0000_0800;
96 const AVX = 0x0000_1000;
97 const AVX2 = 0x0000_2000;
98 const FMA = 0x0000_4000;
99 const BMI1 = 0x0000_8000;
100 const BMI2 = 0x0001_0000;
101 const TBM = 0x0002_0000;
102 const RTM = 0x0004_0000;
103 const INVPCID = 0x0008_0000;
104 const MPX = 0x0010_0000;
105 const SHA = 0x0020_0000;
106 const PREFETCHWT1 = 0x0040_0000;
107 const CYRIX = 0x0080_0000;
108 const AMD = 0x0100_0000;
109 const DIRECTSTORES = 0x0200_0000;
110 }
111}
112
113impl Features {
114 const fn make(bits: u32) -> Features {
115 Features::from_bits_truncate(bits)
116 }
117
118 pub fn from_str(name: &str) -> Option<Features> {
119 match name {
120 "fpu" => Some(Features::FPU),
121 "mmx" => Some(Features::MMX),
122 "tdnow" => Some(Features::TDNOW),
123 "sse" => Some(Features::SSE),
124 "sse2" => Some(Features::SSE2),
125 "sse3" => Some(Features::SSE3),
126 "vmx" => Some(Features::VMX),
127 "ssse3" => Some(Features::SSSE3),
128 "sse4a" => Some(Features::SSE4A),
129 "sse41" => Some(Features::SSE41),
130 "sse42" => Some(Features::SSE42),
131 "sse5" => Some(Features::SSE5),
132 "avx" => Some(Features::AVX),
133 "avx2" => Some(Features::AVX2),
134 "fma" => Some(Features::FMA),
135 "bmi1" => Some(Features::BMI1),
136 "bmi2" => Some(Features::BMI2),
137 "tbm" => Some(Features::TBM),
138 "rtm" => Some(Features::RTM),
139 "invpcid" => Some(Features::INVPCID),
140 "mpx" => Some(Features::MPX),
141 "sha" => Some(Features::SHA),
142 "prefetchwt1" => Some(Features::PREFETCHWT1),
143 "cyrix" => Some(Features::CYRIX),
144 "amd" => Some(Features::AMD),
145 "directstores" => Some(Features::DIRECTSTORES),
146 _ => None
147 }
148 }
149}
150
151impl Display for Features {
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 let mut keys = Vec::new();
154 if self.contains(Features::FPU) { keys.push("fpu"); }
155 if self.contains(Features::MMX) { keys.push("mmx"); }
156 if self.contains(Features::TDNOW) { keys.push("tdnow"); }
157 if self.contains(Features::SSE) { keys.push("sse"); }
158 if self.contains(Features::SSE2) { keys.push("sse2"); }
159 if self.contains(Features::SSE3) { keys.push("sse3"); }
160 if self.contains(Features::VMX) { keys.push("vmx"); }
161 if self.contains(Features::SSSE3) { keys.push("ssse3"); }
162 if self.contains(Features::SSE4A) { keys.push("sse4a"); }
163 if self.contains(Features::SSE41) { keys.push("sse41"); }
164 if self.contains(Features::SSE42) { keys.push("sse42"); }
165 if self.contains(Features::SSE5) { keys.push("sse5"); }
166 if self.contains(Features::AVX) { keys.push("avx"); }
167 if self.contains(Features::AVX2) { keys.push("avx2"); }
168 if self.contains(Features::FMA) { keys.push("fma"); }
169 if self.contains(Features::BMI1) { keys.push("bmi1"); }
170 if self.contains(Features::BMI2) { keys.push("bmi2"); }
171 if self.contains(Features::TBM) { keys.push("tbm"); }
172 if self.contains(Features::RTM) { keys.push("rtm"); }
173 if self.contains(Features::INVPCID) { keys.push("invpcid"); }
174 if self.contains(Features::MPX) { keys.push("mpx"); }
175 if self.contains(Features::SHA) { keys.push("sha"); }
176 if self.contains(Features::PREFETCHWT1) { keys.push("prefetchwt1"); }
177 if self.contains(Features::CYRIX) { keys.push("cyrix"); }
178 if self.contains(Features::AMD) { keys.push("amd"); }
179 if self.contains(Features::DIRECTSTORES) { keys.push("directstores"); }
180 for (i, k) in keys.into_iter().enumerate() {
181 if i != 0 {
182 f.write_str(", ")?;
183 }
184 f.write_str(k)?;
185 }
186 Ok(())
187 }
188}
189
190#[allow(dead_code)]
191pub fn mnemnonics() -> hash_map::Keys<'static, &'static str, &'static [Opdata]> {
192 OPMAP.keys()
193}
194
195const DEFAULT : u32 = Flags::DEFAULT.bits();
197const VEX_OP : u32 = Flags::VEX_OP.bits();
198const XOP_OP : u32 = Flags::XOP_OP.bits();
199const IMM_OP : u32 = Flags::IMM_OP.bits();
200const SHORT_ARG : u32 = Flags::SHORT_ARG.bits();
201const AUTO_SIZE : u32 = Flags::AUTO_SIZE.bits();
202const AUTO_NO32 : u32 = Flags::AUTO_NO32.bits();
203const AUTO_REXW : u32 = Flags::AUTO_REXW.bits();
204const AUTO_VEXL : u32 = Flags::AUTO_VEXL.bits();
205const WORD_SIZE : u32 = Flags::WORD_SIZE.bits();
206const WITH_REXW : u32 = Flags::WITH_REXW.bits();
207const WITH_VEXL : u32 = Flags::WITH_VEXL.bits();
208const EXACT_SIZE : u32 = Flags::EXACT_SIZE.bits();
209const PREF_66 : u32 = Flags::PREF_66.bits();
210const PREF_67 : u32 = Flags::PREF_67.bits();
211const PREF_F0 : u32 = Flags::PREF_F0.bits();
212const PREF_F2 : u32 = Flags::PREF_F2.bits();
213const PREF_F3 : u32 = Flags::PREF_F3.bits();
214const LOCK : u32 = Flags::LOCK.bits();
215const REP : u32 = Flags::REP.bits();
216const REPE : u32 = Flags::REPE.bits();
217const ENC_MR : u32 = Flags::ENC_MR.bits();
218const ENC_VM : u32 = Flags::ENC_VM.bits();
219const ENC_MIB : u32 = Flags::ENC_MIB.bits();
220const X86_ONLY : u32 = Flags::X86_ONLY.bits();
221
222#[allow(dead_code)]
223const X64_IMPLICIT : u32 = Features::X64_IMPLICIT.bits();
224const FPU : u32 = Features::FPU.bits();
225const MMX : u32 = Features::MMX.bits();
226const TDNOW : u32 = Features::TDNOW.bits();
227const SSE : u32 = Features::SSE.bits();
228const SSE2 : u32 = Features::SSE2.bits();
229const SSE3 : u32 = Features::SSE3.bits();
230const VMX : u32 = Features::VMX.bits();
231const SSSE3 : u32 = Features::SSSE3.bits();
232const SSE4A : u32 = Features::SSE4A.bits();
233const SSE41 : u32 = Features::SSE41.bits();
234const SSE42 : u32 = Features::SSE42.bits();
235const SSE5 : u32 = Features::SSE5.bits();
236const AVX : u32 = Features::AVX.bits();
237const AVX2 : u32 = Features::AVX2.bits();
238const FMA : u32 = Features::FMA.bits();
239const BMI1 : u32 = Features::BMI1.bits();
240const BMI2 : u32 = Features::BMI2.bits();
241const TBM : u32 = Features::TBM.bits();
242const RTM : u32 = Features::RTM.bits();
243const INVPCID : u32 = Features::INVPCID.bits();
244const MPX : u32 = Features::MPX.bits();
245const SHA : u32 = Features::SHA.bits();
246const PREFETCHWT1 : u32 = Features::PREFETCHWT1.bits();
247const CYRIX : u32 = Features::CYRIX.bits();
248const AMD : u32 = Features::AMD.bits();
249const DIRECTSTORES : u32 = Features::DIRECTSTORES.bits();
250
251
252lazy_static! {
253 static ref OPMAP: HashMap<&'static str, &'static [Opdata]> = {
254 const X: u8 = 0xFF;
255 static MAP: &[(&str, &[Opdata])] = &include!("gen_opmap.rs");
256 MAP.iter().cloned().collect()
257 };
258}