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