aboutsummaryrefslogtreecommitdiff
path: root/uskel.s
blob: dad9bc5ad28808ce97b495566cb4a64cc01a8c6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

.include "macros.s"

.section .init
.global _start
_start:
	jmp _uskel_start

.section .bss
_memory_state:
	cell 0 # next free position
	cell 0 # region start
	cell 0 # region end

.section .text

_uskel_alloc_basic_mem:
	mov $0x100000, %r15 # desired size

	mov $0x9, %rax # mmap
	mov $0, %rdi # addr = NULL
	mov %r15, %rsi # len = %rcx
	mov $0x3, %rdx # prot = PROT_READ 0x1 | PROT_WRITE 0x2
	mov $0x22, %r10 # flags = MAP_PRIVATE 0x2 | MAP_ANONYMOUS 0x20
	mov $-1, %r8 # fd = -1
	mov $0, %r9 # off = 0
	syscall
	mov $_memory_state, %rdi
	mov %rax, (%rdi)
	mov %rax, 0x8(%rdi)
	add %r15, %rax
	mov %rax, 0x10(%rdi)
	retq

_uskel_start:
	call _uskel_alloc_basic_mem
	mov _memory_state, %rdi
	# push a thunk for main
	mov %rdi, %r15 # backup main for later
	movq $main, 0x00(%rdi)
	movq $0, 0x08(%rdi)
	add $0x10, %rdi
	# save the memory ptr
	mov %rdi, _memory_state

	mov $0, %rsi # set continuation to exit
	enter %r15 # run the program

# Simple values and boxed machine integers
# | ptr | value |
CON_evacuate1:
	retq
CON_scavenge1:
	add $0x10, %rsi
	retq
INT_info_table:
	cell CON_evacuate1
	cell CON_scavenge1
	cell 0
INT_code:
	continue

# List
# | ptr | 0 |
# | ptr | 1 | a | b |
LIST_evacuate:
	# [] | a : b
	retq #TODO
LIST_scavenge:
	mov 0x8(%rbp), %rax
	shl $1, %rax
	add $2, %rax
	shl $3, %rax
	add %rax, %rsi
	retq
LIST_info_table:
	cell LIST_evacuate
	cell LIST_scavenge
	cell 0
LIST_code:
	continue

# FUN/PAP combo objects
# | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] |
FUN_evacuate:
	retq #TODO
FUN_scavenge:
	mov 0x10(%rbp), %rax
	add $3, %rax
	shl $3, %rax
	add %rax, %rsi
	retq

# Simple info for n-ary functions
# TODO continue to add as required
fun1_info_table:
	cell FUN_evacuate
	cell FUN_scavenge
	cell 1
fun1_code:
	continue

fun2_info_table:
	cell FUN_evacuate
	cell FUN_scavenge
	cell 2
fun2_code:
	continue

fun3_info_table:
	cell FUN_evacuate
	cell FUN_scavenge
	cell 3
fun3_code:
	continue

# indirection (Q: how to recognize IND and THUNK on return?)
# | ptr | indptr |
IND_evacuate:
	retq #TODO
IND_scavenge:
	add $0x10,%rsi
	retq
IND_info:
	cell IND_evacuate
	cell IND_scavenge
	cell 0
IND_code:
	enter 0x8(%rbp)

# THU objects (gc implementation only, actual THUs are defined by functions)
# | ptr | args | arg[0] | arg[1] | ... | arg[args] |
# args wouldn't need to be here but let's keep them for gc simplicity
THU_evacuate:
	retq #TODO
THU_scavenge:
	mov 0x8(%rbp), %rax
	add $2,%rax
	shl $3,%rax
	add %rax,%rsi
	retq

#
# Actual code!
#

# || -> cont
.makethunk main
	mov _memory_state, %r15

	# push a new integer
	mov %r15, %r11 # backup first arg
	movq $INT_code, 0x00(%r15)
	movq $100, 0x08(%r15)
	add $0x10, %r15

	# push another new integer
	mov %r15, %r12 # backup second arg
	movq $INT_code, 0x00(%r15)
	movq $23, 0x08(%r15)
	add $0x10, %r15

	# push the plus
	mov %r15, %r13 # backup plus
	movq $plus, 0x00(%r15)
	movq $2, 0x08(%r15)
	mov %r11, 0x10(%r15)
	mov %r12, 0x18(%r15)
	add $0x20, %r15

	# push a cont thunk for main_exit
	mov %r15, %r14 # backup cont thunk
	movq $main_exit, 0x00(%r15)
	movq $1, 0x08(%r15)
	mov %rsi, 0x10(%r15)
	add $0x18, %r15

	mov %r15, _memory_state

	# evaluate into main_exit
	mov %r14, %rsi
	enter %r13

# exitcode -> | cont (unused, should be 0) |
.makethunk main_exit
	mov 0x8(%rsi), %rdi
	mov $0x3c, %rax
	syscall # exit %rdi

# | arg1 | arg2 | -> cont
.makethunk plus
	# push a thunk for finishing the plus
	mov _memory_state, %r15
	mov %r15, %r14 # plus_step1 origin
	movq $plus_step1, 0x00(%r15)
	movq $3, 0x08(%r15)
	mov 0x18(%rbp), %rax
	mov %rax, 0x10(%r15)
	mov %rbp, 0x18(%r15)
	mov %rsi, 0x20(%r15)
	add $0x28, %r15
	mov %r15, _memory_state

	# evaluate arg0
	mov %r14, %rsi
	enter 0x10(%rbp)

# arg0 -> | arg1 | ret | cont |
.makethunk plus_step1
	# this is guaranteed to be entered only once (it's a cont), so we can rewrite the thunk in place
	mov 0x10(%rbp), %rax
	movq $plus_fini, 0x00(%rbp)
	mov %rsi, 0x10(%rbp)

	mov %rbp, %rsi # continue on the rewritten thunk
	enter %rax # evaluate arg1

# arg1 -> | arg0 | ret | cont |
.makethunk plus_fini
	mov 0x8(%rsi), %rax # arg1
	mov 0x10(%rbp), %rsi
	add 0x8(%rsi), %rax # + arg0

	mov 0x18(%rbp), %rsi # rewrite the resulting thunk
	movq $INT_code, 0x00(%rsi)
	mov %rax, 0x08(%rsi)
	# result is in rsi already
	enter 0x20(%rbp)

# Q: are there gonna be functions that have both the argument AND the cont?
# A: No, either stuff is entered as return-continuation (takes res) or as forward call (takes cont)
# (needs validation)