(n-src src))
`(unless (location= ,n-dst ,n-src)
(sc-case ,n-dst
- (single-reg
- (inst movss ,n-dst ,n-src))
- (double-reg
- (inst movsd ,n-dst ,n-src))
+ ((single-reg complex-single-reg)
+ (aver (xmm-register-p ,n-src))
+ (inst movaps ,n-dst ,n-src))
+ ((double-reg complex-double-reg)
+ (aver (xmm-register-p ,n-src))
+ (inst movapd ,n-dst ,n-src))
(t
(inst mov ,n-dst ,n-src))))))
(once-only ((value value))
`(cond ((and (integerp ,value)
(not (typep ,value '(signed-byte 32))))
- (multiple-value-bind (lo hi) (dwords-for-quad ,value)
- (inst mov (make-ea-for-object-slot-half
- ,ptr ,slot ,lowtag) lo)
- (inst mov (make-ea-for-object-slot-half
- ,ptr (+ ,slot 1/2) ,lowtag) hi)))
+ (inst mov temp-reg-tn ,value)
+ (inst mov (make-ea-for-object-slot ,ptr ,slot ,lowtag) temp-reg-tn))
(t
(inst mov (make-ea-for-object-slot ,ptr ,slot ,lowtag) ,value)))))
;;; node-var then it is used to make an appropriate speed vs size
;;; decision.
-(defun allocation-dynamic-extent (alloc-tn size)
+(defun allocation-dynamic-extent (alloc-tn size lowtag)
(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)
+ (inst lea alloc-tn (make-ea :byte :base rsp-tn :disp lowtag))
(values))
;;; This macro should only be used inside a pseudo-atomic section,
;;; which should also cover subsequent initialization of the
;;; object.
-(defun allocation-tramp (alloc-tn size &optional ignored)
- (declare (ignore ignored))
+(defun allocation-tramp (alloc-tn size lowtag)
(inst push size)
(inst lea temp-reg-tn (make-ea :qword
:disp (make-fixup "alloc_tramp" :foreign)))
(inst call temp-reg-tn)
(inst pop alloc-tn)
+ (when lowtag
+ (inst lea alloc-tn (make-ea :byte :base alloc-tn :disp lowtag)))
(values))
-(defun allocation (alloc-tn size &optional ignored dynamic-extent)
+(defun allocation (alloc-tn size &optional ignored dynamic-extent lowtag)
(declare (ignore ignored))
(when dynamic-extent
- (allocation-dynamic-extent alloc-tn size)
+ (allocation-dynamic-extent alloc-tn size lowtag)
(return-from allocation (values)))
(let ((NOT-INLINE (gen-label))
(DONE (gen-label))
:scale 1 :disp
(make-fixup "boxed_region" :foreign 8))))
(cond (in-elsewhere
- (allocation-tramp alloc-tn size))
+ (allocation-tramp alloc-tn size lowtag))
(t
(inst mov temp-reg-tn free-pointer)
(if (tn-p size)
(inst cmp end-addr alloc-tn)
(inst jmp :be NOT-INLINE)
(inst mov free-pointer alloc-tn)
- (inst mov alloc-tn temp-reg-tn)
+ (if lowtag
+ (inst lea alloc-tn (make-ea :byte :base temp-reg-tn :disp lowtag))
+ (inst mov alloc-tn temp-reg-tn))
(emit-label DONE)
(assemble (*elsewhere*)
(emit-label NOT-INLINE)
(cond ((numberp size)
- (allocation-tramp alloc-tn size))
+ (allocation-tramp alloc-tn size lowtag))
(t
(inst sub alloc-tn free-pointer)
- (allocation-tramp alloc-tn alloc-tn)))
- (inst jmp DONE))
- (values)))))
+ (allocation-tramp alloc-tn alloc-tn lowtag)))
+ (inst jmp DONE))))
+ (values)))
;;; Allocate an other-pointer object of fixed SIZE with a single word
;;; header having the specified WIDETAG value. The result is placed in
(bug "empty &body in WITH-FIXED-ALLOCATION"))
(once-only ((result-tn result-tn) (size size) (stack-allocate-p stack-allocate-p))
`(maybe-pseudo-atomic ,stack-allocate-p
- (allocation ,result-tn (pad-data-block ,size) ,inline ,stack-allocate-p)
+ (allocation ,result-tn (pad-data-block ,size) ,inline ,stack-allocate-p
+ other-pointer-lowtag)
(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))
+ ,result-tn 0 other-pointer-lowtag)
,@forms)))
\f
;;;; error code
-(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
- (defun emit-error-break (vop kind code values)
- (let ((vector (gensym)))
- `((progn
- #!-darwin (inst int 3) ; i386 breakpoint instruction
- ;; On Darwin, we need to use #x0b0f instead of int3 in order
- ;; to generate a SIGILL instead of a SIGTRAP as darwin/x86
- ;; doesn't seem to be reliably firing SIGTRAP
- ;; handlers. Hopefully this will be fixed by Apple at a
- ;; later date. Do the same on x86-64 as we do on x86 until this gets
- ;; sorted out.
- #!+darwin (inst word #x0b0f))
-
- ;; The return PC points here; note the location for the debugger.
- (let ((vop ,vop))
- (when vop
- (note-this-location vop :internal-error)))
- (inst byte ,kind) ; eg trap_Xyyy
- (with-adjustable-vector (,vector) ; interr arguments
- (write-var-integer (error-number-or-lose ',code) ,vector)
- ,@(mapcar (lambda (tn)
- `(let ((tn ,tn))
- ;; classic CMU CL comment:
- ;; zzzzz jrd here. tn-offset is zero for constant
- ;; tns.
- (write-var-integer (make-sc-offset (sc-number
- (tn-sc tn))
- (or (tn-offset tn)
- 0))
- ,vector)))
- values)
- (inst byte (length ,vector))
- (dotimes (i (length ,vector))
- (inst byte (aref ,vector i))))))))
-
-(defmacro error-call (vop error-code &rest values)
+(defun emit-error-break (vop kind code values)
+ (assemble ()
+ #!-ud2-breakpoints
+ (inst int 3) ; i386 breakpoint instruction
+ ;; On Darwin, we need to use #x0b0f instead of int3 in order
+ ;; to generate a SIGILL instead of a SIGTRAP as darwin/x86
+ ;; doesn't seem to be reliably firing SIGTRAP
+ ;; handlers. Hopefully this will be fixed by Apple at a
+ ;; later date. Do the same on x86-64 as we do on x86 until this gets
+ ;; sorted out.
+ #!+ud2-breakpoints
+ (inst word #x0b0f)
+ ;; The return PC points here; note the location for the debugger.
+ (when vop
+ (note-this-location vop :internal-error))
+ (inst byte kind) ; eg trap_Xyyy
+ (with-adjustable-vector (vector) ; interr arguments
+ (write-var-integer code vector)
+ (dolist (tn values)
+ ;; classic CMU CL comment:
+ ;; zzzzz jrd here. tn-offset is zero for constant
+ ;; tns.
+ (write-var-integer (make-sc-offset (sc-number (tn-sc tn))
+ (or (tn-offset tn) 0))
+ vector))
+ (inst byte (length vector))
+ (dotimes (i (length vector))
+ (inst byte (aref vector i))))))
+
+(defun error-call (vop error-code &rest values)
#!+sb-doc
"Cause an error. ERROR-CODE is the error to cause."
- (cons 'progn
- (emit-error-break vop error-trap error-code values)))
+ (emit-error-break vop error-trap (error-number-or-lose error-code) values))
-(defmacro generate-error-code (vop error-code &rest values)
+(defun generate-error-code (vop error-code &rest values)
#!+sb-doc
"Generate-Error-Code Error-code Value*
Emit code for an error with the specified Error-Code and context Values."
- `(assemble (*elsewhere*)
- (let ((start-lab (gen-label)))
- (emit-label start-lab)
- (error-call ,vop ,error-code ,@values)
+ (assemble (*elsewhere*)
+ (let ((start-lab (gen-label)))
+ (emit-label start-lab)
+ (emit-error-break vop error-trap (error-number-or-lose error-code) values)
start-lab)))
\f
(progn ,@body)
(pseudo-atomic ,@body)))
+;;; Unsafely clear pa flags so that the image can properly lose in a
+;;; pa section.
+#!+sb-thread
+(defmacro %clear-pseudo-atomic ()
+ '(inst mov (make-ea :qword :base thread-base-tn
+ :disp (* 8 thread-pseudo-atomic-bits-slot))
+ 0))
+
#!+sb-thread
(defmacro pseudo-atomic (&rest forms)
(with-unique-names (label)
`(let ((,label (gen-label)))
- (inst or (make-ea :byte
- :base thread-base-tn
- :disp (* 8 thread-pseudo-atomic-bits-slot))
- (fixnumize 1))
- ,@forms
- (inst xor (make-ea :byte
- :base thread-base-tn
- :disp (* 8 thread-pseudo-atomic-bits-slot))
- (fixnumize 1))
- (inst jmp :z ,label)
- ;; if PAI was set, interrupts were disabled at the same
- ;; time using the process signal mask.
- (inst break pending-interrupt-trap)
- (emit-label ,label))))
+ (inst mov (make-ea :qword
+ :base thread-base-tn
+ :disp (* 8 thread-pseudo-atomic-bits-slot))
+ rbp-tn)
+ ,@forms
+ (inst xor (make-ea :qword
+ :base thread-base-tn
+ :disp (* 8 thread-pseudo-atomic-bits-slot))
+ rbp-tn)
+ (inst jmp :z ,label)
+ ;; if PAI was set, interrupts were disabled at the same time
+ ;; using the process signal mask.
+ (inst break pending-interrupt-trap)
+ (emit-label ,label))))
#!-sb-thread
(defmacro pseudo-atomic (&rest forms)
(with-unique-names (label)
`(let ((,label (gen-label)))
- ;; FIXME: The MAKE-EA noise should become a MACROLET macro or
- ;; something. (perhaps SVLB, for static variable low byte)
- (inst or (make-ea :byte :disp (+ nil-value
- (static-symbol-offset
- '*pseudo-atomic-bits*)
- (ash symbol-value-slot word-shift)
- (- other-pointer-lowtag)))
- (fixnumize 1))
- ,@forms
- (inst xor (make-ea :byte :disp (+ nil-value
- (static-symbol-offset
- '*pseudo-atomic-bits*)
- (ash symbol-value-slot word-shift)
- (- other-pointer-lowtag)))
- (fixnumize 1))
- (inst jmp :z ,label)
- ;; if PAI was set, interrupts were disabled at the same time
- ;; using the process signal mask.
- (inst break pending-interrupt-trap)
- (emit-label ,label))))
-
-
+ ;; FIXME: The MAKE-EA noise should become a MACROLET macro or
+ ;; something. (perhaps SVLB, for static variable low byte)
+ (inst mov (make-ea :qword :disp (+ nil-value
+ (static-symbol-offset
+ '*pseudo-atomic-bits*)
+ (ash symbol-value-slot word-shift)
+ (- other-pointer-lowtag)))
+ rbp-tn)
+ ,@forms
+ (inst xor (make-ea :qword :disp (+ nil-value
+ (static-symbol-offset
+ '*pseudo-atomic-bits*)
+ (ash symbol-value-slot word-shift)
+ (- other-pointer-lowtag)))
+ rbp-tn)
+ (inst jmp :z ,label)
+ ;; if PAI was set, interrupts were disabled at the same time
+ ;; using the process signal mask.
+ (inst break pending-interrupt-trap)
+ (emit-label ,label))))
\f
;;;; indexed references
(:result-types ,el-type)
(:generator 5
(move rax old-value)
- #!+sb-thread
- (inst lock)
(inst cmpxchg (make-ea :qword :base object :index index
+ :scale (ash 1 (- word-shift n-fixnum-tag-bits))
:disp (- (* ,offset n-word-bytes) ,lowtag))
- new-value)
+ new-value :lock)
(move value rax)))))
(defmacro define-full-reffer (name type offset lowtag scs el-type &optional translate)
(:result-types ,el-type)
(:generator 3 ; pw was 5
(inst mov value (make-ea :qword :base object :index index
+ :scale (ash 1 (- word-shift n-fixnum-tag-bits))
:disp (- (* ,offset n-word-bytes)
,lowtag)))))
(define-vop (,(symbolicate name "-C"))
(:result-types ,el-type)
(:generator 3 ; pw was 5
(inst mov value (make-ea :qword :base object :index index
+ :scale (ash 1 (- word-shift n-fixnum-tag-bits))
:disp (- (* (+ ,offset offset) n-word-bytes)
,lowtag)))))
(define-vop (,(symbolicate name "-C"))
(:result-types ,el-type)
(:generator 4 ; was 5
(inst mov (make-ea :qword :base object :index index
+ :scale (ash 1 (- word-shift n-fixnum-tag-bits))
:disp (- (* ,offset n-word-bytes) ,lowtag))
value)
(move result value)))
(:result-types ,el-type)
(:generator 4 ; was 5
(inst mov (make-ea :qword :base object :index index
+ :scale (ash 1 (- word-shift n-fixnum-tag-bits))
:disp (- (* (+ ,offset offset) n-word-bytes) ,lowtag))
value)
(move result value)))
collection."
(if objects
(let ((pins (make-gensym-list (length objects)))
- (wpo (block-gensym "WPO")))
+ (wpo (gensym "WITH-PINNED-OBJECTS-THUNK")))
;; BODY is stuffed in a function to preserve the lexical
;; environment.
`(flet ((,wpo () (progn ,@body)))
+ (declare (muffle-conditions compiler-note))
;; PINS are dx-allocated in case the compiler for some
;; unfathomable reason decides to allocate value-cells
;; for them -- since we have DX value-cells on x86oid