Changeset 14969
- Timestamp:
- Sep 1, 2011, 10:43:41 PM (13 years ago)
- Location:
- trunk/source/compiler/X86
- Files:
-
- 3 edited
-
X8632/x8632-vinsns.lisp (modified) (2 diffs)
-
X8664/x8664-vinsns.lisp (modified) (3 diffs)
-
x862.lisp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/compiler/X86/X8632/x8632-vinsns.lisp
r14959 r14969 1626 1626 ) 1627 1627 1628 (define-x8632-vinsn (pass-multiple-values-known-function :jumplr) (((fnreg :lisp)) 1629 ()) 1630 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::ret1valaddr)))) 1631 (jmp (:%l fnreg))) 1632 1628 1633 1629 1634 (define-x8632-vinsn reserve-outgoing-frame (() … … 4179 4184 (movsd (:%xmm val) (:@ (:%l base) (:%l idx) 2))) 4180 4185 4186 (define-x8632-vinsn pop-outgoing-arg (((n :u16const)) 4187 ()) 4188 (popl (:@ (:apply * n (- x8632::node-size)) (:%l x8632::ebp)))) 4189 4190 (define-x8632-vinsn slide-nth-arg (() 4191 ((n :u16const) 4192 (nstackargs :u16const) 4193 (temp :lisp))) 4194 (movl (:@ (:apply * (:apply - nstackargs (:apply + 1 n)) x8632::node-size) (:%l x8632::esp)) (:%l temp)) 4195 (movl (:%l temp) (:@ (:apply * (:apply + n 1) (- x8632::node-size)) (:%l x8632::ebp)))) 4196 4197 (define-x8632-vinsn set-tail-vsp (((n :u16const)) 4198 ()) 4199 ((:pred = 0 n) 4200 (movl (:%l x8632::ebp) (:%l x8632::esp))) 4201 ((:not (:pred = 0 n)) 4202 (leal (:@ (:apply * n (- x8632::node-size)) (:%l x8632::ebp)) (:%l x8632::esp)))) 4203 4204 ;;; If we've have outgoing arguments in a tail call and are calling 4205 ;;; some function (rather than jumping to an internal entry point), we 4206 ;;; need to push the caller's return address and unlink its frame 4207 ;;; pointer. 4208 (define-x8632-vinsn prepare-tail-call (() 4209 ()) 4210 (pushl (:@ x8632::node-size (:%l x8632::ebp))) 4211 (movl (:@ (:% x8632::ebp)) (:% x8632::ebp))) 4212 4181 4213 (queue-fixup 4182 4214 (fixup-x86-vinsn-templates -
trunk/source/compiler/X86/X8664/x8664-vinsns.lisp
r14959 r14969 1781 1781 ;;; as well as this. 1782 1782 (define-x8664-vinsn (pass-multiple-values :jumplr) (() 1783 ()1784 ((tag :u8)))1783 () 1784 ((tag :u8))) 1785 1785 :resume 1786 1786 (movl (:%l x8664::temp0) (:%l tag)) … … 1797 1797 (:anchored-uuo (uuo-error-not-callable))) 1798 1798 1799 (define-x8664-vinsn (pass-multiple-values-known-function :jumplr) (((fnreg :lisp)) 1800 ()) 1801 (pushq (:@ (:apply + (:apply target-nil-value) (x8664::%kernel-global 'x86::ret1valaddr)))) 1802 (jmp (:%q fnreg))) 1799 1803 1800 1804 … … 4598 4602 (movsd (:%xmm val) (:@ (:%q base) (:%q idx)))) 4599 4603 4604 4605 (define-x8664-vinsn pop-outgoing-arg (((n :u16const)) 4606 ()) 4607 (popq (:@ (:apply * n (- x8664::node-size)) (:%q x8664::rbp)))) 4608 4609 (define-x8664-vinsn slide-nth-arg (() 4610 ((n :u16const) 4611 (nstackargs :u16const) 4612 (temp :lisp))) 4613 (movq (:@ (:apply * (:apply - nstackargs (:apply + 1 n)) x8664::node-size) (:%q x8664::rsp)) (:%q temp)) 4614 (movq (:%q temp) (:@ (:apply * (:apply + n 1) (- x8664::node-size)) (:%q x8664::rbp)))) 4615 4616 4617 (define-x8664-vinsn set-tail-vsp (((nargs :u16const)) 4618 ()) 4619 ((:pred = 0 nargs) 4620 (movq (:%q x8664::rbp) (:%q x8664::rsp))) 4621 ((:not (:pred = 0 nargs)) 4622 (leaq (:@ (:apply * nargs (- x8664::node-size)) (:%q x8664::rbp)) (:%q x8664::rsp)))) 4623 4624 4625 ;;; If we've used one of the fixed-stack-args !slideN vinsns above 4626 ;;; and are calling some function (rather than jumping to an internal 4627 ;;; entry point), we need to push the caller's return address and unlink 4628 ;;; its frame pointer. 4629 (define-x8664-vinsn prepare-tail-call (() 4630 ()) 4631 (pushq (:@ x8664::node-size (:%q x8664::rbp))) 4632 (movq (:@ (:%q x8664::rbp)) (:%q x8664::rbp))) 4633 4600 4634 (queue-fixup 4601 4635 (fixup-x86-vinsn-templates -
trunk/source/compiler/X86/x862.lisp
r14967 r14969 194 194 (defvar *x862-entry-vstack* nil) 195 195 (defvar *x862-fixed-nargs* nil) 196 (defvar *x862-fixed-self-call-label* nil) 197 (defvar *x862-fixed-self-tail-call-label* nil) 196 198 (defvar *x862-need-nargs* t) 197 199 … … 611 613 (*x862-entry-vstack* nil) 612 614 (*x862-fixed-nargs* nil) 615 (*x862-fixed-self-call-label* nil) 616 (*x862-fixed-self-tail-call-label* nil) 613 617 (*x862-need-nargs* t) 614 618 (fname (afunc-name afunc)) … … 1176 1180 (declare (type (unsigned-byte 16) nargs)) 1177 1181 (unless variable-args-entry 1182 (setq *x862-fixed-nargs* nargs) 1183 (@ (setq *x862-fixed-self-call-label* (backend-get-next-label))) 1178 1184 (if (<= nargs *x862-target-num-arg-regs*) ; caller didn't vpush anything 1179 1185 (! save-lisp-context-no-stack-args) 1180 1186 (let* ((offset (* (the fixnum (- nargs *x862-target-num-arg-regs*)) *x862-target-node-size*))) 1181 1187 (declare (fixnum offset)) 1182 (! save-lisp-context-offset offset)))) 1188 (! save-lisp-context-offset offset))) 1189 (@ (setq *x862-fixed-self-tail-call-label* (backend-get-next-label)))) 1183 1190 (target-arch-case 1184 1191 (:x8632 … … 2811 2818 (x862-vpush-register seg (x862-one-untargeted-reg-form seg fn *x862-arg-z*)) 2812 2819 (setq fn (x862-vloc-ea vstack))) 2813 (x862-invoke-fn seg fn (x862-arglist seg arglist mv-return-label ) spread-p xfer mv-return-label)2820 (x862-invoke-fn seg fn (x862-arglist seg arglist mv-return-label (x862-tailcallok xfer)) spread-p xfer mv-return-label) 2814 2821 (if (and (logbitp $backend-mvpass-bit xfer) 2815 2822 (not simple-case)) … … 2849 2856 (! jump-known-symbol) 2850 2857 (! call-known-symbol *x862-arg-z*)))) 2858 2859 (defun x862-self-call (seg nargs tail-p) 2860 (with-x86-local-vinsn-macros (seg) 2861 (cond ((and tail-p 2862 (eql nargs *x862-fixed-nargs*) 2863 (or *x862-open-code-inline* 2864 (<= nargs (+ 3 *x862-target-num-arg-regs*))) 2865 *x862-fixed-self-tail-call-label*) 2866 ;; We can probably do better than popping the nvrs 2867 ;; and then jumping to a point where we push them again ... 2868 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* (<= nargs *x862-target-num-arg-regs*)) 2869 (let* ((nstack (- nargs *x862-target-num-arg-regs*))) 2870 (declare (fixnum nstack)) 2871 (if (< nstack 0) (setq nstack 0)) 2872 (do* ((n nstack (1- n))) 2873 ((= n 0) (! set-tail-vsp nstack)) 2874 (declare (fixnum n)) 2875 (! pop-outgoing-arg n)) 2876 (-> *x862-fixed-self-tail-call-label*)) 2877 t) 2878 ((and (not tail-p) 2879 (eql nargs *x862-fixed-nargs*) 2880 *x862-fixed-self-call-label*) 2881 (! call-label (aref *backend-labels* *x862-fixed-self-call-label*)) 2882 t)))) 2851 2883 2852 2884 ;;; Nargs = nil -> multiple-value case. … … 2869 2901 (destreg (if symp ($ *x862-fname*) (unless label-p ($ *x862-temp0*)))) 2870 2902 (alternate-tail-call 2871 (and tail-p label-p *x862-tail-label* (eql nargs *x862-tail-nargs*) (not spread-p)))) 2872 (when expression-p 2873 ;;Have to do this before spread args, since might be vsp-relative. 2874 (if nargs 2875 (x862-do-lexical-reference seg destreg fn) 2876 (x862-copy-register seg destreg fn))) 2877 (if (or symp lfunp) 2878 (setq func (if symp 2879 (x862-symbol-entry-locative func) 2880 (x862-afunc-lfun-ref func)) 2881 a-reg (x862-register-constant-p func))) 2882 (when tail-p 2883 #-no-compiler-bugs 2884 (unless (or immp symp lfunp (typep fn 'lreg) (fixnump fn)) (compiler-bug "Well, well, well. How could this have happened ?")) 2885 (when a-reg 2886 (x862-copy-register seg destreg a-reg)) 2887 (unless spread-p 2888 (unless alternate-tail-call 2889 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* (and nargs (<= nargs *x862-target-num-arg-regs*)))))) 2890 (if spread-p 2891 (progn 2892 (x862-set-nargs seg (%i- nargs 1)) 2893 ; .SPspread-lexpr-z & .SPspreadargz preserve temp1 2894 (target-arch-case 2895 (:x8632 2896 (! save-node-register-to-spill-area *x862-temp0*))) 2897 (if (eq spread-p 0) 2898 (! spread-lexpr) 2899 (! spread-list)) 2900 (target-arch-case 2901 (:x8632 2902 (! load-node-register-from-spill-area *x862-temp0*))) 2903 2904 (when (and tail-p *x862-register-restore-count*) 2905 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* nil))) 2906 (if nargs 2907 (unless alternate-tail-call (x862-set-nargs seg nargs)) 2908 (! pop-argument-registers))) 2909 (if callable 2910 (if (not tail-p) 2911 (if (x862-mvpass-p xfer) 2912 (let* ((call-reg (if symp ($ *x862-fname*) ($ *x862-temp0*)))) 2913 (unless mvpass-label (compiler-bug "no label for mvpass")) 2914 (if label-p 2915 (x862-copy-register seg call-reg ($ *x862-fn*)) 2916 (if a-reg 2917 (x862-copy-register seg call-reg a-reg) 2918 (x862-store-immediate seg func call-reg))) 2919 (if symp 2920 (! pass-multiple-values-symbol) 2921 (! pass-multiple-values)) 2922 (when mvpass-label 2923 (@= mvpass-label))) 2924 (progn 2925 (if label-p 2926 (progn 2927 (! call-label (aref *backend-labels* 2))) 2928 (progn 2929 (if a-reg 2930 (x862-copy-register seg destreg a-reg) 2931 (x862-store-immediate seg func destreg)) 2932 (if symp 2933 (x862-call-symbol seg nil) 2934 (! call-known-function)))))) 2935 (if alternate-tail-call 2936 (progn 2937 (x862-unwind-stack seg xfer 0 0 *x862-tail-vsp*) 2938 (! jump (aref *backend-labels* *x862-tail-label*))) 2939 (progn 2940 (x862-unwind-stack seg xfer 0 0 #x7fffff) 2941 (if (and (not spread-p) nargs (%i<= nargs *x862-target-num-arg-regs*)) 2942 (progn 2943 (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) 2944 (x862-restore-full-lisp-context seg) 2945 (if label-p 2946 (! jump (aref *backend-labels* 1)) 2947 (progn 2903 (and tail-p label-p *x862-tail-label* (eql nargs *x862-tail-nargs*) (not spread-p))) 2904 (set-nargs-vinsn nil)) 2905 (or (and label-p nargs (not spread-p) (not (x862-mvpass-p xfer)) 2906 (not alternate-tail-call) 2907 (x862-self-call seg nargs tail-p)) 2908 (progn 2909 (when expression-p 2910 ;;Have to do this before spread args, since might be vsp-relative. 2911 (if nargs 2912 (x862-do-lexical-reference seg destreg fn) 2913 (x862-copy-register seg destreg fn))) 2914 (if (or symp lfunp) 2915 (setq func (if symp 2916 (x862-symbol-entry-locative func) 2917 (x862-afunc-lfun-ref func)) 2918 a-reg (x862-register-constant-p func))) 2919 (when tail-p 2920 #-no-compiler-bugs 2921 (unless (or immp symp lfunp (typep fn 'lreg) (fixnump fn)) (compiler-bug "Well, well, well. How could this have happened ?")) 2922 (when a-reg 2923 (x862-copy-register seg destreg a-reg)) 2924 (unless spread-p 2925 (unless alternate-tail-call 2926 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* (and nargs (<= nargs *x862-target-num-arg-regs*)))))) 2927 (if spread-p 2928 (progn 2929 (x862-set-nargs seg (%i- nargs 1)) 2930 ;; .SPspread-lexpr-z & .SPspreadargz preserve temp1 2931 (target-arch-case 2932 (:x8632 2933 (! save-node-register-to-spill-area *x862-temp0*))) 2934 (if (eq spread-p 0) 2935 (! spread-lexpr) 2936 (! spread-list)) 2937 (target-arch-case 2938 (:x8632 2939 (! load-node-register-from-spill-area *x862-temp0*))) 2940 2941 (when (and tail-p *x862-register-restore-count*) 2942 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* nil))) 2943 (if nargs 2944 (unless alternate-tail-call 2945 (setq set-nargs-vinsn (x862-set-nargs seg nargs))) 2946 (! pop-argument-registers))) 2947 (if callable 2948 (if (not tail-p) 2949 (if (x862-mvpass-p xfer) 2950 (let* ((call-reg (if label-p ($ *x862-fn*) (if symp ($ *x862-fname*) ($ *x862-temp0*))))) 2951 (unless mvpass-label (compiler-bug "no label for mvpass")) 2952 (unless label-p 2953 (if a-reg 2954 (x862-copy-register seg call-reg a-reg) 2955 (x862-store-immediate seg func call-reg))) 2956 (if label-p 2957 (! pass-multiple-values-known-function call-reg) 2948 2958 (if symp 2949 (x862-call-symbol seg t) 2950 (! jump-known-function))))) 2951 (progn 2952 (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) 2953 (when label-p 2954 (x862-copy-register seg *x862-temp0* *x862-fn*)) 2955 2956 (cond ((or spread-p (null nargs)) 2957 (if symp 2958 (! tail-call-sym-gen) 2959 (! tail-call-fn-gen))) 2959 (! pass-multiple-values-symbol) 2960 (! pass-multiple-values))) 2961 (when mvpass-label 2962 (@= mvpass-label))) 2963 (progn 2964 (if label-p 2965 (progn 2966 (! call-label (aref *backend-labels* 2))) 2967 (progn 2968 (if a-reg 2969 (x862-copy-register seg destreg a-reg) 2970 (x862-store-immediate seg func destreg)) 2971 (if symp 2972 (x862-call-symbol seg nil) 2973 (! call-known-function)))))) 2974 (if alternate-tail-call 2975 (progn 2976 (x862-unwind-stack seg xfer 0 0 *x862-tail-vsp*) 2977 (! jump (aref *backend-labels* *x862-tail-label*))) 2978 (progn 2979 (x862-unwind-stack seg xfer 0 0 #x7fffff) 2980 (if (and (not spread-p) nargs (%i<= nargs *x862-target-num-arg-regs*)) 2981 (progn 2982 (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) 2983 (x862-restore-full-lisp-context seg) 2984 (if label-p 2985 (! jump (aref *backend-labels* 1)) 2986 (progn 2987 (if symp 2988 (x862-call-symbol seg t) 2989 (! jump-known-function))))) 2990 (progn 2991 (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) 2992 (when label-p 2993 (x862-copy-register seg *x862-temp0* *x862-fn*)) 2994 2995 (cond ((or spread-p (null nargs)) 2996 (if symp 2997 (! tail-call-sym-gen) 2998 (! tail-call-fn-gen))) 2999 ((%i> nargs *x862-target-num-arg-regs*) 3000 (let* ((nstackargs (- nargs *x862-target-num-arg-regs*))) 3001 (if (and (or *x862-open-code-inline* 3002 (<= nstackargs 3))) 3003 (let* ((nstackbytes (ash nstackargs *x862-target-node-shift*))) 3004 (unless (= nstackbytes *x862-vstack*) 3005 (if (>= *x862-vstack* (ash nstackbytes 1)) 3006 ;; If there's room in the caller's 3007 ;; frame beneath the outgoing args, 3008 ;; pop them. This avoids the use 3009 ;; of a temp reg, but can't deal 3010 ;; with the overlap situation if 3011 ;; that constraint isn't met. 3012 (do* ((n nstackargs (1- n))) 3013 ((= n 0)) 3014 (declare (fixnum n)) 3015 (! pop-outgoing-arg n)) 3016 (let* ((temp 3017 (target-arch-case 3018 (:x8664 ($ x8664::temp2)) 3019 (:x8632 ($ x8632::temp1))))) 3020 3021 (dotimes (i nstackargs) 3022 (! slide-nth-arg i nstackargs temp)) 3023 (target-arch-case 3024 (:x8632 3025 ;; x8632::temp1 = x8632::nargs 3026 (remove-dll-node set-nargs-vinsn) 3027 (! set-nargs nargs))))) 3028 (! set-tail-vsp nstackargs)) 3029 (! prepare-tail-call) 3030 (if symp 3031 (! jump-known-symbol) 3032 (! jump-known-function))) 3033 (if symp 3034 (! tail-call-sym-slide) 3035 (! tail-call-fn-slide))))) 3036 (t 3037 (! restore-full-lisp-context) 3038 (if symp 3039 (! jump-known-symbol) 3040 (! jump-known-function))))))))) 3041 ;; The general (funcall) case: we don't know (at compile-time) 3042 ;; for sure whether we've got a symbol or a (local, constant) 3043 ;; function. 3044 (progn 3045 (unless (or (fixnump fn) (typep fn 'lreg)) 3046 (x862-one-targeted-reg-form seg fn destreg)) 3047 (if (not tail-p) 3048 (if (x862-mvpass-p xfer) 3049 (progn (! pass-multiple-values) 3050 (when mvpass-label 3051 (@= mvpass-label))) 3052 (! funcall)) 3053 (cond ((or (null nargs) spread-p) 3054 (! tail-funcall-gen)) 2960 3055 ((%i> nargs *x862-target-num-arg-regs*) 2961 (if symp 2962 (! tail-call-sym-slide) 2963 (! tail-call-fn-slide))) 3056 (! tail-funcall-slide)) 2964 3057 (t 2965 (if symp 2966 (! tail-call-sym-vsp) 2967 (! tail-call-fn-vsp))))))))) 2968 ;; The general (funcall) case: we don't know (at compile-time) 2969 ;; for sure whether we've got a symbol or a (local, constant) 2970 ;; function. 2971 (progn 2972 (unless (or (fixnump fn) (typep fn 'lreg)) 2973 (x862-one-targeted-reg-form seg fn destreg)) 2974 (if (not tail-p) 2975 (if (x862-mvpass-p xfer) 2976 (progn (! pass-multiple-values) 2977 (when mvpass-label 2978 (@= mvpass-label))) 2979 (! funcall)) 2980 (cond ((or (null nargs) spread-p) 2981 (! tail-funcall-gen)) 2982 ((%i> nargs *x862-target-num-arg-regs*) 2983 (! tail-funcall-slide)) 2984 (t 2985 (! restore-full-lisp-context) 2986 (! tail-funcall))))))) 2987 nil)) 3058 (! restore-full-lisp-context) 3059 (! tail-funcall)))))))) 3060 nil))) 2988 3061 2989 3062 (defun x862-seq-fbind (seg vreg xfer vars afuncs body p2decls) … … 3194 3267 n))) 3195 3268 3196 (defun x862-arglist (seg args &optional mv-label )3269 (defun x862-arglist (seg args &optional mv-label suppress-frame-reservation) 3197 3270 (with-x86-local-vinsn-macros (seg) 3198 3271 (when mv-label 3199 3272 (x862-vpush-label seg (aref *backend-labels* mv-label))) 3200 (when ( car args)3273 (when (and (car args) (not suppress-frame-reservation)) 3201 3274 (! reserve-outgoing-frame) 3202 3275 (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil)
Note:
See TracChangeset
for help on using the changeset viewer.
