069-vararg-recv.scm (2808B)
1 ;; tests/cc-cg/69-vararg-recv.scm — variadic receive: va_start / va_arg / 2 ;; va_end on three int variadic args (§G.2). 3 ;; 4 ;; Models: 5 ;; int sum(int n, ...) { 6 ;; va_list ap; va_start(ap, n); 7 ;; int total = 0; 8 ;; int i = 0; 9 ;; while (i < n) { total = total + va_arg(ap, int); i = i + 1; } 10 ;; va_end(ap); 11 ;; return total; 12 ;; } 13 ;; int main(void) { return sum(3, 5, 7, 9); } /* 21 */ 14 ;; 15 ;; Limitation: only first 4 incoming args (named + variadic) live in 16 ;; registers. n=1 named, 3 variadic → fits. 17 18 (let* ((cg (cg-init)) 19 (sum-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #t)))) 20 (sum-sym (%sym "sum" 'fn 'extern sum-fnty #f))) 21 ;; int sum(int n, ...) 22 (let* ((params (cg-fn-begin/v cg "sum" 23 (list (cons "n" %t-i32)) 24 %t-i32 25 #t)) 26 (n* (cdr (car params))) 27 (ap-ty (%ctype 'ptr 8 8 %t-i8)) ; va_list = char* (just a pointer) 28 (ap-sl (cg-alloc-slot cg 8 8)) 29 (ap-sym (%sym "ap" 'var 'auto ap-ty ap-sl)) 30 (tot-sl (cg-alloc-slot cg 4 4)) 31 (tot-sym (%sym "total" 'var 'auto %t-i32 tot-sl)) 32 (i-sl (cg-alloc-slot cg 4 4)) 33 (i-sym (%sym "i" 'var 'auto %t-i32 i-sl))) 34 ;; va_start(ap) 35 (cg-push-sym cg ap-sym) 36 (cg-va-start cg) 37 ;; total = 0 38 (cg-push-sym cg tot-sym) (cg-push-imm cg %t-i32 0) 39 (cg-assign cg) (cg-pop cg) 40 ;; i = 0 41 (cg-push-sym cg i-sym) (cg-push-imm cg %t-i32 0) 42 (cg-assign cg) (cg-pop cg) 43 ;; while (i < n) 44 (cg-loop cg 45 (lambda () 46 (cg-push-sym cg i-sym) (cg-load cg) 47 (cg-push-sym cg n*) (cg-load cg) 48 (cg-binop cg 'lt)) 49 (lambda (tag) 50 ;; total = total + va_arg(ap, int) 51 (cg-push-sym cg tot-sym) 52 (cg-push-sym cg tot-sym) (cg-load cg) 53 (cg-push-sym cg ap-sym) (cg-va-arg cg %t-i32) 54 (cg-binop cg 'add) 55 (cg-assign cg) (cg-pop cg) 56 ;; i = i + 1 57 (cg-push-sym cg i-sym) 58 (cg-push-sym cg i-sym) (cg-load cg) 59 (cg-push-imm cg %t-i32 1) 60 (cg-binop cg 'add) 61 (cg-assign cg) (cg-pop cg))) 62 ;; va_end(ap) 63 (cg-push-sym cg ap-sym) 64 (cg-va-end cg) 65 ;; return total 66 (cg-push-sym cg tot-sym) (cg-load cg) 67 (cg-return cg) 68 (cg-fn-end cg)) 69 ;; int main(void) { return sum(3, 5, 7, 9); } 70 (cg-fn-begin cg "main" '() %t-i32) 71 (cg-push-sym cg sum-sym) 72 (cg-push-imm cg %t-i32 3) 73 (cg-push-imm cg %t-i32 5) 74 (cg-push-imm cg %t-i32 7) 75 (cg-push-imm cg %t-i32 9) 76 (cg-call cg 4 #t) 77 (cg-return cg) 78 (cg-fn-end cg) 79 (write-bv-fd 1 (cg-finish cg)))