Skip to content

Commit 51ea902

Browse files
committed
Merge branch 'instruction-magic'
2 parents 4e1f289 + afb6f43 commit 51ea902

3 files changed

Lines changed: 86 additions & 90 deletions

File tree

langs/a86/ast.rkt

Lines changed: 71 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,27 @@
77
;; with decent error messages.
88

99
(define check:label-symbol
10-
(λ (x n)
10+
(λ (a x n)
1111
(when (register? x)
1212
(error n "cannot use register as label name; given ~v" x))
1313
(unless (symbol? x)
1414
(error n "expects symbol; given ~v" x))
1515
(unless (label? x)
1616
(error n "label names must conform to nasm restrictions"))
17-
x))
17+
(values a x)))
1818

1919
(define check:label-symbol+integer
20-
(λ (x c n)
20+
(λ (a x c n)
2121
(check:label-symbol x n)
2222
(unless (integer? c)
2323
(error n "expects integer constant; given ~v" c))
24-
(values x c)))
24+
(values a x c)))
2525

2626
(define check:target
27-
(λ (x n)
27+
(λ (a x n)
2828
(unless (or (symbol? x) (offset? x)); either register or label
2929
(error n "expects symbol; given ~v" x))
30-
x))
30+
(values a x)))
3131

3232
(define check:cmov
3333
(λ (a1 a2 n)
@@ -38,23 +38,23 @@
3838
(values a1 a2)))
3939

4040
(define check:arith
41-
(λ (a1 a2 n)
41+
(λ (a a1 a2 n)
4242
(unless (register? a1)
4343
(error n "expects register; given ~v" a1))
4444
(unless (or (exact-integer? a2) (register? a2) (offset? a2))
4545
(error n "expects exact integer, register, or offset; given ~v" a2))
4646
(when (and (exact-integer? a2) (> (integer-length a2) 32))
4747
(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)))
4949

5050
(define check:register
51-
(λ (a1 n)
51+
(λ (a a1 n)
5252
(unless (register? a1)
5353
(error n "expects register; given ~v" a1))
54-
a1))
54+
(values a a1)))
5555

5656
(define check:src-dest
57-
(λ (a1 a2 n)
57+
(λ (a a1 a2 n)
5858
(unless (or (register? a1) (offset? a1))
5959
(error n "expects register or offset; given ~v" a1))
6060
(unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2))
@@ -65,10 +65,10 @@
6565
(error n "literal must not exceed 32-bits; given ~v (~v bits); go through a register instead" a2 (integer-length a2)))
6666
(when (and (offset? a1) (exact-integer? a2))
6767
(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)))
6969

7070
(define check:mov
71-
(λ (a1 a2 n)
71+
(λ (a a1 a2 n)
7272
(unless (or (register? a1) (offset? a1))
7373
(error n "expects register or offset; given ~v" a1))
7474
(unless (or (register? a2) (offset? a2) (exact-integer? a2) (Const? a2))
@@ -79,43 +79,43 @@
7979
(error n "literal must not exceed 64-bits; given ~v (~v bits)" a2 (integer-length a2)))
8080
(when (and (offset? a1) (exact-integer? a2))
8181
(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)))
8383

8484
(define check:shift
85-
(λ (a1 a2 n)
85+
(λ (a a1 a2 n)
8686
(unless (register? a1)
8787
(error n "expects register; given ~v" a1))
8888
(unless (or (and (exact-integer? a2) (<= 0 a2 63))
8989
(eq? 'cl a2))
9090
(error n "expects exact integer in [0,63]; given ~v" a2))
91-
(values a1 a2)))
91+
(values a a1 a2)))
9292

9393
(define check:offset
94-
(λ (r i n)
94+
(λ (a r i n)
9595
(unless (or (register? r) (label? r))
9696
(error n "expects register or label as first argument; given ~v" r))
9797
(unless (exact-integer? i)
9898
(error n "expects exact integer as second argument; given ~v" i))
99-
(values r i)))
99+
(values a r i)))
100100

101101
(define check:push
102-
(λ (a1 n)
102+
(λ (a a1 n)
103103
(unless (or (exact-integer? a1) (register? a1))
104104
(error n "expects exact integer or register; given ~v" a1))
105105
(when (and (exact-integer? a1) (> (integer-length a1) 32))
106106
(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)))
108108

109109
(define check:lea
110-
(λ (dst x n)
110+
(λ (a dst x n)
111111
(unless (or (register? dst) (offset? dst))
112112
(error n "expects register or offset; given ~v" dst))
113113
(unless (or (label? x) (offset? x) (exp? x))
114114
(error n "expects label, offset, or expression; given ~v" x))
115-
(values dst x)))
115+
(values a dst x)))
116116

117117
(define check:none
118-
(λ (n) (values)))
118+
(λ (a n) (values a)))
119119

120120
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
121121
;; Comments
@@ -140,12 +140,42 @@
140140
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141141
;; Instructions
142142

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?)))]))
149179

150180
(instruct Text () check:none)
151181
(instruct Data () check:none)
@@ -190,15 +220,15 @@
190220
(instruct Not (x) check:register)
191221
(instruct Div (den) check:register)
192222

193-
(instruct Offset (r i) check:offset)
223+
(instruct Offset (r i) check:offset) ;; May need to make this not an instruction
194224
(instruct Extern (x) check:label-symbol)
195225

196226
(instruct Equ (x v) check:label-symbol+integer)
197227
(instruct Const (x) check:label-symbol)
198228

199229
;; 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)))
202232

203233
(provide (struct-out Plus))
204234
(struct Plus (e1 e2) #:transparent)
@@ -212,7 +242,7 @@
212242
(symbol? x)
213243
(integer? x)))
214244

215-
(provide offset? register? instruction? label? 64-bit-integer? 32-bit-integer?)
245+
(provide offset? register? label? 64-bit-integer? 32-bit-integer?)
216246

217247
(define offset? Offset?)
218248

@@ -233,63 +263,19 @@
233263
(nasm-label? x)
234264
(not (register? x))))
235265

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)))
284270

285271
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
286272
;; Instruction sequencing and program error checking
287273

288274
(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?))])
293279

294280
;; (U Instruction Asm) ... -> Asm
295281
;; Convenient for sequencing instructions or groups of instructions

langs/a86/printer.rkt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,19 @@
7373
[_ (label-symbol->string e)]))
7474

7575
(define tab (make-string 8 #\space))
76+
77+
;; Instruction -> String
78+
(define (fancy-instr->string i)
79+
(let ((s (simple-instr->string i)))
80+
(if (instruction-annotation i)
81+
(if (< (string-length s) 40)
82+
(format "~a~a; ~.s" s (make-string (- 40 (string-length s)) #\space) (instruction-annotation i))
83+
(format "~a ; ~.s" s (instruction-annotation i)))
84+
s)))
85+
7686

7787
;; Instruction -> String
78-
(define (instr->string i)
88+
(define (simple-instr->string i)
7989
(match i
8090
[(Text) (string-append tab "section .text")]
8191
[(Data) (string-append tab "section .data align=8")] ; 8-byte aligned data
@@ -235,7 +245,7 @@
235245
[(%%% s) (string-append ";;; " s)]))
236246

237247
(define (line-comment i s)
238-
(let ((i-str (instr->string i)))
248+
(let ((i-str (simple-instr->string i)))
239249
(let ((pad (make-string (max 1 (- 32 (string-length i-str))) #\space)))
240250
(string-append i-str pad "; " s))))
241251

@@ -248,11 +258,11 @@
248258
(write-char #\newline)
249259
(instrs-display a))]
250260
[(cons i (cons (% s) a))
251-
(begin (write-string (line-comment i s))
261+
(begin (write-string (line-comment i s)) ; a line comment trumps an annotation
252262
(write-char #\newline)
253263
(instrs-display a))]
254264
[(cons i a)
255-
(begin (write-string (instr->string i))
265+
(begin (write-string (fancy-instr->string i))
256266
(write-char #\newline)
257267
(instrs-display a))]))
258268

langs/iniquity/compile.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
(define rdi 'rdi) ; arg
1010

1111
;; type CEnv = [Listof Variable]
12-
12+
1313
;; Prog -> Asm
1414
(define (compile p)
1515
(match p

0 commit comments

Comments
 (0)