aarchmrs_parser/
instructions.rs1use serde::Deserialize;
12
13#[derive(Debug, Deserialize)]
14pub struct Instructions {
15 pub instructions: Vec<InstructionSet>,
16 pub _meta: Meta,
17}
18
19#[derive(Debug, Deserialize)]
20pub struct Meta {
21 pub license: License,
22}
23
24#[derive(Debug, Deserialize)]
25pub struct License {
26 pub copyright: String,
27 pub info: String,
28}
29
30#[derive(Debug, Deserialize)]
31pub struct InstructionSet {
32 pub children: Vec<InstructionGroupOrInstruction>,
33 pub encoding: Encodeset,
34 pub name: String,
35}
36
37#[derive(Debug, Deserialize)]
38pub struct InstructionGroup {
39 pub children: Vec<InstructionGroupOrInstruction>,
40 pub encoding: Encodeset,
41 pub name: String,
42}
43
44#[derive(Debug, Deserialize)]
45#[serde(tag = "_type")]
46pub enum InstructionGroupOrInstruction {
47 #[serde(rename = "Instruction.InstructionGroup")]
48 InstructionGroup(InstructionGroup),
49 #[serde(rename = "Instruction.Instruction")]
50 Instruction(Instruction),
51 #[serde(rename = "Instruction.InstructionAlias")]
52 InstructionAlias(InstructionAlias),
53}
54
55#[derive(Debug, Deserialize)]
56pub struct Encodeset {
57 pub values: Vec<Encode>,
58}
59
60impl<'a> IntoIterator for &'a Encodeset {
61 type Item = &'a Encode;
62
63 type IntoIter = std::slice::Iter<'a, Encode>;
64
65 fn into_iter(self) -> Self::IntoIter {
66 self.values.iter()
67 }
68}
69
70#[derive(Debug, Deserialize)]
71#[serde(tag = "_type")]
72pub enum Encode {
73 #[serde(rename = "Instruction.Encodeset.Field")]
74 Field(Field),
75 #[serde(rename = "Instruction.Encodeset.Bits")]
76 Bits(Bits),
77}
78
79#[derive(Debug, Deserialize)]
80pub struct Field {
81 pub name: String,
82 pub range: Range,
83 pub should_be_mask: Value,
84 pub value: Value,
85}
86
87#[derive(Debug, Deserialize)]
88pub struct Bits {
89 pub range: Range,
90 pub should_be_mask: Value,
91 pub value: Value,
92}
93
94#[derive(Copy, Clone, Debug, Deserialize)]
95pub struct Range {
96 pub start: u32,
97 pub width: u32,
98}
99
100impl IntoIterator for Range {
101 type Item = u32;
102
103 type IntoIter = std::ops::Range<u32>;
104
105 fn into_iter(self) -> Self::IntoIter {
106 self.start..(self.start + self.width)
107 }
108}
109
110#[derive(Debug, Deserialize)]
111pub struct Value {
112 pub value: String,
113 }
115
116impl Value {
117 pub fn as_str(&self) -> Option<&str> {
118 if self.value.starts_with('\'') && self.value.ends_with('\'') {
119 let val = self.value.as_str();
120 Some(val.split_at(val.len() - 1).0.split_at(1).1)
121 } else {
122 None
123 }
124 }
125}
126
127#[derive(Debug, Deserialize)]
128pub struct Instruction {
129 pub encoding: Encodeset,
130 pub name: String,
131 pub operation_id: String,
132 #[serde(default)]
133 pub children: Vec<InstructionGroupOrInstruction>,
134}
135
136#[derive(Debug, Deserialize)]
137pub struct InstructionAlias {
138 pub name: String,
140 pub operation_id: String,
141 #[serde(default)]
142 pub children: Vec<InstructionGroupOrInstruction>,
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 fn test_value_as_str_empty() {
151 assert_eq!(Value { value: "''".into() }.as_str(), Some(""));
152 }
153
154 #[test]
155 fn test_value_as_str() {
156 assert_eq!(
157 Value {
158 value: "'000'".into()
159 }
160 .as_str(),
161 Some("000")
162 );
163 }
164}