|
63 | 63 | [(App f es) (if (<= (length es) s) |
64 | 64 | (compile-tail-call f es c) |
65 | 65 | (compile-app f es c))] |
| 66 | + [(FCall e1 es) (if (<= (length es) s) |
| 67 | + (compile-tail-fun-call e1 es c) |
| 68 | + (compile-fun-call e1 es c))] |
66 | 69 | [(Begin e1 e2) (compile-tail-begin e1 e2 c s)] |
67 | 70 | [_ (compile-e e c)]))) |
68 | 71 |
|
|
104 | 107 | ; Bump the heap pointer |
105 | 108 | (Add rbx 8))) |
106 | 109 |
|
107 | | -(define (compile-fun-call e es c) |
108 | | - (let ((d (length es))) |
109 | | - (seq (compile-e e c) |
110 | | - (assert-proc rax) |
111 | | - (Push rax) |
112 | | - (compile-es es (cons #f c)) |
113 | | - (Mov rax (Offset rsp (* 8 d))) |
114 | | - (Xor rax type-proc) |
115 | | - (Call (Offset rax 0)) |
116 | | - (Add rsp (* 8 (add1 d)))))) |
117 | | - |
118 | 110 | ;; Op0 CEnv -> Asm |
119 | 111 | (define (compile-prim0 p c) |
120 | 112 | (match p |
|
248 | 240 | (Add rsp (* 8 (+ cnt (in-frame c)))) |
249 | 241 | (Jmp (symbol->label f))))) |
250 | 242 |
|
| 243 | +;; Similar to `compile-app` we have to be concerned about 16-byte alignment |
| 244 | +;; of `rsp`. However, the wrinkle is that we also have the function pointer |
| 245 | +;; on the stack, so we have to do the calculation with an `extended` env: `env` |
| 246 | +(define (compile-fun-call e es c) |
| 247 | + (let ((d (length es)) |
| 248 | + (env (cons #f c))) |
| 249 | + ; We have to computer the function pointer either way. |
| 250 | + (seq (compile-e e c) |
| 251 | + (assert-proc rax) |
| 252 | + (Push rax) |
| 253 | + |
| 254 | + ; Then we worry about alignment |
| 255 | + (if (even? (+ d (length env))) |
| 256 | + |
| 257 | + ; We will be 16-byte aligned |
| 258 | + (seq (compile-es es env) |
| 259 | + (Mov rax (Offset rsp (* 8 d))) |
| 260 | + (Xor rax type-proc) |
| 261 | + (Call (Offset rax 0)) |
| 262 | + (Add rsp (* 8 (add1 d)))) |
| 263 | + |
| 264 | + ; We won't be 16-byte aligned, and need to adjust `rsp` |
| 265 | + (seq (Sub rsp 8) |
| 266 | + (compile-es es env) |
| 267 | + (Mov rax (Offset rsp (* 8 (add1 d)))) |
| 268 | + (Xor rax type-proc) |
| 269 | + (Call (Offset rax 0)) |
| 270 | + ; pop arguments, padding, and function pointer |
| 271 | + (Add rsp (* 8 (+ 2 d)))))))) |
| 272 | + |
| 273 | +;; Variable (Listof Expr) CEnv -> Asm |
| 274 | +;; Compile a call in tail position |
| 275 | +(define (compile-tail-fun-call f es c) |
| 276 | + (let ((cnt (length es))) |
| 277 | + (seq (compile-e f c) |
| 278 | + (assert-proc rax) |
| 279 | + (Push rax) |
| 280 | + (compile-es es (cons #f c)) |
| 281 | + (move-args cnt (+ cnt (add1 (in-frame c)))) |
| 282 | + (Mov rax (Offset rsp (* 8 cnt))) |
| 283 | + (Xor rax type-proc) |
| 284 | + (Add rsp (* 8 (+ cnt (add1 (in-frame c))))) |
| 285 | + (Jmp (Offset rax 0))))) |
| 286 | + |
251 | 287 | ;; Integer Integer -> Asm |
252 | 288 | ;; Move i arguments upward on stack by offset off |
253 | 289 | (define (move-args i cnt) |
|
0 commit comments