]>
Witch of Git - ivy/blob - src/trans/x64.rs
1 use crate::trans
::{FnName
, Func
, Program
};
7 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
50 pub struct Definition
{
60 pub fn write_compile(out
: &mut impl Write
, prog
: &Program
) -> io
::Result
<()> {
61 let (entry
, globals
, defns
) = compile(&prog
);
62 writeln
!(out
, ".data")?
;
63 for global
in globals
{
64 writeln
!(out
, "{}", global
)?
;
81 writeln
!(out
, "{}", defn
)?
;
86 pub fn compile(prog
: &Program
) -> (Label
, Vec
<Global
>, Vec
<Definition
>) {
90 .map(|&global
| Global
{
91 name
: Label
::Global(global
),
98 .map(|func
| compile_func(prog
, func
))
100 (Label
::Function(prog
.top
), globals
, defns
)
103 fn compile_func(prog
: &Program
, func
: &Func
) -> Definition
{
104 let mut body
= Vec
::new();
105 body
.push(Inst
::Ret
);
107 name
: Label
::Function(func
.name
),
112 impl fmt
::Display
for Definition
{
113 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
114 match self.body
.len() {
115 0 => write
!(fmt
, "{}:", self.name
),
116 1 => write
!(fmt
, "{}: {}", self.name
, self.body
[0]),
118 writeln
!(fmt
, "{}:", self.name
)?
;
119 for inst
in &self.body
[..len
- 1] {
120 writeln
!(fmt
, " {}", inst
)?
;
122 write
!(fmt
, " {}", self.body
.last().unwrap
())
128 impl fmt
::Display
for Global
{
129 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
130 write
!(fmt
, "{}: .quad {}", self.name
, self.value
)
134 impl fmt
::Display
for Label
{
135 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
137 Label
::Global(g
) => write
!(fmt
, "IVY_GLOBAL${}", g
),
138 Label
::Function(f
) => write
!(fmt
, "ivy_fn${}", f
.0),
143 impl fmt
::Display
for Reg
{
144 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
146 Reg
::Rax
=> write
!(fmt
, "rax"),
147 Reg
::Rbx
=> write
!(fmt
, "rbx"),
148 Reg
::Rcx
=> write
!(fmt
, "rcx"),
149 Reg
::Rdx
=> write
!(fmt
, "rdx"),
150 Reg
::Rsi
=> write
!(fmt
, "rsi"),
151 Reg
::Rdi
=> write
!(fmt
, "rdi"),
152 Reg
::Rbp
=> write
!(fmt
, "rbp"),
153 Reg
::Rsp
=> write
!(fmt
, "rsp"),
154 Reg
::R8
=> write
!(fmt
, "r8"),
155 Reg
::R9
=> write
!(fmt
, "r9"),
156 Reg
::R10
=> write
!(fmt
, "r10"),
157 Reg
::R11
=> write
!(fmt
, "r11"),
158 Reg
::R12
=> write
!(fmt
, "r12"),
159 Reg
::R13
=> write
!(fmt
, "r13"),
160 Reg
::R14
=> write
!(fmt
, "r14"),
161 Reg
::R15
=> write
!(fmt
, "r15"),
166 impl fmt
::Display
for Inst
{
167 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
169 Inst
::Push(r
) => write
!(fmt
, "push {}", r
),
170 Inst
::Pop(r
) => write
!(fmt
, "pop {}", r
),
171 Inst
::Ret
=> write
!(fmt
, "ret"),
172 inst
=> write
!(fmt
, "{:?}", inst
),