067-fnptr-call.scm (1588B)
1 ;; tests/cc-cg/67-fnptr-call.scm — function-pointer call (§K.2). 2 ;; Models: 3 ;; int triple(int x) { return x + x + x; } 4 ;; int main(void) { 5 ;; int (*fp)(int) = triple; 6 ;; return fp(7); /* 21 */ 7 ;; } 8 ;; Exercises cg-call's %callr(t0) branch when the fn opnd is a 9 ;; non-fn-typed (frame) operand: the address is loaded into t0. 10 11 (let* ((cg (cg-init)) 12 (triple-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #f)))) 13 (triple-sym (%sym "triple" 'fn 'extern triple-fnty #f))) 14 ;; int triple(int x) { return x + x + x; } 15 (let* ((params (cg-fn-begin cg "triple" 16 (list (cons "x" %t-i32)) 17 %t-i32)) 18 (x* (cdr (car params)))) 19 (cg-push-sym cg x*) (cg-load cg) 20 (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add) 21 (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add) 22 (cg-return cg) 23 (cg-fn-end cg)) 24 ;; int main(void) { int (*fp)(int) = triple; return fp(7); } 25 (let* ((params (cg-fn-begin cg "main" '() %t-i32)) 26 (fp-ty (%ctype 'ptr 8 8 triple-fnty)) 27 (fp-sl (cg-alloc-slot cg 8 8)) 28 (fp-sym (%sym "fp" 'var 'auto fp-ty fp-sl))) 29 ;; fp = triple (address of fn into the slot) 30 (cg-push-sym cg fp-sym) 31 (cg-push-sym cg triple-sym) 32 (cg-cast cg fp-ty) 33 (cg-assign cg) (cg-pop cg) 34 ;; fp(7) — cg-call expects fn opnd at vstack-bottom of the args. 35 (cg-push-sym cg fp-sym) (cg-load cg) 36 (cg-push-imm cg %t-i32 7) 37 (cg-call cg 1 #t) 38 (cg-return cg) 39 (cg-fn-end cg)) 40 (write-bv-fd 1 (cg-finish cg)))