1use std::collections::HashMap;
2
3#[derive(Debug, PartialEq, Clone, Copy)]
4pub enum BaseType {
5 Word,
6 Long,
7 Single,
8 Double,
9}
10
11#[derive(Debug, PartialEq, Clone, Copy)]
12pub enum ExtType {
13 Base(BaseType),
14 Byte,
15 Halfword,
16}
17
18#[derive(Debug, PartialEq, Clone, Copy)]
19pub enum SubWordType {
20 SignedByte,
21 UnsignedByte,
22 SignedHalf,
23 UnsignedHalf,
24}
25
26impl SubWordType {
27 pub fn is_signed(&self) -> bool {
28 match self {
29 SubWordType::SignedByte => true,
30 SubWordType::UnsignedByte => false,
31 SubWordType::SignedHalf => true,
32 SubWordType::UnsignedHalf => false,
33 }
34 }
35}
36
37#[derive(Debug, PartialEq, Clone, Copy)]
38pub enum SubLongType {
39 SubWord(SubWordType),
40 SignedWord,
41 UnsignedWord,
42}
43
44impl SubLongType {
45 pub fn is_signed(&self) -> bool {
46 match self {
47 SubLongType::SubWord(x) => x.is_signed(),
48 SubLongType::SignedWord => true,
49 SubLongType::UnsignedWord => false,
50 }
51 }
52}
53
54#[derive(Debug, PartialEq)]
55pub enum SubType {
56 ExtType(ExtType),
57 UserDef(String),
58}
59
60#[derive(Debug, PartialEq)]
61pub enum Type {
62 Base(BaseType),
63 SubWordType(SubWordType),
64 UserDef(String),
65}
66
67#[derive(Debug, PartialEq, Clone, Copy)]
68pub enum LoadType {
69 Base(BaseType),
70 SubLong(SubLongType),
71}
72
73impl LoadType {
74 pub fn is_signed(&self) -> bool {
75 match self {
76 LoadType::Base(_) => false,
77 LoadType::SubLong(x) => x.is_signed(),
78 }
79 }
80}
81
82#[derive(Debug, PartialEq)]
83pub enum Const {
84 Number(i64),
85 SFP(f32),
86 DFP(f64),
87 Global(String),
88}
89
90#[derive(Debug, PartialEq)]
91pub enum DynConst {
92 Const(Const),
93 Thread(String),
94}
95
96#[derive(Debug, PartialEq)]
97pub enum Linkage {
98 Export,
99 Thread,
100 Section(String, Option<String>),
101}
102
103#[derive(Debug, PartialEq)]
104pub struct TypeDef {
105 pub name: String,
106 pub defn: AggregateType,
107}
108
109#[derive(Debug, PartialEq)]
110pub enum AggregateType {
111 Regular(Option<u64>, Vec<(SubType, u64)>),
112 Opaque(u64, u64),
113}
114
115#[derive(Debug, PartialEq)]
116pub struct DataDef {
117 pub linkage: Vec<Linkage>,
118 pub name: String,
119 pub align: Option<u64>,
120 pub objs: Vec<DataObj>,
121}
122
123#[derive(Debug, PartialEq)]
124pub enum DataObj {
125 DataItem(ExtType, Vec<DataItem>),
126 ZeroFill(u64),
127}
128
129#[derive(Debug, PartialEq)]
130pub enum DataItem {
131 Symbol(String, Option<u64>),
132 String(String),
133 Const(Const),
134}
135
136#[derive(Debug, PartialEq)]
137pub struct FuncDef {
138 pub linkage: Vec<Linkage>,
139 pub name: String,
140 pub abity: Option<Type>,
141 pub params: Vec<FuncParam>,
142 pub body: Vec<Block>,
143}
144
145#[derive(Debug, PartialEq)]
146pub enum FuncParam {
147 Regular(Type, String),
148 Env(String),
149 Variadic,
150}
151
152impl FuncParam {
153 pub fn get_name(&self) -> Option<&str> {
154 match self {
155 FuncParam::Regular(_, n) => Some(n),
156 FuncParam::Env(n) => Some(n),
157 FuncParam::Variadic => None,
158 }
159 }
160}
161
162#[derive(Debug, PartialEq)]
163pub struct Block {
164 pub label: String,
165 pub phi: Vec<Phi>,
166 pub inst: Vec<Statement>,
167 pub jump: Option<JumpInstr>,
168}
169
170#[derive(Debug, PartialEq)]
171pub enum Value {
172 LocalVar(String),
173 Const(DynConst),
174}
175
176#[derive(Debug, PartialEq)]
177pub enum JumpInstr {
178 Jump(String), // jmp
179 Jnz(Value, String, String), // jnz
180 Return(Option<Value>), // ret
181 Halt, // hlt
182}
183
184#[derive(Debug, PartialEq, Clone, Copy)]
185pub enum CmpOp {
186 Eq,
187 Ne,
188 Sle,
189 Slt,
190 Sge,
191 Sgt,
192 Ule,
193 Ult,
194 Uge,
195 Ugt,
196}
197
198#[derive(Debug, PartialEq, Copy, Clone)]
199pub enum AllocAlign {
200 Word, // Align on 4-byte boundary
201 Long, // Align on 8-byte boundary
202 LongLong, // Align on 16-byte boundary
203}
204
205impl AllocAlign {
206 pub fn byte_align(&self) -> u8 {
207 match self {
208 AllocAlign::Word => 4,
209 AllocAlign::Long => 8,
210 AllocAlign::LongLong => 16,
211 }
212 }
213}
214
215#[derive(Debug, PartialEq)]
216pub struct Phi {
217 pub ident: String,
218 pub base_type: BaseType,
219 pub labels: HashMap<String, Value>,
220}
221
222#[derive(Debug, PartialEq)]
223pub enum Instr {
224 // Arithmetic and Bits
225 Add(Value, Value),
226 Sub(Value, Value),
227 Mul(Value, Value),
228 Neg(Value),
229 UDiv(Value, Value),
230 Rem(Value, Value),
231 URem(Value, Value),
232 Or(Value, Value),
233 Xor(Value, Value),
234 And(Value, Value),
235 Sar(Value, Value),
236 Shr(Value, Value),
237 Shl(Value, Value),
238
239 // Memory
240 Load(LoadType, Value),
241
242 // Stack Allocation
243 Alloc(AllocAlign, u64),
244
245 // Comparision
246 Compare(BaseType, CmpOp, Value, Value),
247
248 // Conversions
249 Ext(SubLongType, Value),
250}
251
252#[derive(Debug, PartialEq)]
253pub enum VolatileInstr {
254 Store(ExtType, Value, Value),
255 Blit(Value, Value, u64),
256}
257
258#[derive(Debug, PartialEq)]
259pub enum Statement {
260 Assign(String, BaseType, Instr),
261 Call(String, Type, String, Vec<FuncParam>),
262 Volatile(VolatileInstr),
263}