boot2

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

071-struct-ret-2word.scm (2173B)


      1 ;; tests/cc-cg/71-struct-ret-2word.scm — two-word direct struct return.
      2 ;;
      3 ;; Models:
      4 ;;   struct P { long a; long b; };           /* 16 bytes */
      5 ;;   struct P pair(long a, long b) {
      6 ;;     struct P p; p.a = a; p.b = b; return p;
      7 ;;   }
      8 ;;   int main(void) {
      9 ;;     struct P q = pair(11, 22);
     10 ;;     return (int)(q.a + q.b);   /* 33 */
     11 ;;   }
     12 ;;
     13 ;; Exercises Stream A1's two-word direct return convention (P1.md
     14 ;; §Arguments and return values): word 0 in a0, word 1 in a1; cg-fn-end
     15 ;; loads both at exit; cg-call's receive side allocates a 16-byte slot
     16 ;; and stores back from a0 (word 0) and a1 (word 1).
     17 
     18 (let* ((cg      (cg-init))
     19        (pair-ty (%ctype 'struct 16 8
     20                         (list "P" #t
     21                               (list (list "a" %t-i64 0)
     22                                     (list "b" %t-i64 8)))))
     23        (fn-ty   (%ctype 'fn 8 8
     24                         (cons pair-ty (cons (list %t-i64 %t-i64) #f))))
     25        (pair-sym (%sym "pair" 'fn 'extern fn-ty #f)))
     26   ;; struct P pair(long a, long b) { ... return p; }
     27   (let* ((params (cg-fn-begin cg "pair"
     28                               (list (cons "a" %t-i64) (cons "b" %t-i64))
     29                               pair-ty))
     30          (a*     (cdr (car params)))
     31          (b*     (cdr (cadr params)))
     32          (p-off  (cg-alloc-slot cg 16 8))
     33          (p-sym  (%sym "p" 'var 'auto pair-ty p-off)))
     34     ;; p.a = a
     35     (cg-push-sym cg p-sym) (cg-push-field cg "a")
     36     (cg-push-sym cg a*)    (cg-load cg)
     37     (cg-assign cg) (cg-pop cg)
     38     ;; p.b = b
     39     (cg-push-sym cg p-sym) (cg-push-field cg "b")
     40     (cg-push-sym cg b*)    (cg-load cg)
     41     (cg-assign cg) (cg-pop cg)
     42     ;; return p
     43     (cg-push-sym cg p-sym)
     44     (cg-return cg)
     45     (cg-fn-end cg))
     46   ;; int main(void) { struct P q = pair(11, 22); return q.a + q.b; }
     47   (cg-fn-begin cg "main" '() %t-i32)
     48   (cg-push-sym cg pair-sym)
     49   (cg-push-imm cg %t-i64 11)
     50   (cg-push-imm cg %t-i64 22)
     51   (cg-call cg 2 #t)
     52   (let ((q-lval (cg-pop cg)))
     53     (cg-push cg q-lval) (cg-push-field cg "a") (cg-load cg)
     54     (cg-push cg q-lval) (cg-push-field cg "b") (cg-load cg)
     55     (cg-binop cg 'add))
     56   (cg-return cg)
     57   (cg-fn-end cg)
     58   (write-bv-fd 1 (cg-finish cg)))