1use proc_macro2::Span;
8use crate::common::Jump;
9use super::riscvdata::Opdata;
10
11use std::fmt;
12
13
14#[derive(Debug, Clone)]
16pub enum Register {
17 Static(RegId),
18 Dynamic(RegFamily, syn::Expr)
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub enum RegId {
24 X0 = 0x00, X1 = 0x01, X2 = 0x02, X3 = 0x03, X4 = 0x04, X5 = 0x05, X6 = 0x06, X7 = 0x07, X8 = 0x08, X9 = 0x09, X10= 0x0A, X11= 0x0B, X12= 0x0C, X13= 0x0D, X14= 0x0E, X15= 0x0F, X16= 0x10, X17= 0x11, X18= 0x12, X19= 0x13, X20= 0x14, X21= 0x15, X22= 0x16, X23= 0x17, X24= 0x18, X25= 0x19, X26= 0x1A, X27= 0x1B, X28= 0x1C, X29= 0x1D, X30= 0x1E, X31= 0x1F, F0 = 0x20, F1 = 0x21, F2 = 0x22, F3 = 0x23,
36 F4 = 0x24, F5 = 0x25, F6 = 0x26, F7 = 0x27,
37 F8 = 0x28, F9 = 0x29, F10= 0x2A, F11= 0x2B,
38 F12= 0x2C, F13= 0x2D, F14= 0x2E, F15= 0x2F,
39 F16= 0x30, F17= 0x31, F18= 0x32, F19= 0x33,
40 F20= 0x34, F21= 0x35, F22= 0x36, F23= 0x37,
41 F24= 0x38, F25= 0x39, F26= 0x3A, F27= 0x3B,
42 F28= 0x3C, F29= 0x3D, F30= 0x3E, F31= 0x3F,
43
44 V0 = 0x40, V1 = 0x41, V2 = 0x42, V3 = 0x43,
46 V4 = 0x44, V5 = 0x45, V6 = 0x46, V7 = 0x47,
47 V8 = 0x48, V9 = 0x49, V10= 0x4A, V11= 0x4B,
48 V12= 0x4C, V13= 0x4D, V14= 0x4E, V15= 0x4F,
49 V16= 0x50, V17= 0x51, V18= 0x52, V19= 0x53,
50 V20= 0x54, V21= 0x55, V22= 0x56, V23= 0x57,
51 V24= 0x58, V25= 0x59, V26= 0x5A, V27= 0x5B,
52 V28= 0x5C, V29= 0x5D, V30= 0x5E, V31= 0x5F,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub enum RegFamily {
58 INTEGER = 0,
59 FP = 1,
60 VECTOR = 2,
61}
62
63impl RegId {
64 pub fn code(self) -> u8 {
66 self as u8 & 0x1F
67 }
68
69 pub fn family(self) -> RegFamily {
71 match self as u8 >> 5 {
72 0 => RegFamily::INTEGER,
73 1 => RegFamily::FP,
74 2 => RegFamily::VECTOR,
75 _ => unreachable!(),
76 }
77 }
78}
79
80impl fmt::Display for RegId {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 match self.family() {
83 RegFamily::INTEGER => write!(f, "x{}", self.code()),
84 RegFamily::FP => write!(f, "f{}", self.code()),
85 RegFamily::VECTOR => write!(f, "v{}", self.code()),
86 }
87 }
88}
89
90impl Register {
91 pub fn code(&self) -> Option<u8> {
93 match self {
94 Register::Static(code) => Some(code.code()),
95 Register::Dynamic(_, _) => None
96 }
97 }
98
99 pub fn family(&self) -> RegFamily {
101 match self {
102 Register::Static(code) => code.family(),
103 Register::Dynamic(family, _) => *family
104 }
105 }
106
107 pub fn is_dynamic(&self) -> bool {
109 match self {
110 Register::Static(_) => false,
111 Register::Dynamic(_, _) => true
112 }
113 }
114
115 pub fn as_id(&self) -> Option<RegId> {
117 match self {
118 Register::Static(id) => Some(*id),
119 Register::Dynamic(_, _) => None
120 }
121 }
122}
123
124
125#[derive(Debug)]
126pub enum RegListCount {
127 Static(u8),
128 Dynamic(syn::Expr),
129 Single(Register),
130 Double(Register, Register)
131}
132
133
134#[derive(Debug)]
146pub enum RawArg {
147 Immediate {
149 value: syn::Expr
150 },
151 JumpTarget {
153 jump: Jump
154 },
155 Register {
157 span: Span,
158 reg: Register
159 },
160 Reference {
162 span: Span,
163 offset: Option<syn::Expr>,
164 base: Register,
165 },
166 LabelReference {
168 span: Span,
169 jump: Jump,
170 base: Register
171 },
172 RegisterList {
174 span: Span,
175 first: Register, count: RegListCount
177 },
178}
179
180#[derive(Debug)]
182pub struct ParsedInstruction {
183 pub name: String,
184 pub span: Span,
185 pub args: Vec<RawArg>
186}
187
188#[derive(Debug)]
189pub enum RegListFlat {
190 Static(u8),
191 Dynamic(syn::Expr)
192}
193
194#[derive(Debug)]
195pub enum FlatArg {
196 Immediate {
197 value: syn::Expr
198 },
199 JumpTarget {
200 jump: Jump
201 },
202 Register {
203 span: Span,
204 reg: Register
205 },
206 RegisterList {
207 span: Span,
208 count: RegListFlat
209 },
210 Default
211}
212
213#[derive(Debug)]
215pub struct MatchData {
216 pub data: &'static Opdata,
217 pub args: Vec<FlatArg>
218}