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
110
111
112
113
114
115
116
117
118
use core::convert::TryFrom;
use bad64_sys::*;
use crate::Reg;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ArrSpec {
Full(Option<u32>),
TwoDoubles(Option<u32>),
FourSingles(Option<u32>),
EightHalves(Option<u32>),
SixteenBytes(Option<u32>),
OneDouble(Option<u32>),
TwoSingles(Option<u32>),
FourHalves(Option<u32>),
EightBytes(Option<u32>),
OneSingle(Option<u32>),
TwoHalves(Option<u32>),
FourBytes(Option<u32>),
OneHalf(Option<u32>),
OneByte(Option<u32>),
}
#[allow(non_upper_case_globals)]
#[doc(hidden)]
impl TryFrom<&bad64_sys::InstructionOperand> for ArrSpec {
type Error = ();
fn try_from(oo: &bad64_sys::InstructionOperand) -> Result<Self, Self::Error> {
let lane = match oo.laneUsed {
true => Some(oo.lane),
false => None,
};
match oo.arrSpec {
ArrangementSpec::ARRSPEC_FULL => Ok(ArrSpec::Full(lane)),
ArrangementSpec::ARRSPEC_2DOUBLES => Ok(ArrSpec::TwoDoubles(lane)),
ArrangementSpec::ARRSPEC_4SINGLES => Ok(ArrSpec::FourSingles(lane)),
ArrangementSpec::ARRSPEC_8HALVES => Ok(ArrSpec::EightHalves(lane)),
ArrangementSpec::ARRSPEC_16BYTES => Ok(ArrSpec::SixteenBytes(lane)),
ArrangementSpec::ARRSPEC_1DOUBLE => Ok(ArrSpec::OneDouble(lane)),
ArrangementSpec::ARRSPEC_2SINGLES => Ok(ArrSpec::TwoSingles(lane)),
ArrangementSpec::ARRSPEC_4HALVES => Ok(ArrSpec::FourHalves(lane)),
ArrangementSpec::ARRSPEC_8BYTES => Ok(ArrSpec::EightBytes(lane)),
ArrangementSpec::ARRSPEC_1SINGLE => Ok(ArrSpec::OneSingle(lane)),
ArrangementSpec::ARRSPEC_2HALVES => Ok(ArrSpec::TwoHalves(lane)),
ArrangementSpec::ARRSPEC_4BYTES => Ok(ArrSpec::FourBytes(lane)),
ArrangementSpec::ARRSPEC_1HALF => Ok(ArrSpec::OneHalf(lane)),
ArrangementSpec::ARRSPEC_1BYTE => Ok(ArrSpec::OneByte(lane)),
ArrangementSpec::ARRSPEC_NONE => Err(()),
}
}
}
impl ArrSpec {
pub fn lane(&self) -> Option<u32> {
match *self {
Self::Full(lane)
| Self::TwoDoubles(lane)
| Self::OneDouble(lane)
| Self::FourSingles(lane)
| Self::TwoSingles(lane)
| Self::OneSingle(lane)
| Self::EightHalves(lane)
| Self::FourHalves(lane)
| Self::TwoHalves(lane)
| Self::OneHalf(lane)
| Self::SixteenBytes(lane)
| Self::EightBytes(lane)
| Self::FourBytes(lane)
| Self::OneByte(lane) => lane,
}
}
pub fn suffix(&self, reg: Reg) -> &'static str {
let is_sve = reg.is_sve();
let is_pred = reg.is_pred();
if !reg.is_simd() && !is_sve && !is_pred {
return "";
}
if self.lane().is_some() || is_sve || is_pred {
return match *self {
Self::Full(_) => ".q",
Self::TwoDoubles(_) | Self::OneDouble(_) => ".d",
Self::FourSingles(_) | Self::TwoSingles(_) | Self::OneSingle(_) => ".s",
Self::EightHalves(_)
| Self::FourHalves(_)
| Self::TwoHalves(_)
| Self::OneHalf(_) => ".h",
Self::SixteenBytes(_)
| Self::EightBytes(_)
| Self::FourBytes(_)
| Self::OneByte(_) => ".b",
};
}
match *self {
Self::Full(_) => ".1q",
Self::TwoDoubles(_) => ".2d",
Self::OneDouble(_) => ".1d",
Self::FourSingles(_) => ".4s",
Self::TwoSingles(_) => ".2s",
Self::OneSingle(_) => ".1s",
Self::EightHalves(_) => ".8h",
Self::FourHalves(_) => ".4h",
Self::TwoHalves(_) => ".2h",
Self::OneHalf(_) => ".1h",
Self::SixteenBytes(_) => ".16b",
Self::EightBytes(_) => ".8b",
Self::FourBytes(_) => ".4b",
Self::OneByte(_) => ".1b",
}
}
}