Skip to content

Commit 1375344

Browse files
committed
Do args for C FFI
1 parent 8e3e0c8 commit 1375344

File tree

4 files changed

+80
-19
lines changed

4 files changed

+80
-19
lines changed

www/notes/shakedown/asm/printer.rkt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@
5353
[(? integer?) (number->string a)]
5454
[(? symbol?) (label->string a)]))
5555

56+
(define all-regs '(rax rbx rcx rdx rsp rdi rip rbp rsi r8 r9 r10 r11 r12 r13 r14 r15))
57+
5658
;; Any -> Boolean
5759
(define (reg? x)
5860
(and (symbol? x)
59-
(memq x '(rax rbx rcx rdx rsp rdi rip rbp rsi r8 r9 r10 r11 r12 r13 r14 r15))))
61+
(memq x all-regs)))
6062

6163
;; Reg -> String
6264
(define (reg->string r)

www/notes/shakedown/clib.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ int64_t c_fun() {
77
puts("Hello, from C!");
88
return (42 << imm_shift);
99
}
10+
11+
int64_t c_fun1(int64_t x) {
12+
printf("You gave me x = %" PRId64 "\n", x);
13+
int64_t res = x * x;
14+
return (res << imm_shift);
15+
}

www/notes/shakedown/compile.rkt

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -122,25 +122,78 @@
122122

123123
;; Label (listof Expr) -> Asm
124124
(define (compile-ccall f es c)
125-
(let ((stack-size (* 8 (length c))))
126-
(match es
127-
[`()
128-
`(
129-
130-
(mov r15 rsp)
131-
132-
; change rsp to reflect the top of the stack
133-
(sub rsp ,stack-size)
125+
(let* ((c0 (store-caller-save caller-saves c))
126+
(c* (car c0))
127+
(c1 (compile-es-ffi es c* 0))
128+
(c2 (cdr (load-caller-save caller-saves c)))
129+
(stack-size (* 8 (length c*))))
130+
131+
; We don't actually have to do all caller-save (that's a lot!)
132+
; Just the ones that our compiler emits
133+
`(,@(cdr c0)
134+
135+
,@c1
136+
(mov r15 rsp) ; Using the fact that r15 is callee save
137+
138+
; change rsp to reflect the top of the stack
139+
(sub rsp ,stack-size)
140+
141+
; align rsp to safest 16-byte aligned spot
142+
(and rsp -16)
143+
144+
; Actually call the function
145+
(call ,f)
146+
147+
; Restore our stack
148+
(mov rsp r15)
149+
150+
; Put the caller-saved values back
151+
,@c2)))
152+
153+
;; The registers that we can use to pass arguments to C functions
154+
;; (in the right order)
155+
;;
156+
(define arg-regs '(rdi rsi rdx rcx r8 r9))
157+
(define callee-saves '(rbp rbx r12 r13 r14 r15))
158+
(define caller-saves '(rcx rdx rdi rsi r8 r9 r10 r11))
159+
160+
; Make sure we store every caller-save register that we care about on the stack.
161+
; This is basiclaly a foldMR, but I need to learn more Racket
162+
(define (store-caller-save rs c)
163+
(match rs
164+
['() (cons c '())]
165+
[(cons r rs)
166+
(match (store-caller-save rs c)
167+
[(cons d asm)
168+
(cons (cons #f d)
169+
(append asm `((mov (offset rsp ,(- (add1 (length d)))) ,r))))])]))
170+
171+
; Same as above but inverse
172+
(define (load-caller-save rs c)
173+
(match rs
174+
['() (cons c '())]
175+
[(cons r rs)
176+
(match (load-caller-save rs c)
177+
[(cons d asm)
178+
(cons (cons #f d)
179+
(append asm `((mov ,r (offset rsp ,(- (add1 (length d))))))))])]))
180+
181+
182+
;; JMCT: I keep 'programming in Haskell in Racket' and I need to stop that...
183+
;; the above is my monadic habits biting me
134184

135-
; align rsp to safest 16-byte aligned spot
136-
(and rsp -16)
137-
138-
(call ,f)
139-
140-
(mov rsp r15)
185+
;; (Listof LExpr) CEnv -> Asm
186+
(define (compile-es-ffi es c i)
187+
(match es
188+
['() '()]
189+
[(cons e es)
190+
(let ((c0 (compile-e e c))
191+
(cs (compile-es-ffi es c (add1 i))))
192+
`(,@c0
193+
(sar rax ,imm-shift)
194+
(mov ,(list-ref arg-regs i) rax) ; Put the result in the appropriate register
195+
,@cs))]))
141196

142-
)]
143-
[_ `()])))
144197

145198
;; (Listof Variable) Label (Listof Variable) CEnv -> Asm
146199
(define (compile-λ xs f ys c)

www/notes/shakedown/example.shk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
(let ((y (ccall c_fun))) ((lambda (x) y) 11))
1+
(let ((y (ccall c_fun1 42))) ((lambda (x) y) 11))

0 commit comments

Comments
 (0)