|
2 | 2 | (provide compile-op0 compile-op1 compile-op2 compile-op3 pad-stack assert-cons)
|
3 | 3 | (require "ast.rkt")
|
4 | 4 | (require "types.rkt")
|
| 5 | +(require "assert.rkt") |
5 | 6 | (require a86/ast)
|
6 | 7 |
|
7 | 8 | (define rax 'rax)
|
|
44 | 45 | (Sar rax char-shift)
|
45 | 46 | (Sal rax int-shift))]
|
46 | 47 | ['integer->char
|
47 |
| - (seq (assert-codepoint) |
| 48 | + (seq (assert-codepoint rax) |
48 | 49 | (Sar rax int-shift)
|
49 | 50 | (Sal rax char-shift)
|
50 | 51 | (Xor rax type-char))]
|
51 | 52 | ['eof-object?
|
52 | 53 | (seq (Cmp rax (value->bits eof))
|
53 | 54 | if-equal)]
|
54 | 55 | ['write-byte
|
55 |
| - (seq assert-byte |
| 56 | + (seq (assert-byte rax) |
56 | 57 | pad-stack
|
57 | 58 | (Mov rdi rax)
|
58 | 59 | (Call 'write_byte)
|
|
64 | 65 | (Add rbx 8))]
|
65 | 66 | ['unbox
|
66 | 67 | (seq (assert-box rax)
|
67 |
| - (Xor rax type-box) |
68 |
| - (Mov rax (Offset rax 0)))] |
| 68 | + (Mov rax (Offset rax (- type-box))))] |
69 | 69 | ['car
|
70 | 70 | (seq (assert-cons rax)
|
71 |
| - (Xor rax type-cons) |
72 |
| - (Mov rax (Offset rax 8)))] |
| 71 | + (Mov rax (Offset rax (- 8 type-cons))))] |
73 | 72 | ['cdr
|
74 | 73 | (seq (assert-cons rax)
|
75 |
| - (Xor rax type-cons) |
76 |
| - (Mov rax (Offset rax 0)))] |
| 74 | + (Mov rax (Offset rax (- type-cons))))] |
77 | 75 |
|
78 | 76 | ['empty? (seq (Cmp rax (value->bits '())) if-equal)]
|
79 | 77 | ['cons? (type-pred ptr-mask type-cons)]
|
|
84 | 82 | (let ((zero (gensym))
|
85 | 83 | (done (gensym)))
|
86 | 84 | (seq (assert-vector rax)
|
87 |
| - (Xor rax type-vect) |
88 |
| - (Cmp rax 0) |
| 85 | + (Cmp rax type-vect) |
89 | 86 | (Je zero)
|
90 |
| - (Mov rax (Offset rax 0)) |
| 87 | + (Mov rax (Offset rax (- type-vect))) |
91 | 88 | (Sal rax int-shift)
|
92 | 89 | (Jmp done)
|
93 | 90 | (Label zero)
|
|
97 | 94 | (let ((zero (gensym))
|
98 | 95 | (done (gensym)))
|
99 | 96 | (seq (assert-string rax)
|
100 |
| - (Xor rax type-str) |
101 |
| - (Cmp rax 0) |
| 97 | + (Cmp rax type-str) |
102 | 98 | (Je zero)
|
103 |
| - (Mov rax (Offset rax 0)) |
| 99 | + (Mov rax (Offset rax (- type-str))) |
104 | 100 | (Sal rax int-shift)
|
105 | 101 | (Jmp done)
|
106 | 102 | (Label zero)
|
|
270 | 266 | (Mov (Offset r8 8) rax)
|
271 | 267 | (Mov rax (value->bits (void))))]))
|
272 | 268 |
|
| 269 | +(define (type-pred mask type) |
| 270 | + (seq (And rax mask) |
| 271 | + (Cmp rax type) |
| 272 | + if-equal)) |
273 | 273 |
|
274 |
| -;; -> Asm |
| 274 | +;; Asm |
275 | 275 | ;; set rax to #t or #f if comparison flag is equal
|
276 | 276 | (define if-equal
|
277 | 277 | (seq (Mov rax (value->bits #f))
|
278 | 278 | (Mov r9 (value->bits #t))
|
279 | 279 | (Cmove rax r9)))
|
280 | 280 |
|
281 |
| -;; -> Asm |
| 281 | +;; Asm |
282 | 282 | ;; set rax to #t or #f if comparison flag is less than
|
283 | 283 | (define if-lt
|
284 | 284 | (seq (Mov rax (value->bits #f))
|
285 | 285 | (Mov r9 (value->bits #t))
|
286 | 286 | (Cmovl rax r9)))
|
287 | 287 |
|
288 |
| -(define (assert-type mask type) |
289 |
| - (λ (arg) |
290 |
| - (seq (Mov r9 arg) |
291 |
| - (And r9 mask) |
292 |
| - (Cmp r9 type) |
293 |
| - (Jne 'err)))) |
294 |
| - |
295 |
| -(define (type-pred mask type) |
296 |
| - (seq (And rax mask) |
297 |
| - (Cmp rax type) |
298 |
| - if-equal)) |
299 |
| - |
300 |
| -(define assert-integer |
301 |
| - (assert-type mask-int type-int)) |
302 |
| -(define assert-char |
303 |
| - (assert-type mask-char type-char)) |
304 |
| -(define assert-box |
305 |
| - (assert-type ptr-mask type-box)) |
306 |
| -(define assert-cons |
307 |
| - (assert-type ptr-mask type-cons)) |
308 |
| -(define assert-vector |
309 |
| - (assert-type ptr-mask type-vect)) |
310 |
| -(define assert-string |
311 |
| - (assert-type ptr-mask type-str)) |
312 |
| - |
313 |
| -(define (assert-codepoint) |
314 |
| - (let ((ok (gensym))) |
315 |
| - (seq (assert-integer rax) |
316 |
| - (Cmp rax (value->bits 0)) |
317 |
| - (Jl 'err) |
318 |
| - (Cmp rax (value->bits 1114111)) |
319 |
| - (Jg 'err) |
320 |
| - (Cmp rax (value->bits 55295)) |
321 |
| - (Jl ok) |
322 |
| - (Cmp rax (value->bits 57344)) |
323 |
| - (Jg ok) |
324 |
| - (Jmp 'err) |
325 |
| - (Label ok)))) |
326 |
| - |
327 |
| -(define assert-byte |
328 |
| - (seq (assert-integer rax) |
329 |
| - (Cmp rax (value->bits 0)) |
330 |
| - (Jl 'err) |
331 |
| - (Cmp rax (value->bits 255)) |
332 |
| - (Jg 'err))) |
333 |
| - |
334 |
| -(define (assert-natural r) |
335 |
| - (seq (assert-integer r) |
336 |
| - (Cmp r (value->bits 0)) |
337 |
| - (Jl 'err))) |
338 | 288 |
|
339 | 289 | ;; Asm
|
340 | 290 | ;; Dynamically pad the stack to be aligned for a call
|
|
0 commit comments