|
7 | 7 | ;; with decent error messages. |
8 | 8 |
|
9 | 9 | (define check:label-symbol |
10 | | - (λ (x n) |
| 10 | + (λ (a x n) |
11 | 11 | (when (register? x) |
12 | 12 | (error n "cannot use register as label name; given ~v" x)) |
13 | 13 | (unless (symbol? x) |
14 | 14 | (error n "expects symbol; given ~v" x)) |
15 | 15 | (unless (label? x) |
16 | 16 | (error n "label names must conform to nasm restrictions")) |
17 | | - x)) |
| 17 | + (values a x))) |
18 | 18 |
|
19 | 19 | (define check:label-symbol+integer |
20 | | - (λ (x c n) |
| 20 | + (λ (a x c n) |
21 | 21 | (check:label-symbol x n) |
22 | 22 | (unless (integer? c) |
23 | 23 | (error n "expects integer constant; given ~v" c)) |
24 | | - (values x c))) |
| 24 | + (values a x c))) |
25 | 25 |
|
26 | 26 | (define check:target |
27 | | - (λ (x n) |
| 27 | + (λ (a x n) |
28 | 28 | (unless (or (symbol? x) (offset? x)); either register or label |
29 | 29 | (error n "expects symbol; given ~v" x)) |
30 | | - x)) |
| 30 | + (values a x))) |
31 | 31 |
|
32 | 32 | (define check:arith |
33 | | - (λ (a1 a2 n) |
| 33 | + (λ (a a1 a2 n) |
34 | 34 | (unless (register? a1) |
35 | 35 | (error n "expects register; given ~v" a1)) |
36 | 36 | (unless (or (exact-integer? a2) (register? a2) (offset? a2)) |
37 | 37 | (error n "expects exact integer, register, or offset; given ~v" a2)) |
38 | 38 | (when (and (exact-integer? a2) (> (integer-length a2) 32)) |
39 | 39 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2))) |
40 | | - (values a1 a2))) |
| 40 | + (values a a1 a2))) |
41 | 41 |
|
42 | 42 | (define check:register |
43 | | - (λ (a1 n) |
| 43 | + (λ (a a1 n) |
44 | 44 | (unless (register? a1) |
45 | 45 | (error n "expects register; given ~v" a1)) |
46 | | - a1)) |
| 46 | + (values a a1))) |
47 | 47 |
|
48 | 48 | (define check:src-dest |
49 | | - (λ (a1 a2 n) |
| 49 | + (λ (a a1 a2 n) |
50 | 50 | (unless (or (register? a1) (offset? a1)) |
51 | 51 | (error n "expects register or offset; given ~v" a1)) |
52 | 52 | (unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2)) |
|
57 | 57 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2))) |
58 | 58 | (when (and (offset? a1) (exact-integer? a2)) |
59 | 59 | (error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2)) |
60 | | - (values a1 a2))) |
| 60 | + (values a a1 a2))) |
61 | 61 |
|
62 | 62 | (define check:mov |
63 | | - (λ (a1 a2 n) |
| 63 | + (λ (a a1 a2 n) |
64 | 64 | (unless (or (register? a1) (offset? a1)) |
65 | 65 | (error n "expects register or offset; given ~v" a1)) |
66 | 66 | (unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2)) |
|
71 | 71 | (error n "literal must not exceed 64-bits; given ~v (~v bits)" a2 (integer-length a2))) |
72 | 72 | (when (and (offset? a1) (exact-integer? a2)) |
73 | 73 | (error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2)) |
74 | | - (values a1 a2))) |
| 74 | + (values a a1 a2))) |
75 | 75 |
|
76 | 76 | (define check:shift |
77 | | - (λ (a1 a2 n) |
| 77 | + (λ (a a1 a2 n) |
78 | 78 | (unless (register? a1) |
79 | 79 | (error n "expects register; given ~v" a1)) |
80 | 80 | (unless (or (and (exact-integer? a2) (<= 0 a2 63)) |
81 | 81 | (eq? 'cl a2)) |
82 | 82 | (error n "expects exact integer in [0,63]; given ~v" a2)) |
83 | | - (values a1 a2))) |
| 83 | + (values a a1 a2))) |
84 | 84 |
|
85 | 85 | (define check:offset |
86 | | - (λ (r i n) |
| 86 | + (λ (a r i n) |
87 | 87 | (unless (or (register? r) (label? r)) |
88 | 88 | (error n "expects register or label as first argument; given ~v" r)) |
89 | 89 | (unless (exact-integer? i) |
90 | 90 | (error n "expects exact integer as second argument; given ~v" i)) |
91 | | - (values r i))) |
| 91 | + (values a r i))) |
92 | 92 |
|
93 | 93 | (define check:push |
94 | | - (λ (a1 n) |
| 94 | + (λ (a a1 n) |
95 | 95 | (unless (or (exact-integer? a1) (register? a1)) |
96 | 96 | (error n "expects exact integer or register; given ~v" a1)) |
97 | 97 | (when (and (exact-integer? a1) (> (integer-length a1) 32)) |
98 | 98 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a1 (integer-length a1))) |
99 | | - a1)) |
| 99 | + (values a a1))) |
100 | 100 |
|
101 | 101 | (define check:lea |
102 | | - (λ (dst x n) |
| 102 | + (λ (a dst x n) |
103 | 103 | (unless (or (register? dst) (offset? dst)) |
104 | 104 | (error n "expects register or offset; given ~v" dst)) |
105 | 105 | (unless (or (label? x) (offset? x) (exp? x)) |
106 | 106 | (error n "expects label, offset, or expression; given ~v" x)) |
107 | | - (values dst x))) |
| 107 | + (values a dst x))) |
108 | 108 |
|
109 | 109 | (define check:none |
110 | | - (λ (n) (values))) |
| 110 | + (λ (a n) (values a))) |
111 | 111 |
|
112 | 112 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
113 | 113 | ;; Comments |
|
132 | 132 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
133 | 133 | ;; Instructions |
134 | 134 |
|
135 | | -(define-syntax-rule |
136 | | - (instruct Name (x ...) guard) |
137 | | - (begin (provide (struct-out Name)) |
138 | | - (struct Name (x ...) |
139 | | - #:transparent |
140 | | - #:guard guard))) |
| 135 | +(require racket/struct) |
| 136 | +(define current-annotation (make-parameter #f)) |
| 137 | +(provide instruction-annotation current-annotation) |
| 138 | + |
| 139 | +(struct instruction (annotation)) |
| 140 | + |
| 141 | +(define-syntax (instruct stx) |
| 142 | + (syntax-case stx () |
| 143 | + [(instruct Name (x ...) guard) |
| 144 | + (with-syntax ([Name? (datum->syntax stx (string->symbol (string-append (symbol->string (syntax->datum #'Name)) "?")))]) |
| 145 | + #'(begin (provide Name Name?) |
| 146 | + (define-match-expander Name |
| 147 | + (lambda (stx) |
| 148 | + (syntax-case stx () |
| 149 | + [(_ elts (... ...)) |
| 150 | + #'(%Name _ elts (... ...))])) |
| 151 | + (lambda (stx) |
| 152 | + (syntax-case stx () |
| 153 | + [m (identifier? #'m) #'(λ (x ...) (%Name (current-annotation) x ...))] |
| 154 | + [(m x ...) #'(%Name (current-annotation) x ...)]))) |
| 155 | + (struct %Name instruction (x ...) |
| 156 | + #:transparent |
| 157 | + #:guard guard |
| 158 | + #:methods gen:equal+hash |
| 159 | + [(define equal-proc (λ (i1 i2 equal?) |
| 160 | + (equal? (struct->vector i1) |
| 161 | + (struct->vector i2)))) |
| 162 | + (define hash-proc (λ (i hash) (hash (struct->vector i)))) |
| 163 | + (define hash2-proc (λ (i hash) (hash (struct->vector i))))] |
| 164 | + #:methods gen:custom-write |
| 165 | + [(define write-proc |
| 166 | + (make-constructor-style-printer |
| 167 | + (lambda (obj) 'Name) |
| 168 | + (lambda (obj) |
| 169 | + (rest (rest (vector->list (struct->vector obj)))))))]) |
| 170 | + (define Name? %Name?)))])) |
141 | 171 |
|
142 | 172 | (instruct Text () check:none) |
143 | 173 | (instruct Data () check:none) |
|
167 | 197 | (instruct Lea (dst x) check:lea) |
168 | 198 | (instruct Div (den) check:register) |
169 | 199 |
|
170 | | -(instruct Offset (r i) check:offset) |
| 200 | +(instruct Offset (r i) check:offset) ;; May need to make this not an instruction |
171 | 201 | (instruct Extern (x) check:label-symbol) |
172 | 202 |
|
173 | 203 | (instruct Equ (x v) check:label-symbol+integer) |
174 | 204 | (instruct Const (x) check:label-symbol) |
175 | 205 |
|
176 | 206 | ;; IMPROVE: do more checking |
177 | | -(instruct Dd (x) (lambda (x n) x)) |
178 | | -(instruct Dq (x) (lambda (x n) x)) |
| 207 | +(instruct Dd (x) (lambda (a x n) (values a x))) |
| 208 | +(instruct Dq (x) (lambda (a x n) (values a x))) |
179 | 209 |
|
180 | 210 | (provide (struct-out Plus)) |
181 | 211 | (struct Plus (e1 e2) #:transparent) |
|
210 | 240 | (nasm-label? x) |
211 | 241 | (not (register? x)))) |
212 | 242 |
|
| 243 | +#; |
213 | 244 | (define (instruction? x) |
214 | 245 | (or (Text? x) |
215 | 246 | (Data? x) |
|
0 commit comments