|
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:cmov |
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 (register? a2) (offset? a2)) |
37 | 37 | (error n "expects register or offset; given ~v" a2)) |
38 | | - (values a1 a2))) |
| 38 | + (values a a1 a2))) |
39 | 39 |
|
40 | 40 | (define check:arith |
41 | | - (λ (a1 a2 n) |
| 41 | + (λ (a a1 a2 n) |
42 | 42 | (unless (register? a1) |
43 | 43 | (error n "expects register; given ~v" a1)) |
44 | 44 | (unless (or (exact-integer? a2) (register? a2) (offset? a2)) |
45 | 45 | (error n "expects exact integer, register, or offset; given ~v" a2)) |
46 | 46 | (when (and (exact-integer? a2) (> (integer-length a2) 32)) |
47 | 47 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2))) |
48 | | - (values a1 a2))) |
| 48 | + (values a a1 a2))) |
49 | 49 |
|
50 | 50 | (define check:register |
51 | | - (λ (a1 n) |
| 51 | + (λ (a a1 n) |
52 | 52 | (unless (register? a1) |
53 | 53 | (error n "expects register; given ~v" a1)) |
54 | | - a1)) |
| 54 | + (values a a1))) |
55 | 55 |
|
56 | 56 | (define check:src-dest |
57 | | - (λ (a1 a2 n) |
| 57 | + (λ (a a1 a2 n) |
58 | 58 | (unless (or (register? a1) (offset? a1)) |
59 | 59 | (error n "expects register or offset; given ~v" a1)) |
60 | 60 | (unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2)) |
|
65 | 65 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2))) |
66 | 66 | (when (and (offset? a1) (exact-integer? a2)) |
67 | 67 | (error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2)) |
68 | | - (values a1 a2))) |
| 68 | + (values a a1 a2))) |
69 | 69 |
|
70 | 70 | (define check:mov |
71 | | - (λ (a1 a2 n) |
| 71 | + (λ (a a1 a2 n) |
72 | 72 | (unless (or (register? a1) (offset? a1)) |
73 | 73 | (error n "expects register or offset; given ~v" a1)) |
74 | 74 | (unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2)) |
|
79 | 79 | (error n "literal must not exceed 64-bits; given ~v (~v bits)" a2 (integer-length a2))) |
80 | 80 | (when (and (offset? a1) (exact-integer? a2)) |
81 | 81 | (error n "cannot use a memory locations and literal; given ~v, ~v; go through a register instead" a1 a2)) |
82 | | - (values a1 a2))) |
| 82 | + (values a a1 a2))) |
83 | 83 |
|
84 | 84 | (define check:shift |
85 | | - (λ (a1 a2 n) |
| 85 | + (λ (a a1 a2 n) |
86 | 86 | (unless (register? a1) |
87 | 87 | (error n "expects register; given ~v" a1)) |
88 | 88 | (unless (or (and (exact-integer? a2) (<= 0 a2 63)) |
89 | 89 | (eq? 'cl a2)) |
90 | 90 | (error n "expects exact integer in [0,63]; given ~v" a2)) |
91 | | - (values a1 a2))) |
| 91 | + (values a a1 a2))) |
92 | 92 |
|
93 | 93 | (define check:offset |
94 | | - (λ (r i n) |
| 94 | + (λ (a r i n) |
95 | 95 | (unless (or (register? r) (label? r)) |
96 | 96 | (error n "expects register or label as first argument; given ~v" r)) |
97 | 97 | (unless (exact-integer? i) |
98 | 98 | (error n "expects exact integer as second argument; given ~v" i)) |
99 | | - (values r i))) |
| 99 | + (values a r i))) |
100 | 100 |
|
101 | 101 | (define check:push |
102 | | - (λ (a1 n) |
| 102 | + (λ (a a1 n) |
103 | 103 | (unless (or (exact-integer? a1) (register? a1)) |
104 | 104 | (error n "expects exact integer or register; given ~v" a1)) |
105 | 105 | (when (and (exact-integer? a1) (> (integer-length a1) 32)) |
106 | 106 | (error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a1 (integer-length a1))) |
107 | | - a1)) |
| 107 | + (values a a1))) |
108 | 108 |
|
109 | 109 | (define check:lea |
110 | | - (λ (dst x n) |
| 110 | + (λ (a dst x n) |
111 | 111 | (unless (or (register? dst) (offset? dst)) |
112 | 112 | (error n "expects register or offset; given ~v" dst)) |
113 | 113 | (unless (or (label? x) (offset? x) (exp? x)) |
114 | 114 | (error n "expects label, offset, or expression; given ~v" x)) |
115 | | - (values dst x))) |
| 115 | + (values a dst x))) |
116 | 116 |
|
117 | 117 | (define check:none |
118 | | - (λ (n) (values))) |
| 118 | + (λ (a n) (values a))) |
119 | 119 |
|
120 | 120 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
121 | 121 | ;; Comments |
|
140 | 140 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
141 | 141 | ;; Instructions |
142 | 142 |
|
143 | | -(define-syntax-rule |
144 | | - (instruct Name (x ...) guard) |
145 | | - (begin (provide (struct-out Name)) |
146 | | - (struct Name (x ...) |
147 | | - #:transparent |
148 | | - #:guard guard))) |
| 143 | +(require racket/struct) |
| 144 | +(define current-annotation (make-parameter #f)) |
| 145 | +(provide instruction-annotation current-annotation) |
| 146 | + |
| 147 | +(struct instruction (annotation)) |
| 148 | + |
| 149 | +(define-syntax (instruct stx) |
| 150 | + (syntax-case stx () |
| 151 | + [(instruct Name (x ...) guard) |
| 152 | + (with-syntax ([Name? (datum->syntax stx (string->symbol (string-append (symbol->string (syntax->datum #'Name)) "?")))]) |
| 153 | + #'(begin (provide Name Name?) |
| 154 | + (define-match-expander Name |
| 155 | + (lambda (stx) |
| 156 | + (syntax-case stx () |
| 157 | + [(_ elts (... ...)) |
| 158 | + #'(%Name _ elts (... ...))])) |
| 159 | + (lambda (stx) |
| 160 | + (syntax-case stx () |
| 161 | + [m (identifier? #'m) #'(λ (x ...) (%Name (current-annotation) x ...))] |
| 162 | + [(m x ...) #'(%Name (current-annotation) x ...)]))) |
| 163 | + (struct %Name instruction (x ...) |
| 164 | + #:transparent |
| 165 | + #:guard guard |
| 166 | + #:methods gen:equal+hash |
| 167 | + [(define equal-proc (λ (i1 i2 equal?) |
| 168 | + (equal? (struct->vector i1) |
| 169 | + (struct->vector i2)))) |
| 170 | + (define hash-proc (λ (i hash) (hash (struct->vector i)))) |
| 171 | + (define hash2-proc (λ (i hash) (hash (struct->vector i))))] |
| 172 | + #:methods gen:custom-write |
| 173 | + [(define write-proc |
| 174 | + (make-constructor-style-printer |
| 175 | + (lambda (obj) 'Name) |
| 176 | + (lambda (obj) |
| 177 | + (rest (rest (vector->list (struct->vector obj)))))))]) |
| 178 | + (define Name? %Name?)))])) |
149 | 179 |
|
150 | 180 | (instruct Text () check:none) |
151 | 181 | (instruct Data () check:none) |
|
190 | 220 | (instruct Not (x) check:register) |
191 | 221 | (instruct Div (den) check:register) |
192 | 222 |
|
193 | | -(instruct Offset (r i) check:offset) |
| 223 | +(instruct Offset (r i) check:offset) ;; May need to make this not an instruction |
194 | 224 | (instruct Extern (x) check:label-symbol) |
195 | 225 |
|
196 | 226 | (instruct Equ (x v) check:label-symbol+integer) |
197 | 227 | (instruct Const (x) check:label-symbol) |
198 | 228 |
|
199 | 229 | ;; IMPROVE: do more checking |
200 | | -(instruct Dd (x) (lambda (x n) x)) |
201 | | -(instruct Dq (x) (lambda (x n) x)) |
| 230 | +(instruct Dd (x) (lambda (a x n) (values a x))) |
| 231 | +(instruct Dq (x) (lambda (a x n) (values a x))) |
202 | 232 |
|
203 | 233 | (provide (struct-out Plus)) |
204 | 234 | (struct Plus (e1 e2) #:transparent) |
|
212 | 242 | (symbol? x) |
213 | 243 | (integer? x))) |
214 | 244 |
|
215 | | -(provide offset? register? instruction? label? 64-bit-integer? 32-bit-integer?) |
| 245 | +(provide offset? register? label? 64-bit-integer? 32-bit-integer?) |
216 | 246 |
|
217 | 247 | (define offset? Offset?) |
218 | 248 |
|
|
233 | 263 | (nasm-label? x) |
234 | 264 | (not (register? x)))) |
235 | 265 |
|
236 | | -(define (instruction? x) |
237 | | - (or (Text? x) |
238 | | - (Data? x) |
239 | | - (Global? x) |
240 | | - (Label? x) |
241 | | - (Extern? x) |
242 | | - (Call? x) |
243 | | - (Ret? x) |
244 | | - (Mov? x) |
245 | | - (Add? x) |
246 | | - (Sub? x) |
247 | | - (Cmp? x) |
248 | | - (Jmp? x) |
249 | | - (Je? x) |
250 | | - (Jne? x) |
251 | | - (Jl? x) |
252 | | - (Jle? x) |
253 | | - (Jg? x) |
254 | | - (Jge? x) |
255 | | - (Jo? x) |
256 | | - (Jno? x) |
257 | | - (Jc? x) |
258 | | - (Jnc? x) |
259 | | - (Cmove? x) |
260 | | - (Cmovne? x) |
261 | | - (Cmovl? x) |
262 | | - (Cmovle? x) |
263 | | - (Cmovg? x) |
264 | | - (Cmovge? x) |
265 | | - (Cmovo? x) |
266 | | - (Cmovno? x) |
267 | | - (Cmovc? x) |
268 | | - (Cmovnc? x) |
269 | | - (And? x) |
270 | | - (Or? x) |
271 | | - (Xor? x) |
272 | | - (Sal? x) |
273 | | - (Sar? x) |
274 | | - (Push? x) |
275 | | - (Pop? x) |
276 | | - (Lea? x) |
277 | | - (Not? x) |
278 | | - (Div? x) |
279 | | - (Comment? x) |
280 | | - (Equ? x) |
281 | | - (Dd? x) |
282 | | - (Dq? x) |
283 | | - )) |
| 266 | +(provide (rename-out [a86:instruction? instruction?])) |
| 267 | +(define (a86:instruction? x) |
| 268 | + (or (instruction? x) |
| 269 | + (Comment? x))) |
284 | 270 |
|
285 | 271 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
286 | 272 | ;; Instruction sequencing and program error checking |
287 | 273 |
|
288 | 274 | (provide/contract |
289 | | - [seq (-> (or/c instruction? (listof instruction?)) ... |
290 | | - (listof instruction?))] |
291 | | - [prog (-> (or/c instruction? (listof instruction?)) ... |
292 | | - (listof instruction?))]) |
| 275 | + [seq (-> (or/c a86:instruction? (listof a86:instruction?)) ... |
| 276 | + (listof a86:instruction?))] |
| 277 | + [prog (-> (or/c a86:instruction? (listof a86:instruction?)) ... |
| 278 | + (listof a86:instruction?))]) |
293 | 279 |
|
294 | 280 | ;; (U Instruction Asm) ... -> Asm |
295 | 281 | ;; Convenient for sequencing instructions or groups of instructions |
|
0 commit comments