boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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)))