]> Witch of Git - ivy/blob - rt/example.s
Add runtime library and example assembly
[ivy] / rt / example.s
1 // clang -masm=intel -nostdlib -Ltarget/release -lrt -lSystem -Wl,-e,_start -g example.s -o target/example
2
3 .data
4 ZERO: .zero 8
5 SUCC: .zero 8
6 ADD: .zero 8
7 MUL: .zero 8
8 DEBUG: .zero 8
9
10 .text
11 .global _start
12 _start:
13 // Align the stack
14 sub rsp, 64
15 and spl, 0xF0
16
17 lea rdi, [rip + zero]
18 mov rsi, 2
19 mov rdx, 0
20 call _ivy_make_lam
21 mov [rip + ZERO], rax
22 mov rdi, rax
23 call _ivy_incref
24
25 lea rdi, [rip + succ]
26 mov rsi, 3
27 mov rdx, 0
28 call _ivy_make_lam
29 mov [rip + SUCC], rax
30 mov rdi, rax
31 call _ivy_incref
32
33 lea rdi, [rip + add]
34 mov rsi, 4
35 mov rdx, 0
36 call _ivy_make_lam
37 mov [rip + ADD], rax
38 mov rdi, rax
39 call _ivy_incref
40
41 lea rdi, [rip + mul]
42 mov rsi, 4
43 mov rdx, 0
44 call _ivy_make_lam
45 mov [rip + MUL], rax
46 mov rdi, rax
47 call _ivy_incref
48
49 lea rdi, [rip + debug]
50 mov rsi, 1
51 mov rdx, 0
52 call _ivy_make_lam
53 mov [rip + DEBUG], rax
54 mov rdi, rax
55 call _ivy_incref
56
57 main:
58 mov rdi, [rip + SUCC]
59 mov rsi, [rip + ZERO]
60 call _ivy_app // succ zero
61 mov rdi, [rip + SUCC]
62 mov rsi, rax
63 call _ivy_app // succ (succ zero)
64 // RAX contains Church #2
65 mov [rsp], rax // 2 := succ (succ zero)
66 mov rdi, [rip + ADD]
67 mov rsi, rax
68 call _ivy_app // add 2
69 mov rdi, rax
70 mov rsi, [rsp]
71 call _ivy_app // add 2 2
72 mov [rsp], rax
73 // RAX contains Church #4
74 mov rdi, [rip + MUL]
75 mov rsi, rax
76 call _ivy_app // mul (add 2 2)
77 mov rdi, rax
78 mov rsi, [rsp]
79 call _ivy_app // 16 := mul (add 2 2) (add 2 2)
80 mov rdi, [rip + MUL]
81 mov rsi, rax
82 call _ivy_app // mul (add 2 2)
83 mov rdi, rax
84 mov rsi, [rsp]
85 call _ivy_app // 64 := mul (add 2 2) 16
86 // RAX contains Church #16
87 mov rdi, rax
88 mov rsi, [rip + DEBUG]
89 call _ivy_app // 64 debug
90 mov rdi, rax
91 mov rsi, [rip + ZERO]
92 call _ivy_app // 64 debug zero
93 // This should print out "DBUG <0-addr>" 16 times. I hope.
94
95 mov rdi, 0
96 call _exit
97
98 /*
99 let
100 zero = lam (f x) => x;
101 succ = lam (n f x) => f (n f x);
102 add = lam (m n f x) => m f (n f x);
103 mul = lam (m n f x) => m (n f) x;
104 debug = some magic nonsense
105 in let
106 two = succ (succ zero);
107 four = add two two;
108 _64 = mul (mul four four) four
109 in
110 _64 debug zero
111 */
112
113 // \fx.x
114 zero:
115 mov rax, [rdi + (0x18 + 8)]
116 ret
117
118 // \nfx.f(nfx)
119 succ:
120 push rbx
121 mov rbx, rdi
122 mov rdi, [rbx + 0x18]
123 mov rsi, [rbx + (0x18 + 8)]
124 call _ivy_app // nf
125 mov rdi, rax
126 mov rsi, [rbx + (0x18 + 16)
127 call _ivy_app // nfx
128 mov rdi, [rbx + (0x18 + 8)]
129 mov rsi, rax
130 call _ivy_app // f(nfx)
131 pop rbx
132 ret
133
134 // \mnfx.mf(nfx)
135 add:
136 push rbx
137 sub rsp, 16
138 mov rbx, rdi
139 mov rdi, [rbx + 0x18]
140 mov rsi, [rbx + (0x18 + 16)]
141 call _ivy_app // mf
142 mov [rsp], rax
143 mov rdi, [rbx + (0x18 + 8)]
144 mov rsi, [rbx + (0x18 + 16)]
145 call _ivy_app // nf
146 mov rdi, rax
147 mov rsi, [rbx + (0x18 + 24)]
148 call _ivy_app // nfx
149 mov rdi, [rsp]
150 mov rsi, rax
151 call _ivy_app // mf(nfx)
152 add rsp, 16
153 pop rbx
154 ret
155
156 // \mnfx.m(nf)x
157 mul:
158 push rbx
159 mov rbx, rdi
160 mov rdi, [rbx + (0x18 + 8)]
161 mov rsi, [rbx + (0x18 + 16)]
162 call _ivy_app // nf
163 mov rdi, [rbx + 0x18]
164 mov rsi, rax
165 call _ivy_app // m(nf)
166 mov rdi, rax
167 mov rsi, [rbx + (0x18 + 24)]
168 call _ivy_app // m(nf)x
169 pop rbx
170 ret
171
172 // \x.debug x
173 debug:
174 push rbx
175 mov rdi, [rdi + 0x18]
176 call _ivy_debug
177 pop rbx
178 ret