|
5 | 5 | (define rax 'rax) ; return |
6 | 6 | (define rdi 'rdi) ; arg |
7 | 7 | (define r8 'r8) ; scratch in +, - |
8 | | -(define r9 'r9) ; scratch in assert-type |
| 8 | +(define r9 'r9) ; scratch |
9 | 9 | (define r15 'r15) ; stack pad (non-volatile) |
10 | 10 | (define rsp 'rsp) ; stack |
11 | 11 |
|
12 | 12 | ;; Op0 -> Asm |
13 | 13 | (define (compile-op0 p) |
14 | 14 | (match p |
15 | | - ['void (seq (Mov rax val-void))] |
| 15 | + ['void (seq (Mov rax (value->bits (void))))] |
16 | 16 | ['read-byte (seq pad-stack |
17 | 17 | (Call 'read_byte) |
18 | 18 | unpad-stack)] |
|
30 | 30 | (seq (assert-integer rax) |
31 | 31 | (Sub rax (value->bits 1)))] |
32 | 32 | ['zero? |
33 | | - (let ((l1 (gensym))) |
34 | | - (seq (assert-integer rax) |
35 | | - (Cmp rax 0) |
36 | | - (Mov rax val-true) |
37 | | - (Je l1) |
38 | | - (Mov rax val-false) |
39 | | - (Label l1)))] |
40 | | - ['char? (type-pred mask-char type-char)] |
| 33 | + (seq (assert-integer rax) |
| 34 | + (Cmp rax 0) |
| 35 | + (if-equal))] |
| 36 | + ['char? |
| 37 | + (type-pred mask-char type-char)] |
41 | 38 | ['char->integer |
42 | 39 | (seq (assert-char rax) |
43 | 40 | (Sar rax char-shift) |
|
47 | 44 | (Sar rax int-shift) |
48 | 45 | (Sal rax char-shift) |
49 | 46 | (Xor rax type-char))] |
50 | | - ['eof-object? (eq-imm val-eof)] |
| 47 | + ['eof-object? (eq-value eof)] |
51 | 48 | ['write-byte |
52 | 49 | (seq (assert-byte rax) |
53 | 50 | pad-stack |
54 | 51 | (Mov rdi rax) |
55 | 52 | (Call 'write_byte) |
56 | 53 | unpad-stack |
57 | | - (Mov rax val-void))])) |
| 54 | + (Mov rax (value->bits (void))))])) |
58 | 55 |
|
59 | 56 | ;; Op2 -> Asm |
60 | 57 | (define (compile-op2 p) |
|
74 | 71 | (seq (Pop r8) |
75 | 72 | (assert-integer r8) |
76 | 73 | (assert-integer rax) |
77 | | - (Cmp r8 rax) |
78 | | - (Mov rax val-true) |
79 | | - (let ((true (gensym))) |
80 | | - (seq (Jl true) |
81 | | - (Mov rax val-false) |
82 | | - (Label true))))] |
| 74 | + (Cmp r8 rax) |
| 75 | + (if-lt))] |
83 | 76 | ['= |
84 | 77 | (seq (Pop r8) |
85 | 78 | (assert-integer r8) |
86 | 79 | (assert-integer rax) |
87 | 80 | (Cmp r8 rax) |
88 | | - (Mov rax val-true) |
89 | | - (let ((true (gensym))) |
90 | | - (seq (Je true) |
91 | | - (Mov rax val-false) |
92 | | - (Label true))))])) |
| 81 | + (if-equal))])) |
93 | 82 |
|
94 | 83 |
|
95 | 84 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
102 | 91 | (Jne 'raise_error_align)))) |
103 | 92 |
|
104 | 93 | (define (type-pred mask type) |
105 | | - (let ((l (gensym))) |
106 | | - (seq (And rax mask) |
107 | | - (Cmp rax type) |
108 | | - (Mov rax (value->bits #t)) |
109 | | - (Je l) |
110 | | - (Mov rax (value->bits #f)) |
111 | | - (Label l)))) |
| 94 | + (seq (And rax mask) |
| 95 | + (Cmp rax type) |
| 96 | + (if-equal))) |
112 | 97 |
|
113 | 98 | (define assert-integer |
114 | 99 | (assert-type mask-int type-int)) |
|
136 | 121 | (Cmp r (value->bits 255)) |
137 | 122 | (Jg 'raise_error_align))) |
138 | 123 |
|
139 | | -;; Imm -> Asm |
140 | | -(define (eq-imm imm) |
141 | | - (let ((l1 (gensym))) |
142 | | - (seq (Cmp rax imm) |
143 | | - (Mov rax val-true) |
144 | | - (Je l1) |
145 | | - (Mov rax val-false) |
146 | | - (Label l1)))) |
| 124 | +;; -> Asm |
| 125 | +;; set rax to #t or #f based on given comparison |
| 126 | +(define (if-compare c) |
| 127 | + (seq (Mov rax (value->bits #f)) |
| 128 | + (Mov r9 (value->bits #t)) |
| 129 | + (c rax r9))) |
| 130 | + |
| 131 | +(define (if-equal) (if-compare Cmove)) |
| 132 | +(define (if-lt) (if-compare Cmovl)) |
| 133 | + |
| 134 | +;; Value -> Asm |
| 135 | +(define (eq-value v) |
| 136 | + (seq (Cmp rax (value->bits v)) |
| 137 | + (if-equal))) |
147 | 138 |
|
148 | 139 | ;; Asm |
149 | 140 | ;; Dynamically pad the stack to be aligned for a call |
|
0 commit comments