1use 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}