070-struct-ret-1word.scm (2358B)
1 ;; tests/cc-cg/70-struct-ret-1word.scm — one-word direct struct return. 2 ;; 3 ;; Models: 4 ;; struct S { int a; int b; }; 5 ;; struct S make(int a, int b) { struct S s; s.a = a; s.b = b; return s; } 6 ;; int main(void) { 7 ;; struct S r = make(7, 9); 8 ;; return r.a + r.b * 10; /* 97 */ 9 ;; } 10 ;; 11 ;; Exercises Stream A1's one-word direct return convention (P1.md 12 ;; §Arguments and return values): result word 0 in a0; cg-fn-end emits 13 ;; LD a0, [sp + ret-slot] at exit; cg-call's receive side allocates a 14 ;; fresh frame slot sized to the return ctype, stores back from a0, 15 ;; and pushes a struct frame-lval so chained .field works. 16 17 (let* ((cg (cg-init)) 18 (st-ty (%ctype 'struct 8 4 19 (list "S" #t 20 (list (list "a" %t-i32 0) 21 (list "b" %t-i32 4))))) 22 (fn-ty (%ctype 'fn 8 8 23 (cons st-ty (cons (list %t-i32 %t-i32) #f)))) 24 (make-sym (%sym "make" 'fn 'extern fn-ty #f))) 25 ;; struct S make(int a, int b) { ... return s; } 26 (let* ((params (cg-fn-begin cg "make" 27 (list (cons "a" %t-i32) (cons "b" %t-i32)) 28 st-ty)) 29 (a* (cdr (car params))) 30 (b* (cdr (cadr params))) 31 (s-off (cg-alloc-slot cg 8 4)) 32 (s-sym (%sym "s" 'var 'auto st-ty s-off))) 33 ;; s.a = a 34 (cg-push-sym cg s-sym) (cg-push-field cg "a") 35 (cg-push-sym cg a*) (cg-load cg) 36 (cg-assign cg) (cg-pop cg) 37 ;; s.b = b 38 (cg-push-sym cg s-sym) (cg-push-field cg "b") 39 (cg-push-sym cg b*) (cg-load cg) 40 (cg-assign cg) (cg-pop cg) 41 ;; return s — struct-typed return 42 (cg-push-sym cg s-sym) 43 (cg-return cg) 44 (cg-fn-end cg)) 45 ;; int main(void) { struct S r = make(7, 9); return r.a + r.b * 10; } 46 (cg-fn-begin cg "main" '() %t-i32) 47 (cg-push-sym cg make-sym) 48 (cg-push-imm cg %t-i32 7) 49 (cg-push-imm cg %t-i32 9) 50 (cg-call cg 2 #t) ; pushes struct lval (recv slot) 51 ;; The result is a struct lval. Read .a and .b. 52 (let ((r-lval (cg-pop cg))) 53 (cg-push cg r-lval) (cg-push-field cg "a") (cg-load cg) 54 (cg-push cg r-lval) (cg-push-field cg "b") (cg-load cg) 55 (cg-push-imm cg %t-i32 10) (cg-binop cg 'mul) 56 (cg-binop cg 'add)) 57 (cg-return cg) 58 (cg-fn-end cg) 59 (write-bv-fd 1 (cg-finish cg)))