Skip to main content

citadel_backend/asm/elements/
traits.rs

1//! Trait implementations for asm elements, mainly the Display trait
2
3use std::fmt::Display;
4
5use crate::asm::{elements::{
6    AsmElement, Declaration, Directive, DirectiveType, Instruction, Label, Literal, MemAddr, Opcode, Operand,
7    Register,
8}, utils};
9
10use super::{DataSize, Size, SizedLiteral};
11
12impl Display for AsmElement {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        write!(
15            f,
16            "{}",
17            match self {
18                AsmElement::Label(label) => label.to_string(),
19                AsmElement::Instruction(ins) => ins.to_string(),
20                AsmElement::Directive(dir) => dir.to_string(),
21                AsmElement::Operand(op) => op.to_string(),
22                AsmElement::Declaration(decl) => decl.to_string(),
23            }
24        )
25    }
26}
27
28impl Display for Declaration {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        write!(
31            f,
32            "{}",
33            match self {
34                Declaration::Global(ident) => format!("global {}", ident),
35                Declaration::DefineBytes(ident, lit, terminator) =>
36                    format!("{} db {}{}", ident, lit, match terminator {
37                        Some(terminator) => format!(", {}", terminator),
38                        None => String::new()
39                    }),
40            }
41        )
42    }
43}
44
45impl Display for Label {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        write!(f, "{}:", self.name)
48    }
49}
50
51impl Display for Instruction {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        write!(
54            f,
55            "{}{}",
56            self.opcode,
57            if !self.args.is_empty() {
58                format!(" {}", utils::op_vec_to_string(&self.args))
59            } else {
60                String::new()
61            }
62        )
63    }
64}
65
66impl Display for Directive {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        write!(
69            f,
70            "section .{}",
71            match self._type {
72                DirectiveType::Data => "data",
73                DirectiveType::Rodata => "rodata",
74                DirectiveType::Text => "text",
75            },
76        )
77    }
78}
79
80impl Display for Operand {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        write!(
83            f,
84            "{}",
85            match self {
86                Operand::Register(regis) => regis.to_string(),
87                Operand::MemAddr(addr) => addr.to_string(),
88                Operand::Literal(lit) => lit.to_string(),
89                Operand::SizedLiteral(lit) => lit.to_string(),
90                Operand::Ident(ident) => ident.to_string(),
91            }
92        )
93    }
94}
95
96impl Display for SizedLiteral {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        write!(f, "{} {}", self.1, self.0)
99    }
100}
101
102impl Display for DataSize {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        write!(
105            f,
106            "{}",
107            match self {
108                DataSize::Byte => "byte",
109                DataSize::Word => "word",
110                DataSize::DWord => "dword",
111                DataSize::QWord => "qword",
112            }
113        )
114    }
115}
116
117impl Display for Register {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        write!(
120            f,
121            "{}",
122            match self {
123                Register::Rax => "rax",
124                Register::Rbx => "rbx",
125                Register::Rcx => "rcx",
126                Register::Rdx => "rdx",
127                Register::Rdi => "rdi",
128                Register::Rsi => "rsi",
129                Register::Rbp => "rbp",
130                Register::Rsp => "rsp",
131                Register::R8 => "r8",
132                Register::R9 => "r9",
133                Register::R10 => "r10",
134                Register::R11 => "r11",
135                Register::R12 => "r12",
136                Register::R13 => "r13",
137                Register::R14 => "r14",
138                Register::R15 => "r15",
139
140                Register::Eax => "eax",
141                Register::Ebx => "ebx",
142                Register::Ecx => "ecx",
143                Register::Edx => "edx",
144                Register::Edi => "edi",
145                Register::Esi => "esi",
146                Register::Ebp => "ebp",
147                Register::Esp => "esp",
148                Register::R8d => "r8d",
149                Register::R9d => "r9d",
150                Register::R10d => "r10d",
151                Register::R11d => "r11d",
152                Register::R12d => "r12d",
153                Register::R13d => "r13d",
154                Register::R14d => "r14d",
155                Register::R15d => "r15d",
156
157                Register::Ax => "ax",
158                Register::Bx => "bx",
159                Register::Cx => "cx",
160                Register::Dx => "dx",
161                Register::Di => "di",
162                Register::Si => "si",
163                Register::Bp => "bp",
164                Register::Sp => "sp",
165                Register::R8w => "r8w",
166                Register::R9w => "r9w",
167                Register::R10w => "r10w",
168                Register::R11w => "r11w",
169                Register::R12w => "r12w",
170                Register::R13w => "r13w",
171                Register::R14w => "r14w",
172                Register::R15w => "r15w",
173
174                Register::Al => "al",
175                Register::Bl => "bl",
176                Register::Cl => "cl",
177                Register::Dl => "dl",
178                Register::Sil => "sil",
179                Register::Dil => "dil",
180                Register::Spl => "spl",
181                Register::Bpl => "bpl",
182                Register::R8b => "r8b",
183                Register::R9b => "r9b",
184                Register::R10b => "r10b",
185                Register::R11b => "r11b",
186                Register::R12b => "r12b",
187                Register::R13b => "r13b",
188                Register::R14b => "r14b",
189                Register::R15b => "r15b",
190            }
191        )
192    }
193}
194
195impl Display for MemAddr {
196    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197        write!(
198            f,
199            "[{}]",
200            match self {
201                MemAddr::Register(reg) => reg.to_string(),
202                MemAddr::Literal(lit) => lit.to_string(),
203                MemAddr::RegisterPos(reg, pos) => format!("{}{}", reg, if *pos != 0 {
204                    pos.to_string()
205                } else {
206                    String::new()
207                }),
208                MemAddr::Ident(ident) => ident.to_string(),
209            }
210        )
211    }
212}
213
214impl Display for Literal {
215    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216        write!(
217            f,
218            "{}",
219            match *self {
220                Literal::Int8(int) => int.to_string(),
221                Literal::Int16(int) => int.to_string(),
222                Literal::Int32(int) => int.to_string(),
223                Literal::Int64(int) => int.to_string(),
224                Literal::Float32(float) => float.to_string(),
225                Literal::Float64(float) => float.to_string(),
226            }
227        )
228    }
229}
230
231impl Display for Opcode {
232    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
233        write!(
234            f,
235            "{}",
236            match self {
237                Opcode::Mov => "mov",
238                Opcode::Syscall => "syscall",
239                Opcode::Add => "add",
240                Opcode::Sub => "sub",
241                Opcode::Mul => "mul",
242                Opcode::Div => todo!(),
243                Opcode::And => todo!(),
244                Opcode::Or => todo!(),
245                Opcode::XOr => todo!(),
246                Opcode::Not => todo!(),
247                Opcode::Cmp => todo!(),
248                Opcode::Jmp => "jmp",
249                Opcode::JE => todo!(),
250                Opcode::JNe => todo!(),
251                Opcode::JZ => todo!(),
252                Opcode::JNz => todo!(),
253                Opcode::Call => "call",
254                Opcode::Ret => "ret",
255                Opcode::Push => "push",
256                Opcode::Pop => "pop",
257                Opcode::Shl => todo!(),
258                Opcode::Shr => todo!(),
259                Opcode::Movsb => todo!(),
260                Opcode::Movsw => todo!(),
261                Opcode::Int => todo!(),
262                Opcode::Fadd => todo!(),
263                Opcode::Fsub => todo!(),
264                Opcode::FMul => todo!(),
265                Opcode::FDiv => todo!(),
266                Opcode::FCmp => todo!(),
267                Opcode::FAbs => todo!(),
268                Opcode::Dec => todo!(),
269                Opcode::Inc => todo!(),
270            }
271        )
272    }
273}
274
275impl Size for Register {
276    fn size(&self) -> u8 {
277        match self {
278            Register::Rax
279            | Register::Rbx
280            | Register::Rcx
281            | Register::Rdx
282            | Register::Rsi
283            | Register::Rdi
284            | Register::Rsp
285            | Register::Rbp
286            | Register::R8
287            | Register::R9
288            | Register::R10
289            | Register::R11
290            | Register::R12
291            | Register::R13
292            | Register::R14
293            | Register::R15 => 64,
294            Register::Eax
295            | Register::Ebx
296            | Register::Ecx
297            | Register::Edx
298            | Register::Edi
299            | Register::Esi
300            | Register::Ebp
301            | Register::Esp
302            | Register::R8d
303            | Register::R9d
304            | Register::R10d
305            | Register::R11d
306            | Register::R12d
307            | Register::R13d
308            | Register::R14d
309            | Register::R15d => 32,
310            Register::Ax
311            | Register::Bx
312            | Register::Cx
313            | Register::Dx
314            | Register::Si
315            | Register::Di
316            | Register::Sp
317            | Register::Bp
318            | Register::R8w
319            | Register::R9w
320            | Register::R10w
321            | Register::R11w
322            | Register::R12w
323            | Register::R13w
324            | Register::R14w
325            | Register::R15w => 16,
326            Register::Al
327            | Register::Bl
328            | Register::Cl
329            | Register::Dl
330            | Register::Sil
331            | Register::Dil
332            | Register::Spl
333            | Register::Bpl
334            | Register::R8b
335            | Register::R9b
336            | Register::R10b
337            | Register::R11b
338            | Register::R12b
339            | Register::R13b
340            | Register::R14b
341            | Register::R15b => 8,
342        }
343    }
344}
345
346impl Size for Operand {
347    fn size(&self) -> u8 {
348        match self {
349            Operand::Ident(_) => todo!(),
350            Operand::Literal(_) => todo!(),
351            Operand::MemAddr(_) => 8,
352            Operand::Register(reg) => reg.size(),
353            Operand::SizedLiteral(lit) => lit.1.size(),
354        }
355    }
356}
357
358impl Size for DataSize {
359    fn size(&self) -> u8 {
360        match self {
361            DataSize::Byte => 1,
362            DataSize::Word => 2,
363            DataSize::DWord => 4,
364            DataSize::QWord => 8,
365        }
366    }
367}