Skip to content

Commit 925c3e1

Browse files
committed
Update Knock notes
1 parent 83df854 commit 925c3e1

File tree

1 file changed

+58
-43
lines changed

1 file changed

+58
-43
lines changed

www/notes/knock.scrbl

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ expression (that should evaluate to a function):
4343
@verbatim|{
4444
;; type Expr =
4545
;; | ....
46-
;; | `(fun ,Variable)
47-
;; | `(call ,Expr ,@(Listof Expr))
46+
;; | (Fun Id)
47+
;; | (Call Expr (Listof Expr))
4848
}|
4949

5050
These new syntactic forms are temporary forms that don't correspond
@@ -73,18 +73,18 @@ value.
7373

7474
@#reader scribble/comment-reader
7575
(racketblock
76-
;; Variable -> Asm
76+
;; Id -> Asm
7777
(define (compile-fun f)
78-
`(; rax <- address of label f
79-
(lea rax (offset ,(symbol->label f) 0))
80-
; write in to heap
81-
(mov (offset rdi 0) rax)
82-
; rax <- pointer into heap
83-
(mov rax rdi)
84-
; tag as procedure pointer
85-
(or rax ,type-proc)
86-
; alloc
87-
(add rdi 8)))
78+
; Load the address of the label into rax
79+
(seq (Lea rax (symbol->label f))
80+
; Copy the value onto the heap
81+
(Mov (Offset rbx 0) rax)
82+
; Copy the heap address into rax
83+
(Mov rax rbx)
84+
; Tag the value as a proc
85+
(Or rax type-proc)
86+
; Bump the heap pointer
87+
(Add rbx 8)))
8888
)
8989

9090
A function call, @racket[(call _e0 _es ...)] will evaluate on the
@@ -93,45 +93,60 @@ function, i.e. tagged pointer. We can erase the tag to compute the
9393
address in the heap. Dereferencing that location, gets us the label
9494
address, which can then jump to.
9595

96+
Similar to `compile-app` from Iniquity, we have to be concerned about 16-byte
97+
alignment for `rsp`. However, the wrinkle is that we also have the function
98+
pointer on the stack, so we have to do the calculation with an `extended` env:
99+
`env`:
100+
96101
@#reader scribble/comment-reader
97102
(racketblock
98-
;; Expr (Listof Expr) CEnv -> Asm
99103
(define (compile-fun-call e0 es c)
100-
(let ((cs (compile-es es (cons #f c)))
101-
(c0 (compile-e e0 c))
102-
(i (- (add1 (length c))))
103-
(stack-size (* 8 (length c))))
104-
`(,@c0
105-
; save f in stack
106-
(mov (offset rsp ,i) rax)
107-
,@cs
108-
; restore f
109-
(mov rax (offset rsp ,i))
110-
,@assert-proc
111-
(sub rsp ,stack-size)
112-
(xor rax ,type-proc)
113-
; call f
114-
(call (offset rax 0))
115-
(add rsp ,stack-size))))
104+
(let ((d (length es))
105+
(env (cons #f c)))
106+
; We have to computer the function pointer either way.
107+
(seq (compile-e e0 c)
108+
(assert-proc rax)
109+
(Push rax)
110+
111+
; Then we worry about alignment
112+
(if (even? (+ d (length env)))
113+
114+
; We will be 16-byte aligned
115+
(seq (compile-es es env)
116+
(Mov rax (Offset rsp (* 8 d)))
117+
(Xor rax type-proc)
118+
(Call (Offset rax 0))
119+
(Add rsp (* 8 (add1 d))))
120+
121+
; We won't be 16-byte aligned, and need to adjust `rsp`
122+
(seq (Sub rsp 8)
123+
(compile-es es env)
124+
(Mov rax (Offset rsp (* 8 (add1 d))))
125+
(Xor rax type-proc)
126+
(Call (Offset rax 0))
127+
; pop arguments, padding, and function pointer
128+
(Add rsp (* 8 (+ 2 d))))))))
129+
116130
)
117131

118132
A tail call version of the above can be defined as:
119133

120134
@#reader scribble/comment-reader
121135
(racketblock
122-
;; Expr (Listof Expr) CEnv -> Asm
123-
(define (compile-fun-tail-call e0 es c)
124-
(let ((cs (compile-es es (cons #f c)))
125-
(c0 (compile-e e0 c))
126-
(i (- (add1 (length c)))))
127-
`(,@c0
128-
(mov (offset rsp ,i) rax)
129-
,@cs
130-
(mov rax (offset rsp ,i))
131-
,@(move-args (length es) i)
132-
,@assert-proc
133-
(xor rax ,type-proc)
134-
(jmp (offset rax 0)))))
136+
;; Variable (Listof Expr) CEnv -> Asm
137+
;; Compile a call in tail position
138+
(define (compile-tail-fun-call f es c)
139+
(let ((cnt (length es)))
140+
(seq (compile-e f c)
141+
(assert-proc rax)
142+
(Push rax)
143+
(compile-es es (cons #f c))
144+
(move-args cnt (+ cnt (add1 (in-frame c))))
145+
(Mov rax (Offset rsp (* 8 cnt)))
146+
(Xor rax type-proc)
147+
(Add rsp (* 8 (+ cnt (add1 (in-frame c)))))
148+
(Jmp (Offset rax 0)))))
149+
135150
)
136151

137152
The complete compiler:

0 commit comments

Comments
 (0)