1use std::{
2 convert::TryFrom,
3 io::{ErrorKind, Read, Write},
4 ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
5};
6
7use crate::{
8 disasm::OpcodePrinter,
9 traits::{Address, InsnRead, InsnWrite, Reloc, RelocCode},
10};
11
12#[derive(Debug)]
13pub struct CleverExtensionFromStrError;
14
15impl core::fmt::Display for CleverExtensionFromStrError {
16 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
17 f.write_str("Unknown clever")
18 }
19}
20
21impl std::error::Error for CleverExtensionFromStrError {}
22
23macro_rules! define_clever_features{
24 {
25 $(($enum:ident, $feature:literal)),* $(,)?
26 } => {
27 #[derive(Copy,Clone,Debug,Hash,PartialEq,Eq)]
28 #[non_exhaustive]
29 #[repr(i32)]
30 pub enum CleverExtension{
31 $($enum,)*
32 }
33
34 impl CleverExtension{
35 pub fn extension_name(&self) -> &'static str{
36 match self{
37 $(#[allow(unreachable_patterns)] Self::$enum => $feature,)*
38 }
39 }
40 }
41
42 impl core::str::FromStr for CleverExtension{
43 type Err = CleverExtensionFromStrError;
44 fn from_str(x: &str) -> Result<Self,Self::Err>{
45 match x{
46
47 $(#[allow(unreachable_patterns)] $feature => Ok(Self::$enum),)*
48 _ => Err(CleverExtensionFromStrError)
49 }
50 }
51 }
52
53 impl core::fmt::Display for CleverExtension{
54 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result{
55 match self{
56 $(Self::$enum => f.write_str($feature),)*
57 }
58 }
59 }
60 }
61}
62
63define_clever_features! {
64 (Main, "main"),
65 (Float, "float"),
66 (FloatExt, "float-ext"),
67 (Vec, "vec"),
68 (Rand, "rand"),
69 (Virtualization, "virtualization"),
70}
71
72#[derive(Copy, Clone, Hash, PartialEq, Eq)]
73pub struct CleverRegister(pub u8);
74
75#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
76pub struct RegisterFromStrError;
77
78macro_rules! clever_registers{
79 {
80 $($name:ident $(| $altnames:ident)* => $val:expr),* $(,)?
81 } => {
82 #[allow(non_upper_case_globals)]
83 impl CleverRegister{
84 $(pub const $name: Self = Self($val); $(pub const $altnames: Self = Self($val);)*)*
85 }
86 impl ::core::str::FromStr for CleverRegister{
87 type Err = RegisterFromStrError;
88 fn from_str(st: &str) -> Result<Self,Self::Err>{
89 match st{
90 $(
91 ::core::stringify!($name) $(| ::core::stringify!($altnames))* => Ok(Self($val)),
92 )*
93 _ => Err(RegisterFromStrError)
94 }
95 }
96 }
97 impl ::core::fmt::Display for CleverRegister{
98 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result{
99 match self{
100 $(CleverRegister($val) => f.write_str(::core::stringify!($name)),)*
101 CleverRegister(val) => f.write_fmt(::core::format_args!("r{}",val))
102 }
103 }
104 }
105
106 impl ::core::fmt::Debug for CleverRegister{
107 fn fmt(&self, f: &mut core::fmt::Formatter) -> ::core::fmt::Result{
108 struct DontEscape(&'static str);
109 impl ::core::fmt::Debug for DontEscape{
110 fn fmt(&self, f: &mut core::fmt::Formatter) -> ::core::fmt::Result{
111 f.write_str(self.0)
112 }
113 }
114
115 match self{
116 $(CleverRegister($val) => {
117 f.debug_tuple("CleverRegister")
118 .field(&DontEscape(::core::stringify!($name))).finish()
119 })*
120 CleverRegister(val) => f.debug_tuple("CleverRegister").field(&val).finish()
121 }
122 }
123 }
124 }
125}
126
127clever_registers! {
128 r0 | racc => 0,
129 r1 | rsrc => 1,
130 r2 | rdst => 2,
131 r3 | rcnt => 3,
132 r4 => 4,
133 r5 => 5,
134 r6 | fbase => 6,
135 r7 | sptr => 7,
136 r8 => 8,
137 r9 => 9,
138 r10 => 10,
139 r11 => 11,
140 r12 => 12,
141 r13 => 13,
142 r14 => 14,
143 r15 | link => 15,
144 ip => 16,
145 flags => 17,
146 mode => 18,
147 fpcw => 19,
148 f0 => 24,
149 f1 => 25,
150 f2 => 26,
151 f3 => 27,
152 f4 => 28,
153 f5 => 29,
154 f6 => 30,
155 f7 => 31,
156 v0l => 64,
157 v0h => 65,
158 v1l => 66,
159 v1h => 67,
160 v2l => 68,
161 v2h => 69,
162 v3l => 70,
163 v3h => 71,
164 v4l => 72,
165 v4h => 73,
166 v5l => 74,
167 v5h => 75,
168 v6l => 76,
169 v6h => 77,
170 v7l => 78,
171 v7h => 79,
172 v8l => 80,
173 v8h => 81,
174 v9l => 82,
175 v9h => 83,
176 v10l => 84,
177 v10h => 85,
178 v11l => 86,
179 v11h => 87,
180 v12l => 88,
181 v12h => 89,
182 v13l => 90,
183 v13h => 91,
184 v14l => 92,
185 v14h => 93,
186 v15l => 94,
187 v15h => 95,
188 cr0 => 128,
189 page | cr1 => 129,
190 flprotected | cr2 => 130,
191 scdp | cr3 => 131,
192 scsp | cr4 => 132,
193 sccr | cr5 => 133,
194 itabp | cr6 => 134,
195 ciread | cr7 => 135,
196 cpuidlo => 136,
197 cpuidhi => 137,
198 cpuex2 => 138,
199 cpuex3 => 139,
200 cpuex4 => 140,
201 cpuex5 => 141,
202 cpuex6 => 142,
203 mscpuex => 143,
204 fcode | cr8 => 144,
205 pfchar | cr9 => 145,
206 msr0 => 148,
207 msr1 => 149,
208 msr2 => 150,
209 msr3 => 151,
210 msr4 => 152,
211 msr5 => 153,
212 msr6 => 154,
213 rdinfo => 156
214}
215
216macro_rules! register_extensions{
217 ($($reg:ident: $ext:expr),* $(,)?) => {
218 impl CleverRegister{
219 pub fn extension(self) -> Option<CleverExtension>{
220 match self{
221 $(Self:: $reg => Some($ext),)*
222 #[allow(unreachable_patterns)] _ => None
223 }
224 }
225 }
226
227 }
228}
229
230use CleverExtension::Vec as Vector;
231
232register_extensions!(
233 r0: Main,
234 r1: Main,
235 r2: Main,
236 r3: Main,
237 r4: Main,
238 r5: Main,
239 r6: Main,
240 r7: Main,
241 r8: Main,
242 r9: Main,
243 r10: Main,
244 r11: Main,
245 r12: Main,
246 r13: Main,
247 r14: Main,
248 r15: Main,
249 ip: Main,
250 flags: Main,
251 mode: Main,
252 fpcw: Float,
253 f0: Float,
254 f1: Float,
255 f2: Float,
256 f3: Float,
257 f4: Float,
258 f5: Float,
259 f6: Float,
260 f7: Float,
261 v0l: Vector,
262 v0h: Vector,
263 v1l: Vector,
264 v1h: Vector,
265 v2l: Vector,
266 v2h: Vector,
267 v3l: Vector,
268 v3h: Vector,
269 v4l: Vector,
270 v4h: Vector,
271 v5l: Vector,
272 v5h: Vector,
273 v6l: Vector,
274 v6h: Vector,
275 v7l: Vector,
276 v7h: Vector,
277 v8l: Vector,
278 v8h: Vector,
279 v9l: Vector,
280 v9h: Vector,
281 v10l: Vector,
282 v10h: Vector,
283 v11l: Vector,
284 v11h: Vector,
285 v12l: Vector,
286 v12h: Vector,
287 v13l: Vector,
288 v13h: Vector,
289 v14l: Vector,
290 v14h: Vector,
291 v15l: Vector,
292 v15h: Vector,
293 cr0: Main,
294 cr1: Main,
295 cr2: Main,
296 cr3: Main,
297 cr4: Main,
298 cr5: Main,
299 cr6: Main,
300 cr7: Main,
301 cpuidlo: Main,
302 cpuidhi: Main,
303 cpuex2: Main,
304 cpuex3: Main,
305 cpuex4: Main,
306 cpuex5: Main,
307 cpuex6: Main,
308 mscpuex: Main,
309 cr8: Main,
310 cr9: Main,
311 msr0: Main,
312 msr1: Main,
313 msr2: Main,
314 msr3: Main,
315 msr4: Main,
316 msr5: Main,
317 msr6: Main,
318 rdinfo: Rand,
319);
320
321#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
322#[repr(u8)]
323pub enum ConditionCode {
324 Parity,
325 Carry,
326 Overflow,
327 Zero,
328 LessThan,
329 LessEq,
330 BelowEq,
331 Minus,
332 Plus,
333 Above,
334 Greater,
335 GreaterEq,
336 NotZero,
337 NoOverflow,
338 NoCarry,
339 NoParity,
340}
341
342#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
343pub enum CleverIndex {
344 Register(CleverRegister),
345 Abs(i16),
346}
347
348impl core::fmt::Display for CleverIndex {
349 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
350 match self {
351 Self::Register(r) => r.fmt(f),
352 Self::Abs(n) => n.fmt(f),
353 }
354 }
355}
356
357trait HBits {
358 fn from_bits(bits: u16) -> Self;
359 fn to_hbits(self) -> u16;
360}
361
362impl HBits for bool {
363 fn from_bits(bits: u16) -> Self {
364 bits != 0
365 }
366
367 fn to_hbits(self) -> u16 {
368 self as u16
369 }
370}
371
372impl HBits for u8 {
373 fn from_bits(bits: u16) -> Self {
374 bits as u8
375 }
376 fn to_hbits(self) -> u16 {
377 self as u16
378 }
379}
380
381impl HBits for i8 {
382 fn from_bits(bits: u16) -> Self {
383 (bits as i8) | ((bits & 0x8).wrapping_neg() as i8)
384 }
385 fn to_hbits(self) -> u16 {
386 (self & 0xf) as u16
387 }
388}
389
390impl HBits for u16 {
392 fn from_bits(bits: u16) -> Self {
393 bits
394 }
395 fn to_hbits(self) -> u16 {
396 self
397 }
398}
399
400impl HBits for CleverRegister {
401 fn from_bits(bits: u16) -> Self {
402 Self(bits as u8)
403 }
404
405 fn to_hbits(self) -> u16 {
406 self.0 as u16
407 }
408}
409
410impl HBits for ConditionCode {
411 fn from_bits(bits: u16) -> Self {
412 match bits {
413 0 => ConditionCode::Parity,
414 1 => ConditionCode::Carry,
415 2 => ConditionCode::Overflow,
416 3 => ConditionCode::Zero,
417 4 => ConditionCode::LessThan,
418 5 => ConditionCode::LessEq,
419 6 => ConditionCode::BelowEq,
420 7 => ConditionCode::Minus,
421 8 => ConditionCode::Plus,
422 9 => ConditionCode::Above,
423 10 => ConditionCode::Greater,
424 11 => ConditionCode::GreaterEq,
425 12 => ConditionCode::NotZero,
426 13 => ConditionCode::NoOverflow,
427 14 => ConditionCode::NoCarry,
428 15 => ConditionCode::NoParity,
429 _ => unreachable!(),
430 }
431 }
432
433 fn to_hbits(self) -> u16 {
434 self as u8 as u16
435 }
436}
437
438trait HBitRange<T> {
439 fn shift(&self) -> u32;
440 fn mask(&self) -> u16;
441}
442
443impl HBitRange<u32> for u32 {
444 fn shift(&self) -> u32 {
445 *self
446 }
447
448 fn mask(&self) -> u16 {
449 1u16 << (*self)
450 }
451}
452
453impl HBitRange<u32> for Range<u32> {
454 fn shift(&self) -> u32 {
455 self.start
456 }
457
458 fn mask(&self) -> u16 {
459 ((1u16 << (self.end - self.start)) - 1) << self.start
460 }
461}
462
463impl HBitRange<u32> for RangeInclusive<u32> {
464 fn shift(&self) -> u32 {
465 *self.start()
466 }
467
468 fn mask(&self) -> u16 {
469 ((1u16 << (self.end() - self.start())) - 1) << self.start()
470 }
471}
472
473impl HBitRange<u32> for RangeFrom<u32> {
474 fn shift(&self) -> u32 {
475 self.start
476 }
477
478 fn mask(&self) -> u16 {
479 ((1u16 << (4 - self.start)) - 1) << self.start
480 }
481}
482
483impl HBitRange<u32> for RangeTo<u32> {
484 fn shift(&self) -> u32 {
485 0
486 }
487
488 fn mask(&self) -> u16 {
489 (1u16 << (self.end - 1)) - 1
490 }
491}
492
493impl HBitRange<u32> for RangeToInclusive<u32> {
494 fn shift(&self) -> u32 {
495 0
496 }
497
498 fn mask(&self) -> u16 {
499 (1u16 << self.end) - 1
500 }
501}
502
503impl HBitRange<u32> for RangeFull {
504 fn shift(&self) -> u32 {
505 0
506 }
507
508 fn mask(&self) -> u16 {
509 0xf
510 }
511}
512
513#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
514pub enum CleverOperandKind {
515 Normal(u32),
516 AbsAddr,
517 RelAddr,
518 Size,
519 HRegister,
520 HImmediate,
521 Insn,
523}
524
525macro_rules! clever_instructions{
526 {
527 $([$enum:ident, $insn:literal, $opcode:literal, $operands:expr, $ext:expr $(, { $($hfield:ident @ $range:expr => $ty:ty ),* $(,)?})? ]),* $(,)?
528 } => {
529
530 #[derive(Copy,Clone,Debug,Hash,PartialEq, Eq)]
531 #[non_exhaustive]
532 pub enum CleverOpcode{
533 $($enum $({$($hfield: $ty),*})?),*
534 }
535
536 impl CleverOpcode{
537
538 pub fn from_opcode(opc: u16) -> Option<CleverOpcode>{
539 match opc>>4{
540 $(#[allow(unreachable_patterns)] $opcode => {
541 #[allow(unused_mut)]
542 let mut hmask = 0;
543
544 $(#[allow(unused_parens, clippy::eval_order_dependence, clippy::mixed_read_write_in_expression)] let ($($hfield),*) = (
545 $({
546 fn range() -> impl HBitRange<u32>{
547 $range
548 }
549 let range = range();
550 hmask |= HBitRange::mask(&range)<<HBitRange::shift(&range);
551 HBits::from_bits((opc&HBitRange::mask(&range))>>HBitRange::shift(&range))
552 }),*
553 );)?
554 if ((opc&0xf)&!hmask)!=0{
555 return None
556 }
557 Some(Self:: $enum $({$($hfield),*})?)
558 },)*
559 _ => None
560 }
561 }
562
563 pub fn extension(&self) -> CleverExtension{
564 match self{
565 $(Self:: $enum {..} => $ext,)*
566 }
567 }
568
569 pub fn name(&self) -> &'static str{
570 match self{
571 $(Self:: $enum {..} => $insn,)*
572 }
573 }
574
575 pub fn opcode(&self) -> u16{
576 match self{
577 $(Self:: $enum $({$($hfield),*})? => {
578 let base: u16 = $opcode;
579 #[allow(unused_mut)] let mut opc = base<<4;
581 $($({
582 let range = $range;
583
584 let bits = (HBits::to_hbits(*$hfield)<< HBitRange::shift(&range))&HBitRange::mask(&range);
585 opc |= bits;
586 })*)?
587 opc
588 })*
589 }
590 }
591
592 pub fn operands(&self) -> CleverOperandKind{
593 match self{
594 $(Self:: $enum {..} => $operands,)*
595 }
596 }
597 }
598 }
599}
600
601use CleverExtension::{Float, FloatExt, Main, Rand, Virtualization};
602
603clever_instructions! {
604 [Und0, "und", 0x000, CleverOperandKind::Normal(0), Main],
606
607 [Add, "add", 0x001, CleverOperandKind::Normal(2), Main, {lock @ 3 => bool, flags @ 0 => bool}],
609 [Sub, "sub", 0x002, CleverOperandKind::Normal(2), Main, {lock @ 3 => bool, flags @ 0 => bool}],
610 [And, "and", 0x003, CleverOperandKind::Normal(2), Main, {lock @ 3 => bool, flags @ 0 => bool}],
611 [Or , "or" , 0x004, CleverOperandKind::Normal(2), Main, {lock @ 3 => bool, flags @ 0 => bool}],
612 [Xor, "xor", 0x005, CleverOperandKind::Normal(2), Main, {lock @ 3 => bool, flags @ 0 => bool}],
613
614 [Mul, "mul", 0x006, CleverOperandKind::Normal(0), Main, {ss @ 2..4 => u16, flags @ 0 => bool}],
616 [Div, "div", 0x007, CleverOperandKind::Normal(0), Main, {ss @ 2..4 => u16, wide @ 1 => bool, flags @ 0 => bool}],
617
618 [Mov, "mov", 0x008, CleverOperandKind::Normal(2), Main],
620 [Lea, "lea", 0x009, CleverOperandKind::Normal(2), Main],
621 [MovRD, "mov", 0x00A, CleverOperandKind::Normal(1), Main, {r @ .. => CleverRegister}],
622 [MovRS, "mov", 0x00B, CleverOperandKind::Normal(1), Main, {r @ .. => CleverRegister}],
623 [LeaRD, "lea", 0x00C, CleverOperandKind::Normal(1), Main, {r @ .. => CleverRegister}],
624
625 [Nop10, "nop", 0x010, CleverOperandKind::Normal(0), Main, {any @ .. => u16}],
627 [Nop11, "nop", 0x011, CleverOperandKind::Normal(1), Main, {any @ .. => u16}],
628 [Nop12, "nop", 0x012, CleverOperandKind::Normal(2), Main, {any @ .. => u16}],
629 [Nop13, "nop", 0x013, CleverOperandKind::Normal(3), Main, {any @ .. => u16}],
630
631 [Push, "push", 0x014, CleverOperandKind::Normal(1), Main],
633 [Pop , "pop" , 0x015, CleverOperandKind::Normal(1), Main],
634 [PushR, "push", 0x016, CleverOperandKind::Normal(0), Main, {r @ .. => CleverRegister}],
635 [PopR , "pop" , 0x017, CleverOperandKind::Normal(0), Main, {r @ .. => CleverRegister}],
636
637 [Stogpr , "stogpr" , 0x018, CleverOperandKind::Normal(1), Main],
639 [Stoar , "stoar" , 0x019, CleverOperandKind::Normal(1), Main],
640 [Rstogpr, "rstogpr", 0x01A, CleverOperandKind::Normal(1), Main],
641 [Rstoar , "rstoar" , 0x01B, CleverOperandKind::Normal(1), Main],
642 [Pushgpr, "pushgpr", 0x01C, CleverOperandKind::Normal(0), Main],
643 [Pushar , "pushar" , 0x01D, CleverOperandKind::Normal(0), Main],
644 [Popgpr , "popgpr" , 0x01E, CleverOperandKind::Normal(0), Main],
645 [Popar , "popar" , 0x01F, CleverOperandKind::Normal(0), Main],
646
647 [Movsx, "movsx", 0x020, CleverOperandKind::Normal(2), Main, {flags @ 0 => bool}],
649 [Bswap, "bswap", 0x021, CleverOperandKind::Normal(2), Main, {flags @ 0 => bool}],
650 [Movsif, "movsif", 0x022, CleverOperandKind::Normal(2), Float, {flags @ 0 => bool}],
651 [Movxf, "movxf", 0x023, CleverOperandKind::Normal(2), Float, {ss @ 3..=4 => u16, int @ 2 => bool,flags @0 => bool}],
652 [Movfsi, "movfsi", 0x024, CleverOperandKind::Normal(2), Float, {flags @ 0 => bool}],
653 [Movfx, "movfx", 0x025, CleverOperandKind::Normal(2), Float, {ss @ 3..=4 => u16, int @ 2 => bool,flags @0 => bool}],
654 [Cvtf, "cvtf", 0x026, CleverOperandKind::Normal(2), Float, {flags @ 0 => bool}],
655
656
657 [Repbi, "repbi", 0x028, CleverOperandKind::Insn, Main, {cc @ 0..4 => ConditionCode}],
659 [Repbc, "repbc", 0x029, CleverOperandKind::Insn, Main],
660 [Bcpy, "bcpy", 0x02a, CleverOperandKind::Normal(0), Main, {ss @ 0..2 => u16}],
661 [Bsto, "bsto", 0x02b, CleverOperandKind::Normal(0), Main, {ss @ 0..2 => u16}],
662 [Bsca, "bsca", 0x02c, CleverOperandKind::Normal(0), Main, {ss @ 0..2 => u16}],
663 [Bcmp, "bcmp", 0x02d, CleverOperandKind::Normal(0), Main, {ss @ 0..2 => u16}],
664 [Btst, "btst", 0x02e, CleverOperandKind::Normal(0), Main, {ss @ 0..2 => u16}],
665
666 [Lsh, "lsh", 0x030, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
668 [Rsh, "rsh", 0x031, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
669 [Arsh, "arsh", 0x032, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
670 [Lshc, "lshc", 0x033, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
671 [Rshc, "rshc", 0x034, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
672 [Lrot, "lrot", 0x035, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
673 [Rrot, "rrot", 0x036, CleverOperandKind::Normal(2), Main, {l @ 3 => bool, f @ 0 => bool}],
674 [LshR, "lsh", 0x038, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
675 [RshR, "rsh", 0x039, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
676 [ArshR, "arsh", 0x03A, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
677 [LshcR, "lshc", 0x03B, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
678 [RshcR, "rshc", 0x03C, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
679 [LrotR, "lrot", 0x03D, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
680 [RrotR, "rrot", 0x03E, CleverOperandKind::Normal(2), Main, {r @ 0..4 => CleverRegister}],
681
682 [Imul, "imul", 0x040, CleverOperandKind::Normal(0), Main, {ss @ 2..4 => u16, flags @ 0 => bool}],
686 [AddRD, "add", 0x041, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
687 [SubRD, "sub", 0x042, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
688 [AndRD, "and", 0x043, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
689 [OrRD, "or", 0x044, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
690 [XorRD, "xor", 0x045, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
691 [BNot, "bnot", 0x046, CleverOperandKind::Normal(1), Main, {l @ 3 => bool, f @ 0 => bool}],
692 [Neg, "neg", 0x047, CleverOperandKind::Normal(1), Main, {l @ 3 => bool, f @ 0 => bool}],
693 [Idiv, "idiv", 0x048, CleverOperandKind::Normal(1), Main, {ss @ 2..4 => u16, wide @ 1 => bool, flags @ 0 => bool}],
694 [AddRS, "add", 0x049, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
695 [SubRS, "sub", 0x04A, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
696 [AndRS, "and", 0x04B, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
697 [OrRS, "or", 0x04C, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
698 [XorRS, "xor", 0x04D, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
699 [BNotR, "bnot", 0x046, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
700 [NegR, "neg", 0x047, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
701
702 [Cmp, "cmp", 0x06C, CleverOperandKind::Normal(2), Main],
704 [Test, "test", 0x06D, CleverOperandKind::Normal(2), Main],
705 [CmpR, "cmp", 0x06C, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
706 [TestR, "test", 0x06D, CleverOperandKind::Normal(1), Main, {r @ 0..4 => CleverRegister}],
707
708 [Round, "round", 0x100, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
710 [Ceil, "ceil", 0x101, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
711 [Floor, "floor", 0x102, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
712 [FAbs, "fabs", 0x103, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
713 [FNeg, "fneg", 0x104, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
714 [FInv, "finv",0x105, CleverOperandKind::Normal(1), Float, {f @ 0 => bool}],
715 [FAdd, "fadd", 0x106, CleverOperandKind::Normal(2), Float, {f @ 0 => bool}],
716 [FSub, "fsub", 0x107, CleverOperandKind::Normal(2), Float, {f @ 0 => bool}],
717 [FMul, "fmul", 0x108, CleverOperandKind::Normal(2), Float, {f @ 0 => bool}],
718 [FDiv, "fdiv", 0x109, CleverOperandKind::Normal(2), Float, {f @ 0 => bool}],
719 [FRem, "frem", 0x10A, CleverOperandKind::Normal(2), Float, {f @ 0 => bool}],
720 [FFma, "ffma", 0x10B, CleverOperandKind::Normal(3), Float, {f @ 0 => bool}],
721
722 [FCmpz, "fcmpz", 0x118, CleverOperandKind::Normal(1), Float],
724 [FCmp, "fcmp", 0x119, CleverOperandKind::Normal(2), Float],
725
726 [Exp, "exp", 0x120, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
728 [Ln, "ln", 0x121, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
729 [Lg, "lg", 0x122, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
730 [Sin, "sin", 0x123, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
731 [Cos, "cos", 0x124, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
732 [Tan, "tan", 0x125, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
733 [Asin, "asin", 0x126, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
734 [Acos, "acos", 0x127, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
735 [Atan, "atan", 0x128, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
736 [Exp2,"exp2", 0x129, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
737 [Log10, "log10", 0x12A, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
738 [Lnp1, "lnp1", 0x12B, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
739 [Expm1, "expm1", 0x12C, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
740 [Sqrt, "sqrt", 0x12D, CleverOperandKind::Normal(1), FloatExt, {f @ 0 => bool}],
741
742 [FRaiseExcept, "fraiseexcept", 0x130, CleverOperandKind::Normal(0), Float],
744 [FTriggerExcept, "ftriggerexcept", 0x130, CleverOperandKind::Normal(0), Float],
745
746 [Xchg, "xchg", 0x200, CleverOperandKind::Normal(2), Main],
748 [Cmpxchg, "cmpxchg", 0x201, CleverOperandKind::Normal(3), Main],
749 [Wcmpxchg, "wcmpxchg", 0x202, CleverOperandKind::Normal(3), Main],
750 [Fence, "fence", 0x203, CleverOperandKind::Normal(0), Main],
751
752 [RPoll, "rpoll", 0x230, CleverOperandKind::Normal(0), Rand, {r @ .. => CleverRegister}],
754
755 [Vec, "vec", 0x400, CleverOperandKind::Insn, CleverExtension::Vec],
757 [Vmov, "vmov",0x401, CleverOperandKind::Normal(2), CleverExtension::Vec],
758 [VShuffle, "vshuffle", 0x402, CleverOperandKind::Normal(2), CleverExtension::Vec],
759
760 [CBP0A , "jp" , 0x700, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
762 [CBC0A , "jc" , 0x701, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
763 [CBV0A , "jo" , 0x702, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
764 [CBZ0A , "jz" , 0x703, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
765 [CBL0A , "jlt", 0x704, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
766 [CBLE0A, "jle", 0x705, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
767 [CBBE0A, "jbe", 0x706, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
768 [CBM0A , "jmi", 0x707, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
769 [CBPS0A, "jps", 0x708, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
770 [CBA0A , "ja" , 0x709, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
771 [CBG0A , "jgt", 0x70A, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
772 [CBGE0A, "jge", 0x70B, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
773 [CBNZ0A, "jnz", 0x70C, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
774 [CBNV0A, "jno", 0x70D, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
775 [CBNC0A, "jnc", 0x70E, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
776 [CBNP0A, "jnp", 0x70F, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
777
778 [CBP0R , "jp" , 0x710, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
779 [CBC0R , "jc" , 0x711, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
780 [CBV0R , "jo" , 0x712, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
781 [CBZ0R , "jz" , 0x713, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
782 [CBL0R , "jlt", 0x714, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
783 [CBLE0R, "jle", 0x715, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
784 [CBBE0R, "jbe", 0x716, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
785 [CBM0R , "jmi", 0x717, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
786 [CBPS0R, "jps", 0x718, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
787 [CBA0R , "ja" , 0x719, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
788 [CBG0R , "jgt", 0x71A, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
789 [CBGE0R, "jge", 0x71B, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
790 [CBNZ0R, "jnz", 0x71C, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
791 [CBNV0R, "jno", 0x71D, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
792 [CBNC0R, "jnc", 0x71E, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
793 [CBNP0R, "jnp", 0x71F, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
794
795 [CBP1A , "jp" , 0x740, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
796 [CBC1A , "jc" , 0x741, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
797 [CBV1A , "jo" , 0x742, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
798 [CBZ1A , "jz" , 0x743, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
799 [CBL1A , "jlt", 0x744, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
800 [CBLE1A, "jle", 0x745, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
801 [CBBE1A, "jbe", 0x746, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
802 [CBM1A , "jmi", 0x747, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
803 [CBPS1A, "jps", 0x748, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
804 [CBA1A , "ja" , 0x749, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
805 [CBG1A , "jgt", 0x74A, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
806 [CBGE1A, "jge", 0x74B, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
807 [CBNZ1A, "jnz", 0x74C, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
808 [CBNV1A, "jno", 0x74D, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
809 [CBNC1A, "jnc", 0x74E, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
810 [CBNP1A, "jnp", 0x74F, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
811
812 [CBP1R , "jp" , 0x750, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
813 [CBC1R , "jc" , 0x751, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
814 [CBV1R , "jo" , 0x752, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
815 [CBZ1R , "jz" , 0x753, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
816 [CBL1R , "jlt", 0x754, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
817 [CBLE1R, "jle", 0x755, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
818 [CBBE1R, "jbe", 0x756, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
819 [CBM1R , "jmi", 0x757, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
820 [CBPS1R, "jps", 0x758, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
821 [CBA1R , "ja" , 0x759, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
822 [CBG1R , "jgt", 0x75A, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
823 [CBGE1R, "jge", 0x75B, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
824 [CBNZ1R, "jnz", 0x75C, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
825 [CBNV1R, "jno", 0x75D, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
826 [CBNC1R, "jnc", 0x75E, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
827 [CBNP1R, "jnp", 0x75F, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
828
829 [CBP2A , "jp" , 0x780, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
830 [CBC2A , "jc" , 0x781, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
831 [CBV2A , "jo" , 0x782, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
832 [CBZ2A , "jz" , 0x783, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
833 [CBL2A , "jlt", 0x784, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
834 [CBLE2A, "jle", 0x785, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
835 [CBBE2A, "jbe", 0x786, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
836 [CBM2A , "jmi", 0x787, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
837 [CBPS2A, "jps", 0x788, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
838 [CBA2A , "ja" , 0x789, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
839 [CBG2A , "jgt", 0x78A, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
840 [CBGE2A, "jge", 0x78B, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
841 [CBNZ2A, "jnz", 0x78C, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
842 [CBNV2A, "jno", 0x78D, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
843 [CBNC2A, "jnc", 0x78E, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
844 [CBNP2A, "jnp", 0x78F, CleverOperandKind::AbsAddr, Main, {w @ .. => i8}],
845
846 [CBP2R , "jp" , 0x790, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
847 [CBC2R , "jc" , 0x791, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
848 [CBV2R , "jo" , 0x792, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
849 [CBZ2R , "jz" , 0x793, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
850 [CBL2R , "jlt", 0x794, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
851 [CBLE2R, "jle", 0x795, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
852 [CBBE2R, "jbe", 0x796, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
853 [CBM2R , "jmi", 0x797, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
854 [CBPS2R, "jps", 0x798, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
855 [CBA2R , "ja" , 0x799, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
856 [CBG2R , "jgt", 0x79A, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
857 [CBGE2R, "jge", 0x79B, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
858 [CBNZ2R, "jnz", 0x79C, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
859 [CBNV2R, "jno", 0x79D, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
860 [CBNC2R, "jnc", 0x79E, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
861 [CBNP2R, "jnp", 0x79F, CleverOperandKind::RelAddr, Main, {w @ .. => i8}],
862
863 [JmpA, "jmp", 0x7C0, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
865 [CallA, "call", 0x7C1, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
866 [FcallA, "fcall", 0x7C2, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
867 [Ret, "ret", 0x7C3, CleverOperandKind::Normal(0), Main],
868 [Scall, "scall", 0x7C4, CleverOperandKind::Normal(0), Main],
869 [Int, "int", 0x7C5, CleverOperandKind::HImmediate, Main, {i @ .. => u16}],
870 [IjmpA, "ijmp", 0x7C8, CleverOperandKind::HRegister, Main, {r @ .. => CleverRegister}],
871 [IcallA, "icall", 0x7C9, CleverOperandKind::HRegister, Main, {r @ .. => CleverRegister}],
872 [IfcallA, "ifcall", 0x7CA, CleverOperandKind::HRegister, Main],
873 [JmpSM, "jsm", 0x7CB, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
874 [CallSM, "callsm", 0x7CC, CleverOperandKind::AbsAddr, Main, {v @ 3 => bool, ss @ 0..2 => u16}],
875 [RetRSM, "retrsm", 0x7CD, CleverOperandKind::Normal(0), Main],
876 [JmpR, "jmp", 0x7D0, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
877 [CallR, "call", 0x7D1, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
878 [FcallR, "fcall", 0x7D2, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
879 [IjmpR, "ijmp", 0x7D8, CleverOperandKind::HRegister, Main, {r @ .. => CleverRegister}],
880 [IcallR, "icall", 0x7D9, CleverOperandKind::HRegister, Main, {r @ .. => CleverRegister}],
881 [IfcallR, "ifcall", 0x7DA, CleverOperandKind::HRegister, Main],
882 [JmpSMR, "jsm", 0x7DB, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16}],
883 [CallSMR, "callsm", 0x7DC, CleverOperandKind::AbsAddr, Main, {ss @ 0..2 => u16, v @ 3 => bool}],
884
885 [Halt, "halt", 0x801, CleverOperandKind::Normal(0), Main],
887
888 [Pcfl, "pcfl", 0x802, CleverOperandKind::Normal(0), Main],
890 [FlAll, "flall", 0x803, CleverOperandKind::Normal(0), Main],
891 [Dflush, "dflush", 0x804, CleverOperandKind::Normal(1), Main],
892 [Iflush, "iflush", 0x805, CleverOperandKind::Normal(1), Main],
893
894 [In, "in", 0x806, CleverOperandKind::Size, Main, {ss @ 0..2 => u16}],
896 [Out, "out", 0x807, CleverOperandKind::Size, Main, {ss @ 0..2 => u16}],
897
898 [StoRegF, "storegf", 0x808, CleverOperandKind::Normal(1), Main],
900 [RstRegF, "rstregf", 0x809, CleverOperandKind::Normal(1), Main],
901
902 [Scret, "scret", 0xFC6, CleverOperandKind::Normal(0), Main],
904 [Iret, "iret", 0xFC6, CleverOperandKind::Normal(0), Main],
905 [Hcall, "hcall", 0xFCB, CleverOperandKind::Normal(0), Main],
906 [Hret, "hret", 0xFD6, CleverOperandKind::Normal(0), Main],
907 [Hresume, "hresume", 0xFD7, CleverOperandKind::Normal(0), Main],
908
909 [VMCreate, "vmcreate", 0xFDA, CleverOperandKind::Normal(1), Virtualization],
911 [VMDestroy,"vmdestroy",0xFDB, CleverOperandKind::Normal(0), Virtualization],
912
913 [Und255, "und", 0xFFF, CleverOperandKind::Normal(0), Main]
914}
915
916macro_rules! prefix_valid_instructions{
917 ($($prefix:ident : {
918 $($insn:ident),*
919 $(,)?
920 })*) => {
921 impl CleverOpcode{
922 pub fn valid_prefix_for(&self, prefixed: &CleverOpcode) -> bool{
923 match (self,prefixed){
924 $($((Self:: $prefix {..},Self:: $insn {..}) => true,)*)*
925 #[allow(unreachable_patterns)] _ => false
926 }
927 }
928 }
929 }
930}
931
932prefix_valid_instructions! {
933 Repbc : { Bcpy, Bsto, Bsca, Bcmp, Btst, In, Out}
934 Repbi : { Bcpy, Bsto, Bsca, Bcmp, Btst, In, Out}
935 Vec : {Add, Sub, And, Or, Xor, Mov, MovRD, MovRS,
936 Lsh, Rsh, Arsh, Lshc, Rshc, Lrot, Rrot,
937 LshR, RshR, ArshR, LshcR, RshcR, LrotR, RrotR,
938 AddRD, SubRD, AndRD, OrRD, XorRD, BNot, Neg,
939 AddRS, SubRS, AndRS, OrRS, XorRS, BNotR, NegR,
940 Round, Ceil, Floor, FAbs, FNeg, FInv, FAdd, FSub, FMul, FDiv, FRem, FFma,
941 Exp, Ln, Lg, Sin, Cos, Tan, Asin, Acos, Atan, Exp2, Log10, Lnp1, Expm1, Sqrt,
942 }
943}
944
945macro_rules! gpr_specializations{
946 ($($base:ident : {
947 $left_spec:ident
948 $(, $right_spec:ident)?
949 $(,)?
950 })*) => {
951 impl CleverOpcode{
952 pub fn gpr_dest_specialization(&self,reg: CleverRegister) -> Option<CleverOpcode>{
953 match self{
954 $(Self:: $base {..} => {
955 Some(Self:: $left_spec {r: reg})
956 },)*
957 _ => None
958 }
959 }
960
961 pub fn gpr_src_specialization(&self,reg: CleverRegister) -> Option<CleverOpcode>{
962 match self{
963 $($(Self:: $base {..} => {
964 Some(Self:: $right_spec {r: reg})
965 },)?)*
966 _ => None
967 }
968 }
969
970 pub fn is_gpr_left_spec(&self) -> bool{
971 match self{
972 $(Self::$left_spec {..} => {true},)*
973 _ => false
974 }
975 }
976 pub fn is_gpr_right_spec(&self) -> bool{
977 match self{
978 $($(Self::$right_spec {..} => {true},)?)*
979 _ => false
980 }
981 }
982
983 pub fn get_spec_register(&self) -> Option<CleverRegister>{
984 match self{
985 $(Self::$left_spec {r} => {Some(*r)},)*
986 $($(Self::$right_spec {r} => {Some(*r)},)?)*
987 _ => None
988 }
989 }
990 }
991 }
992}
993
994gpr_specializations! {
995 Add: {AddRD, AddRS}
996 Sub: {SubRD, SubRS}
997 And: {AndRD, AndRS}
998 Or: {OrRD , OrRS }
999 Xor: {XorRD, XorRS}
1000 Mov: {MovRD, MovRS}
1001 Lea: {LeaRD}
1002 Lsh: {LshR}
1003 Rsh: {RshR}
1004 Arsh: {ArshR}
1005 Lshc: {LshcR}
1006 Rshc: {RshcR}
1007 Lrot: {LrotR}
1008 Rrot: {RrotR}
1009 Neg: {NegR}
1010 BNot: {BNotR}
1011}
1012
1013macro_rules! nop_instructions{
1014 ($($constant:ident: $var:ident),*) => {
1015 impl CleverOpcode{
1016 $(#[allow(non_upper_case_globals)] pub const $constant: Self = Self:: $var{any: 0};)*
1017 }
1018 }
1019}
1020
1021nop_instructions!(NOP0: Nop10, NOP1: Nop11, NOP2: Nop12, NOP3: Nop13);
1022
1023macro_rules! print_h_field{
1024 [$(($enum:ident {$($h:pat,)* $(, ..)?} => |$fmt:pat| $e:expr)),* $(,)?] => {
1025 impl core::fmt::Display for CleverOpcode{
1026 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result{
1027 f.write_str(self.name())?;
1028
1029 match self{
1030 $(Self:: $enum {$($h,)* ..} => (match f{
1031 $fmt => $e
1032 }),)*
1033 _ => Ok(())
1034 }
1035 }
1036 }
1037 }
1038}
1039
1040print_h_field![];
1041
1042impl CleverOpcode {
1043 pub fn is_branch(&self) -> bool {
1044 (self.opcode() < 0xFD80) && (self.opcode() & 0x7200 == 0x7000)
1045 }
1046
1047 pub fn is_cbranch(&self) -> bool {
1048 matches!(self.opcode() & 0xFE00, 0x7000 | 0x7400 | 0x7800)
1049 }
1050
1051 pub fn branch_pcrel(&self) -> Option<bool> {
1052 if self.is_branch() {
1053 Some((self.opcode() & 0x100) != 0)
1054 } else {
1055 None
1056 }
1057 }
1058
1059 pub fn branch_set_relative(&self, isrel: bool) -> Option<CleverOpcode> {
1060 if self.is_branch() {
1061 let opc = (self.opcode() & !0x100) | (if isrel { 0x100 } else { 0x000 });
1062 CleverOpcode::from_opcode(opc)
1063 } else {
1064 None
1065 }
1066 }
1067
1068 pub fn branch_condition(&self) -> Option<ConditionCode> {
1069 match self.opcode() & 0xFE00 {
1070 0x7000 | 0x7400 | 0x7800 => Some(ConditionCode::from_bits((self.opcode() & 0xf0) >> 4)),
1071 _ => None,
1072 }
1073 }
1074
1075 pub fn branch_weight(&self) -> Option<i8> {
1076 match self.opcode() & 0xFE00 {
1077 0x7000 | 0x7400 | 0x7800 => Some(i8::from_bits(self.opcode() & 0xf)),
1078 _ => None,
1079 }
1080 }
1081
1082 pub fn branch_width(&self) -> Option<u16> {
1083 if self.opcode() & 0xFFF0 == 0x7C40 {
1084 return None;
1085 }
1086 match self.opcode() & 0xFE00 {
1087 0x7000 | 0x7400 | 0x7800 => Some(((self.opcode() & 0xC00) >> 10) + 1),
1088 0x7C00 => Some((self.opcode() & 0x2) + 1),
1089 _ => None,
1090 }
1091 }
1092
1093 pub fn cbranch(cc: ConditionCode, width: u16, pcrel: bool, weight: i8) -> Self {
1094 assert!(width - 1 < 3);
1095 let (width, pcrel, cc, weight) = (
1096 (width - 1) << 10,
1097 (pcrel as u16) << 8,
1098 cc.to_hbits() << 4,
1099 (weight & 0xf) as u16,
1100 );
1101
1102 Self::from_opcode(0x7000 | width | pcrel | cc | weight).unwrap()
1103 }
1104}
1105#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1106pub enum CleverOperand {
1107 Register {
1108 size: u16,
1109 reg: CleverRegister,
1110 },
1111 Indirect {
1112 size: u16,
1113 base: CleverRegister,
1114 scale: u8,
1115 index: CleverIndex,
1116 },
1117 VecPair {
1118 size: u16,
1119 lo: CleverRegister,
1120 },
1121 Immediate(CleverImmediate),
1122}
1123
1124#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1125pub enum CleverImmediate {
1126 Short(u16),
1127 ShortRel(i16),
1128 ShortAddr(Address),
1129 ShortAddrRel(Address),
1130 Long(u16, u64),
1131 LongRel(u16, i64),
1132 LongAddr(u16, Address),
1133 LongAddrRel(u16, Address),
1134 LongMem(u16, Address, u16),
1135 LongMemRel(u16, Address, u16),
1136 Vec(u128),
1137}
1138
1139impl CleverImmediate {
1140 pub fn addr(&self) -> Option<(u64, &Address, bool)> {
1141 match self {
1142 CleverImmediate::ShortAddr(addr) => Some((12, addr, false)),
1143 CleverImmediate::ShortAddrRel(addr) => Some((12, addr, true)),
1144 CleverImmediate::LongAddr(addrsize, addr) => Some((u64::from(*addrsize), addr, false)),
1145 CleverImmediate::LongAddrRel(addrsize, addr) => {
1146 Some((u64::from(*addrsize), addr, false))
1147 }
1148 CleverImmediate::LongMem(addrsize, addr, _) => {
1149 Some((u64::from(*addrsize), addr, false))
1150 }
1151 CleverImmediate::LongMemRel(addrsize, addr, _) => {
1152 Some((u64::from(*addrsize), addr, false))
1153 }
1154 _ => None,
1155 }
1156 }
1157
1158 pub fn is_short(&self) -> bool {
1159 matches!(
1160 self,
1161 Self::Short(_) | Self::ShortRel(_) | Self::ShortAddr(_) | Self::ShortAddrRel(_)
1162 )
1163 }
1164}
1165
1166fn write_immediate_size(size: u16, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1167 match size {
1168 8 => f.write_str("byte"),
1169 16 => f.write_str("half"),
1170 32 => f.write_str("single"),
1171 64 => f.write_str("double"),
1172 128 => f.write_str("quad"),
1173 n => f.write_fmt(format_args!("<invalid-size {}>", n)),
1174 }
1175}
1176
1177impl core::fmt::Display for CleverImmediate {
1178 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1179 match self {
1180 CleverImmediate::Short(s) => f.write_fmt(format_args!("short {}", s)),
1181 CleverImmediate::ShortRel(s) => f.write_fmt(format_args!("short {}+ip", s)),
1182 CleverImmediate::ShortAddr(addr) => f.write_fmt(format_args!("short {}", addr)),
1183 CleverImmediate::ShortAddrRel(addr) => f.write_fmt(format_args!("short {}+ip", addr)),
1184 CleverImmediate::Long(size, val) => {
1185 write_immediate_size(*size, f)?;
1186 f.write_fmt(format_args!(" {}", val))
1187 }
1188 CleverImmediate::LongRel(size, val) => {
1189 write_immediate_size(*size, f)?;
1190 f.write_fmt(format_args!(" {}+ip", val))
1191 }
1192 CleverImmediate::LongAddr(size, val) => {
1193 write_immediate_size(*size, f)?;
1194 f.write_fmt(format_args!(" {}", val))
1195 }
1196 CleverImmediate::LongAddrRel(size, val) => {
1197 write_immediate_size(*size, f)?;
1198 f.write_fmt(format_args!(" {}+ip", val))
1199 }
1200 CleverImmediate::LongMem(asize, val, refsize) => {
1201 write_immediate_size(*refsize, f)?;
1202 f.write_str(" [")?;
1203 write_immediate_size(*asize, f)?;
1204 f.write_fmt(format_args!(" {}]", val))
1205 }
1206 CleverImmediate::LongMemRel(asize, val, refsize) => {
1207 write_immediate_size(*refsize, f)?;
1208 f.write_str(" [")?;
1209 write_immediate_size(*asize, f)?;
1210 f.write_fmt(format_args!(" {}+ip]", val))
1211 }
1212 CleverImmediate::Vec(v) => f.write_fmt(format_args!("quad {}", v)),
1213 }
1214 }
1215}
1216
1217impl CleverOperand {
1218 pub fn size(&self) -> u16 {
1219 match self {
1220 CleverOperand::Register { size, .. } => *size,
1221 CleverOperand::VecPair { size, .. } => *size,
1222 CleverOperand::Indirect { size, .. } => *size,
1223 CleverOperand::Immediate(
1224 CleverImmediate::Short(_)
1225 | CleverImmediate::ShortRel(_)
1226 | CleverImmediate::ShortAddr(_)
1227 | CleverImmediate::ShortAddrRel(_),
1228 ) => 12,
1229 CleverOperand::Immediate(
1230 CleverImmediate::Long(size, _)
1231 | CleverImmediate::LongRel(size, _)
1232 | CleverImmediate::LongAddr(size, _)
1233 | CleverImmediate::LongAddrRel(size, _),
1234 ) => *size,
1235 CleverOperand::Immediate(CleverImmediate::Vec(_)) => 16,
1236 CleverOperand::Immediate(
1237 CleverImmediate::LongMem(_, _, size) | CleverImmediate::LongMemRel(_, _, size),
1238 ) => *size,
1239 }
1240 }
1241
1242 pub fn size_ss(&self) -> Option<u16> {
1243 match self.size() {
1244 8 => Some(0),
1245 12 => None,
1246 16 => Some(1),
1247 32 => Some(2),
1248 64 => Some(3),
1249 128 => Some(4),
1250 size => panic!("Invalid register size {:?}", size),
1251 }
1252 }
1253
1254 pub fn as_control_structure(&self) -> u16 {
1255 match self {
1256 CleverOperand::Register { size, reg } => {
1257 let ss = match size {
1258 8 => 0,
1259 16 => 1,
1260 32 => 2,
1261 64 => 3,
1262 size => panic!("Invalid register size {:?}", size),
1263 };
1264
1265 let r = reg.0 as u16;
1266 (ss << 8) | r
1267 }
1268 CleverOperand::Indirect {
1269 size,
1270 base,
1271 scale,
1272 index,
1273 } => {
1274 let ss = match size {
1275 8 => 0,
1276 16 => 1,
1277 32 => 2,
1278 64 => 3,
1279 size => panic!("Invalid register size {:?}", size),
1280 };
1281
1282 let ll = match scale {
1283 1 => 0,
1284 2 => 1,
1285 4 => 2,
1286 8 => 3,
1287 16 => 4,
1288 32 => 5,
1289 64 => 6,
1290 128 => 7,
1291 scale => panic!("Invalid scale {:?}", scale),
1292 };
1293
1294 let (o, k) = match index {
1295 CleverIndex::Abs(val) => ((*val as u16) & 0xf, 1),
1296 CleverIndex::Register(r) => ((r.0 as u16) & 0xf, 0),
1297 };
1298
1299 0x4000 | (o << 10) | (ll << 7) | (k << 6) | (ss << 4) | ((base.0 as u16) & 0xf)
1300 }
1301 CleverOperand::Immediate(imm) => match imm {
1302 CleverImmediate::Short(val) => 0x8000 | (*val),
1303 CleverImmediate::ShortRel(val) => 0x9000 | (*val as u16),
1304 CleverImmediate::ShortAddr(_) => 0x8000,
1305 CleverImmediate::ShortAddrRel(_) => 0x9000,
1306 CleverImmediate::Long(size, _) => {
1307 let ss = match size {
1308 16 => 0,
1309 32 => 1,
1310 64 => 2,
1311 size => panic!("Invalid Immediate size {:?}", size),
1312 };
1313
1314 0xC000 | (ss << 8)
1315 }
1316 CleverImmediate::LongRel(size, _) => {
1317 let ss = match size {
1318 16 => 0,
1319 32 => 1,
1320 64 => 2,
1321 size => panic!("Invalid Immediate size {:?}", size),
1322 };
1323
1324 0xC400 | (ss << 8)
1325 }
1326 CleverImmediate::LongAddr(size, _) => {
1327 let ss = match size {
1328 16 => 0,
1329 32 => 1,
1330 64 => 2,
1331 size => panic!("Invalid Immediate size {:?}", size),
1332 };
1333
1334 0xC000 | (ss << 8)
1335 }
1336 CleverImmediate::LongAddrRel(size, _) => {
1337 let ss = match size {
1338 16 => 0,
1339 32 => 1,
1340 64 => 2,
1341 size => panic!("Invalid Immediate size {:?}", size),
1342 };
1343
1344 0xC400 | (ss << 8)
1345 }
1346 CleverImmediate::LongMem(size, _, refsize) => {
1347 let ss = match size {
1348 16 => 0,
1349 32 => 1,
1350 64 => 2,
1351 size => panic!("Invalid Immediate size {:?}", size),
1352 };
1353
1354 let zz = match refsize {
1355 8 => 0,
1356 16 => 1,
1357 32 => 2,
1358 64 => 3,
1359 128 => 4,
1360 size => panic!("Invalid reference size {:?}", size),
1361 };
1362
1363 0xE000 | (ss << 8) | (zz << 4)
1364 }
1365 CleverImmediate::LongMemRel(size, _, refsize) => {
1366 let ss = match size {
1367 16 => 0,
1368 32 => 1,
1369 64 => 2,
1370 size => panic!("Invalid Immediate size {:?}", size),
1371 };
1372
1373 let zz = match refsize {
1374 8 => 0,
1375 16 => 1,
1376 32 => 2,
1377 64 => 3,
1378 128 => 4,
1379 size => panic!("Invalid reference size {:?}", size),
1380 };
1381
1382 0xE400 | (ss << 8) | (zz << 4)
1383 }
1384 CleverImmediate::Vec(_) => 0xC300,
1385 },
1386 CleverOperand::VecPair { size, lo } => {
1387 let ss = match size {
1388 8 => 0,
1389 16 => 1,
1390 32 => 2,
1391 64 => 3,
1392 128 => 4,
1393 size => panic!("Invalid register size {:?}", size),
1394 };
1395
1396 let r = lo.0 as u16;
1397 0x2000 | (ss << 8) | r
1398 }
1399 }
1400 }
1401
1402 pub fn immediate_value(&self) -> Option<&CleverImmediate> {
1403 match self {
1404 Self::Immediate(imm) => Some(imm),
1405 _ => None,
1406 }
1407 }
1408}
1409
1410impl core::fmt::Display for CleverOperand {
1411 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1412 match self {
1413 CleverOperand::Register { size, reg } => {
1414 write_immediate_size(*size, f)?;
1415 f.write_fmt(format_args!(" {}", reg))
1416 }
1417 CleverOperand::Indirect {
1418 size,
1419 base,
1420 scale: _,
1421 index: CleverIndex::Abs(0),
1422 } => {
1423 write_immediate_size(*size, f)?;
1424 f.write_fmt(format_args!("[{}]", base))
1425 }
1426 CleverOperand::Indirect {
1427 size,
1428 base,
1429 scale: 1,
1430 index,
1431 } => {
1432 write_immediate_size(*size, f)?;
1433 f.write_fmt(format_args!("[{}+{}]", index, base))
1434 }
1435 CleverOperand::Indirect {
1436 size,
1437 base,
1438 scale,
1439 index,
1440 } => {
1441 write_immediate_size(*size, f)?;
1442 f.write_fmt(format_args!("[{}*{}+{}]", scale, index, base))
1443 }
1444 CleverOperand::VecPair { size, lo } => {
1445 write_immediate_size(*size, f)?;
1446 f.write_fmt(format_args!(" {}", lo))
1447 }
1448 CleverOperand::Immediate(imm) => imm.fmt(f),
1449 }
1450 }
1451}
1452
1453#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1454pub struct CleverInstruction {
1455 prefix: Option<CleverOpcode>,
1456 opcode: CleverOpcode,
1457 operands: Vec<CleverOperand>,
1458}
1459
1460impl CleverInstruction {
1461 pub const fn new(opcode: CleverOpcode, operands: Vec<CleverOperand>) -> Self {
1462 Self {
1463 prefix: None,
1464 opcode,
1465 operands,
1466 }
1467 }
1468 pub const fn new_prefixed(
1469 prefix: CleverOpcode,
1470 opcode: CleverOpcode,
1471 operands: Vec<CleverOperand>,
1472 ) -> Self {
1473 Self {
1474 prefix: Some(prefix),
1475 opcode,
1476 operands,
1477 }
1478 }
1479
1480 pub fn prefix(&self) -> Option<CleverOpcode> {
1481 self.prefix
1482 }
1483
1484 pub fn opcode(&self) -> CleverOpcode {
1485 self.opcode
1486 }
1487
1488 pub fn operands(&self) -> &[CleverOperand] {
1489 &self.operands
1490 }
1491
1492 pub fn set_prefix(&mut self, prefix: CleverOpcode) {
1493 self.prefix = Some(prefix);
1494 }
1495}
1496
1497impl core::fmt::Display for CleverInstruction {
1498 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1499 self.opcode().fmt(f)?;
1500
1501 match self.opcode().operands() {
1502 CleverOperandKind::Size => {
1503 let ss = self.opcode().opcode() & 0x3;
1504 match ss {
1505 0 => f.write_str(" byte")?,
1506 1 => f.write_str(" half")?,
1507 2 => f.write_str(" single")?,
1508 3 => f.write_str(" double")?,
1509 _ => unreachable!(),
1510 }
1511 }
1512 CleverOperandKind::HImmediate => {
1513 let h = self.opcode().opcode() & 0xf;
1514 f.write_str(" ")?;
1515 h.fmt(f)?;
1516 }
1517 CleverOperandKind::HRegister => {
1518 let h = self.opcode().opcode() & 0xf;
1519 let r = CleverRegister(h as u8);
1520 f.write_str(" ")?;
1521 r.fmt(f)?;
1522 }
1523 _ => {
1524 let mut sep = " ";
1525
1526 if self.opcode().is_gpr_left_spec() {
1527 sep = ", ";
1528 f.write_str(" ")?;
1529 self.opcode().get_spec_register().unwrap().fmt(f)?;
1530 }
1531 for opr in self.operands() {
1532 f.write_str(sep)?;
1533 sep = ", ";
1534 opr.fmt(f)?;
1535 }
1536 if self.opcode().is_gpr_right_spec() {
1537 f.write_str(sep)?;
1538 self.opcode().get_spec_register().unwrap().fmt(f)?;
1539 }
1540 }
1541 }
1542
1543 Ok(())
1544 }
1545}
1546
1547pub struct CleverEncoder<W> {
1548 inner: W,
1549}
1550
1551impl<W> CleverEncoder<W> {
1552 pub const fn new(inner: W) -> Self {
1553 Self { inner }
1554 }
1555
1556 pub fn into_inner(self) -> W {
1557 self.inner
1558 }
1559
1560 pub fn inner_mut(&mut self) -> &mut W {
1561 &mut self.inner
1562 }
1563
1564 pub fn inner(&self) -> &W {
1565 &self.inner
1566 }
1567}
1568
1569impl<W: Write> Write for CleverEncoder<W> {
1570 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
1571 self.inner.write(buf)
1572 }
1573
1574 fn flush(&mut self) -> std::io::Result<()> {
1575 self.inner.flush()
1576 }
1577}
1578
1579impl<W: InsnWrite> InsnWrite for CleverEncoder<W> {
1580 fn write_addr(&mut self, size: usize, addr: Address, rel: bool) -> std::io::Result<()> {
1581 self.inner.write_addr(size, addr, rel)
1582 }
1583
1584 fn write_reloc(&mut self, reloc: crate::traits::Reloc) -> std::io::Result<()> {
1585 self.inner.write_reloc(reloc)
1586 }
1587
1588 fn offset(&self) -> usize {
1589 self.inner.offset()
1590 }
1591}
1592
1593impl<W: InsnWrite> CleverEncoder<W> {
1594 pub fn write_instruction(&mut self, insn: CleverInstruction) -> std::io::Result<()> {
1595 if let Some(prefix) = insn.prefix() {
1596 self.write_all(&prefix.opcode().to_be_bytes())?;
1597 }
1598 self.write_all(&insn.opcode().opcode().to_be_bytes())?;
1599 match insn.opcode().operands(){
1600 CleverOperandKind::Size | CleverOperandKind::HRegister | CleverOperandKind::HImmediate => {
1601 assert_eq!(insn.operands().len(),0);
1602 }
1603 CleverOperandKind::Normal(n) => {
1604 assert_eq!(insn.operands().len(), n as usize);
1605
1606 for op in insn.operands(){
1607 let operand = op.as_control_structure();
1608
1609 let imm = op.immediate_value();
1610
1611 if let Some(imm) = imm{
1612 match imm{
1613 CleverImmediate::ShortAddr(Address::Abs(addr)) => self.write_all(&(operand | u16::try_from(*addr).unwrap()).to_be_bytes())?,
1614 CleverImmediate::ShortAddrRel(Address::Disp(addr)) => self.write_all(&(operand | u16::try_from(*addr).unwrap()).to_be_bytes())?,
1615 CleverImmediate::ShortAddr(addr) => {
1616 let relocc = RelocCode::CleverShort;
1617 let reloc = match addr{
1618 Address::Abs(_) => unreachable!(),
1619 Address::Disp(_) => todo!("Non-symbol short relocation"),
1620 Address::Symbol { name, disp } => {
1621 Reloc{
1622 code: relocc,
1623 symbol: name.clone(),
1624 addend: Some(*disp),
1625 offset: self.offset() as u64
1626 }
1627 },
1628 Address::PltSym { name: _ } => panic!("Cannot use explicit short relocation against GOT or PLT"),
1629 };
1630 self.write_all(&(operand.to_be_bytes()))?;
1631 self.write_reloc(reloc)?;
1632 },
1633 CleverImmediate::ShortAddrRel(addr) => {
1634 let relocc = RelocCode::CleverShortPcrel;
1635 let reloc = match addr{
1636 Address::Abs(val) => Reloc { code: relocc, symbol: "*ABS*".to_string(), addend: Some(*val as i64), offset: self.offset() as u64},
1637 Address::Disp(_) => unreachable!(),
1638 Address::Symbol { name, disp } => {
1639 Reloc{
1640 code: relocc,
1641 symbol: name.clone(),
1642 addend: Some(*disp),
1643 offset: self.offset() as u64
1644 }
1645 },
1646 Address::PltSym { name: _ } => panic!("Cannot use explicit short relocation against GOT or PLT"),
1647 };
1648 self.write_all(&(operand.to_be_bytes()))?;
1649 self.write_reloc(reloc)?;
1650 },
1651 CleverImmediate::Long(size, val) => {
1652 let val_bytes = &(*val).to_le_bytes()[..((*size/8) as usize)];
1653 self.write_all(&operand.to_be_bytes())?;
1654 self.write_all(val_bytes)?;
1655 }
1656 CleverImmediate::LongRel(size, val) => {
1657 let val_bytes = &(*val).to_le_bytes()[..((*size/8) as usize)];
1658 self.write_all(&operand.to_be_bytes())?;
1659 self.write_all(val_bytes)?;
1660 }
1661 CleverImmediate::LongAddr(size, addr) | CleverImmediate::LongMem(size,addr,_) => {
1662 self.write_all(&operand.to_be_bytes())?;
1663 self.write_addr(*size as usize, addr.clone(), false)?;
1664 }
1665 CleverImmediate::LongAddrRel(size, addr) | CleverImmediate::LongMemRel(size,addr,_) => {
1666 self.write_all(&operand.to_be_bytes())?;
1667 self.write_addr(*size as usize, addr.clone(), true)?;
1668 }
1669 CleverImmediate::Vec(vec) => {
1670 self.write_all(&operand.to_be_bytes())?;
1671 self.write_all(&vec.to_le_bytes())?;
1672 }
1673 _ => self.write_all(&operand.to_be_bytes())?
1674 }
1675 }else{
1676 self.write_all(&operand.to_be_bytes())?;
1677 }
1678 }
1679 },
1680 CleverOperandKind::AbsAddr => {
1681 assert_eq!(insn.operands().len(),1);
1682
1683 let imm = insn.operands()[0].immediate_value()
1684 .unwrap();
1685
1686 let width = insn.opcode().branch_width().unwrap();
1687 match imm{
1688 CleverImmediate::Long(_, a) => {
1689 self.write_all(&((*a).to_be_bytes()[..(1<<width)]))?;
1690 }
1691 CleverImmediate::LongAddr(_, addr) => {
1692 self.write_addr((8<<width) as usize, addr.clone(), false)?;
1693 }
1694 CleverImmediate::LongAddrRel(_, addr) => {
1695 self.write_addr((8<<width) as usize, addr.clone(), false)?;
1696 }
1697 a => panic!("Got wrong operand type for a branch {:?}",a)
1698 }
1699 },
1700 CleverOperandKind::RelAddr => {
1701 assert_eq!(insn.operands().len(),1);
1702 let imm = insn.operands()[0].immediate_value()
1703 .unwrap();
1704
1705 let width = insn.opcode().branch_width().unwrap();
1706
1707 match imm{
1708 CleverImmediate::LongRel(_, a) => {
1709 self.write_all(&((*a).to_be_bytes()[..(1<<width)]))?;
1710 }
1711 CleverImmediate::LongAddrRel(_, addr) => {
1712 self.write_addr((8<<width) as usize, addr.clone(), true)?;
1713 }
1714 a => panic!("Got wrong operand type for a branch {:?}",a)
1715 }
1716 },
1717 CleverOperandKind::Insn => panic!("Cannot write a prefix as a primary instruction, use `CleverInstruction::new_with_prefix` instead"),
1718 }
1719 Ok(())
1720 }
1721}
1722
1723pub struct CleverDecoder<R> {
1724 inner: R,
1725}
1726
1727impl<R> CleverDecoder<R> {
1728 pub const fn new(inner: R) -> Self {
1729 Self { inner }
1730 }
1731
1732 pub fn into_inner(self) -> R {
1733 self.inner
1734 }
1735
1736 pub fn inner_mut(&mut self) -> &mut R {
1737 &mut self.inner
1738 }
1739
1740 pub fn inner(&self) -> &R {
1741 &self.inner
1742 }
1743}
1744
1745impl<R: Read> Read for CleverDecoder<R> {
1746 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
1747 self.inner.read(buf)
1748 }
1749}
1750
1751impl<R: InsnRead> InsnRead for CleverDecoder<R> {
1752 fn read_addr(&mut self, size: usize, rel: bool) -> std::io::Result<Address> {
1753 self.inner.read_addr(size, rel)
1754 }
1755
1756 fn read_reloc(
1757 &mut self,
1758 size: usize,
1759 rel: bool,
1760 offset: Option<isize>,
1761 ) -> std::io::Result<Option<Address>> {
1762 self.inner.read_reloc(size, rel, offset)
1763 }
1764}
1765
1766impl<R: InsnRead> CleverDecoder<R> {
1767 pub fn read_insn(&mut self) -> std::io::Result<CleverInstruction> {
1768 let mut opcode = [0u8; 2];
1769 self.read_exact(&mut opcode)?;
1770 let opcode = u16::from_be_bytes(opcode);
1771 let op = CleverOpcode::from_opcode(opcode).ok_or_else(|| {
1772 std::io::Error::new(
1773 ErrorKind::InvalidData,
1774 format!("Invalid opcode {:#x}", opcode),
1775 )
1776 })?;
1777 match op.operands() {
1778 CleverOperandKind::Insn => {
1779 let mut inner = self.read_insn()?;
1780 if let Some(prefix) = inner.prefix {
1781 return Err(std::io::Error::new(
1782 ErrorKind::InvalidData,
1783 format!("Cannot combine multiple prefixes {:?} and {:?}", op, prefix),
1784 ));
1785 } else {
1786 inner.prefix = Some(op);
1787 }
1788 Ok(inner)
1789 }
1790 CleverOperandKind::Size
1791 | CleverOperandKind::HRegister
1792 | CleverOperandKind::HImmediate => Ok(CleverInstruction::new(op, Vec::new())),
1793 kind @ (CleverOperandKind::AbsAddr | CleverOperandKind::RelAddr) => {
1794 let bytes = 8 << (op.branch_width().unwrap() as u32);
1795 let rel = kind == CleverOperandKind::RelAddr;
1796 let addr = self.read_addr(bytes, rel)?;
1797
1798 Ok(CleverInstruction::new(
1799 op,
1800 vec![CleverOperand::Immediate(CleverImmediate::LongAddr(
1801 bytes as u16,
1802 addr,
1803 ))],
1804 ))
1805 }
1806 CleverOperandKind::Normal(n) => {
1807 let mut ops = Vec::with_capacity(n as usize);
1808
1809 for _ in 0..n {
1810 let mut ctrl = [0u8; 2];
1811 self.read_exact(&mut ctrl)?;
1812 let ctrl = u16::from_be_bytes(ctrl);
1813
1814 let opr = match ctrl >> 14 {
1815 0b00 => {
1816 let v = (ctrl & 0x2000) != 0;
1817
1818 let reg = CleverRegister(ctrl as u8);
1819
1820 let ss = 8 << ((ctrl >> 8) & 0x7);
1821
1822 if v {
1823 CleverOperand::VecPair { size: ss, lo: reg }
1824 } else {
1825 CleverOperand::Register { size: ss, reg }
1826 }
1827 }
1828 0b01 => {
1829 let offset = (ctrl >> 10) & 0xf;
1830
1831 let scale = 1 << ((ctrl >> 7) & 0x7);
1832
1833 let ss = 8 << ((ctrl >> 4) & 0x3) as u32;
1834
1835 let k = (ctrl & 0x40) != 0;
1836
1837 let base = CleverRegister((ctrl & 0xf) as u8);
1838
1839 let index = if k {
1840 CleverIndex::Abs(offset as i16)
1841 } else {
1842 CleverIndex::Register(CleverRegister(offset as u8))
1843 };
1844
1845 CleverOperand::Indirect {
1846 size: ss,
1847 base,
1848 scale,
1849 index,
1850 }
1851 }
1852 0b10 => {
1853 let short = ctrl & 0xfff;
1854
1855 let rel = (ctrl & 0x1000) != 0;
1856
1857 let addr = self.read_reloc(12, rel, Some(-2))?;
1858
1859 let imm = match (addr, rel) {
1860 (Some(addr), true) => CleverImmediate::ShortAddrRel(addr),
1861 (Some(addr), false) => CleverImmediate::ShortAddr(addr),
1862 (None, true) => CleverImmediate::ShortRel(short as i16),
1863 (None, false) => CleverImmediate::Short(short),
1864 };
1865
1866 CleverOperand::Immediate(imm)
1867 }
1868 0b11 => {
1869 let mem = (ctrl & 0x2000) != 0;
1870 let rel = (ctrl & 0x400) != 0;
1871 let size = 8 << (1 + ((ctrl >> 8) & 0x3));
1872
1873 let zize = 8 << ((ctrl >> 4) & 0xf);
1874
1875 let val = self.read_addr(size as usize, rel)?;
1876
1877 let imm = match (val, rel, mem) {
1878 (Address::Abs(val), false, false) if size == 128 => {
1879 CleverImmediate::Vec(val)
1880 }
1881 _ if size == 128 => {
1882 return Err(std::io::Error::new(
1883 ErrorKind::InvalidData,
1884 "invalid immediate with size 128",
1885 ))
1886 }
1887 (Address::Disp(val), true, false) => {
1888 CleverImmediate::LongRel(size, val)
1889 }
1890 (Address::Abs(val), false, false) => {
1891 CleverImmediate::Long(size, val as u64)
1892 }
1893 (addr, true, false) => CleverImmediate::LongAddrRel(size, addr),
1894 (addr, false, false) => CleverImmediate::LongAddr(size, addr),
1895 (addr, true, true) => CleverImmediate::LongMemRel(size, addr, zize),
1896 (addr, false, true) => CleverImmediate::LongMem(size, addr, zize),
1897 };
1898
1899 CleverOperand::Immediate(imm)
1900 }
1901 _ => unreachable!(),
1902 };
1903
1904 ops.push(opr);
1905 }
1906
1907 Ok(CleverInstruction::new(op, ops))
1908 }
1909 }
1910 }
1911}
1912
1913#[non_exhaustive]
1914#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1915pub struct CleverPrinter {}
1916
1917impl CleverPrinter {
1918 pub const fn new() -> Self {
1919 Self {}
1920 }
1921}
1922
1923impl Default for CleverPrinter {
1924 fn default() -> Self {
1925 Self::new()
1926 }
1927}
1928
1929impl OpcodePrinter for CleverPrinter {
1930 fn print_opcode(
1931 &self,
1932 f: &mut core::fmt::Formatter,
1933 read: &mut dyn InsnRead,
1934 ) -> std::io::Result<()> {
1935 let insn = CleverDecoder::new(read).read_insn()?;
1936
1937 <CleverInstruction as core::fmt::Display>::fmt(&insn, f).unwrap();
1938 Ok(())
1939 }
1940}
1941
1942#[cfg(test)]
1943mod test {
1944 use crate::test::TestWriter;
1945
1946 use super::*;
1947 #[test]
1948 pub fn test_encode_nop() {
1949 let mut encoder = CleverEncoder::new(TestWriter { inner: Vec::new() });
1950 encoder
1951 .write_instruction(CleverInstruction::new(CleverOpcode::NOP0, vec![]))
1952 .unwrap();
1953
1954 assert_eq!(&*encoder.inner_mut().inner, &[0x01, 0x00]);
1955 }
1956
1957 #[test]
1958 pub fn test_encode_nop1() {
1959 let mut encoder = CleverEncoder::new(TestWriter { inner: Vec::new() });
1960 encoder
1961 .write_instruction(CleverInstruction::new(
1962 CleverOpcode::NOP1,
1963 vec![CleverOperand::Register {
1964 size: 64,
1965 reg: CleverRegister::r0,
1966 }],
1967 ))
1968 .unwrap();
1969
1970 assert_eq!(&*encoder.inner_mut().inner, &[0x01, 0x10, 0x03, 0x00]);
1971 }
1972
1973 #[test]
1974 pub fn test_encode_nop1_simm() {
1975 let mut encoder = CleverEncoder::new(TestWriter { inner: Vec::new() });
1976 encoder
1977 .write_instruction(CleverInstruction::new(
1978 CleverOpcode::NOP1,
1979 vec![CleverOperand::Immediate(CleverImmediate::Short(1337))],
1980 ))
1981 .unwrap();
1982
1983 assert_eq!(&*encoder.inner_mut().inner, &[0x01, 0x10, 0x85, 0x39]);
1984 }
1985
1986 #[test]
1987 pub fn test_encode_nop2() {
1988 let mut encoder = CleverEncoder::new(TestWriter { inner: Vec::new() });
1989 encoder
1990 .write_instruction(CleverInstruction::new(
1991 CleverOpcode::NOP2,
1992 vec![
1993 CleverOperand::Register {
1994 size: 64,
1995 reg: CleverRegister::flags,
1996 },
1997 CleverOperand::Immediate(CleverImmediate::Long(16, 1337)),
1998 ],
1999 ))
2000 .unwrap();
2001
2002 assert_eq!(
2003 &*encoder.inner_mut().inner,
2004 &[0x01, 0x20, 0x03, 0x11, 0xC0, 0x00, 0x39, 0x05]
2005 );
2006 }
2007
2008 #[test]
2009
2010 pub fn test_encode_branch() {
2011 let mut encoder = CleverEncoder::new(TestWriter { inner: Vec::new() });
2012 encoder
2013 .write_instruction(CleverInstruction::new(
2014 CleverOpcode::cbranch(ConditionCode::Zero, 1, true, 0),
2015 vec![CleverOperand::Immediate(CleverImmediate::LongAddrRel(
2016 16,
2017 Address::Disp(-32),
2018 ))],
2019 ))
2020 .unwrap();
2021
2022 assert_eq!(
2023 &*encoder.inner().inner,
2024 &[0x71, 0x30, 0xe0, 0xff],
2025 "{:x?} != {:x?}",
2026 encoder.inner().inner,
2027 [0x71, 0x30, 0xe0, 0xff]
2028 );
2029 }
2030}