X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fmacros.lisp;h=29601b552b5a3cd4157f6dd42c6149a41ba38319;hb=69d60b456b07a0256f08df0d02484f361ce5737c;hp=dc0247facef224548a6a74b111189f941d221741;hpb=4dc4761909992ceb346d003f3fb19e5c837ee985;p=sbcl.git diff --git a/src/compiler/x86-64/macros.lisp b/src/compiler/x86-64/macros.lisp index dc0247f..29601b5 100644 --- a/src/compiler/x86-64/macros.lisp +++ b/src/compiler/x86-64/macros.lisp @@ -11,31 +11,6 @@ (in-package "SB!VM") -;;; We can load/store into fp registers through the top of stack -;;; %st(0) (fr0 here). Loads imply a push to an empty register which -;;; then changes all the reg numbers. These macros help manage that. - -;;; Use this when we don't have to load anything. It preserves old tos -;;; value, but probably destroys tn with operation. -(defmacro with-tn@fp-top((tn) &body body) - `(progn - (unless (zerop (tn-offset ,tn)) - (inst fxch ,tn)) - ,@body - (unless (zerop (tn-offset ,tn)) - (inst fxch ,tn)))) - -;;; Use this to prepare for load of new value from memory. This -;;; changes the register numbering so the next instruction had better -;;; be a FP load from memory; a register load from another register -;;; will probably be loading the wrong register! -(defmacro with-empty-tn@fp-top((tn) &body body) - `(progn - (inst fstp ,tn) - ,@body - (unless (zerop (tn-offset ,tn)) - (inst fxch ,tn)))) ; save into new dest and restore st(0) - ;;;; instruction-like macros (defmacro move (dst src) @@ -149,6 +124,14 @@ ;;; node-var then it is used to make an appropriate speed vs size ;;; decision. +(defun allocation-dynamic-extent (alloc-tn size) + (inst sub rsp-tn size) + ;; see comment in x86/macros.lisp implementation of this + (inst and rsp-tn #.(lognot lowtag-mask)) + (aver (not (location= alloc-tn rsp-tn))) + (inst mov alloc-tn rsp-tn) + (values)) + ;;; This macro should only be used inside a pseudo-atomic section, ;;; which should also cover subsequent initialization of the ;;; object. @@ -161,8 +144,11 @@ (inst pop alloc-tn) (values)) -(defun allocation (alloc-tn size &optional ignored) +(defun allocation (alloc-tn size &optional ignored dynamic-extent) (declare (ignore ignored)) + (when dynamic-extent + (allocation-dynamic-extent alloc-tn size) + (return-from allocation (values))) (let ((NOT-INLINE (gen-label)) (DONE (gen-label)) ;; Yuck. @@ -214,14 +200,17 @@ ;;; header having the specified WIDETAG value. The result is placed in ;;; RESULT-TN. (defmacro with-fixed-allocation ((result-tn widetag size &optional inline) - &rest forms) - `(pseudo-atomic - (allocation ,result-tn (pad-data-block ,size) ,inline) - (storew (logior (ash (1- ,size) n-widetag-bits) ,widetag) - ,result-tn) - (inst lea ,result-tn - (make-ea :qword :base ,result-tn :disp other-pointer-lowtag)) - ,@forms)) + &body forms) + (unless forms + (bug "empty &body in WITH-FIXED-ALLOCATION")) + (once-only ((result-tn result-tn) (size size)) + `(pseudo-atomic + (allocation ,result-tn (pad-data-block ,size) ,inline) + (storew (logior (ash (1- ,size) n-widetag-bits) ,widetag) + ,result-tn) + (inst lea ,result-tn + (make-ea :qword :base ,result-tn :disp other-pointer-lowtag)) + ,@forms))) ;;;; error code (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute) @@ -280,6 +269,12 @@ ;;; the ATOMIC bit is bit 0, the INTERRUPTED bit is bit 1, and you check ;;; the C flag after the shift to see whether you were interrupted. +;;; FIXME: THIS NAME IS BACKWARDS! +(defmacro maybe-pseudo-atomic (really-p &body body) + `(if ,really-p + (progn ,@body) + (pseudo-atomic ,@body))) + (defmacro pseudo-atomic (&rest forms) (with-unique-names (label) `(let ((,label (gen-label)))