(inst word 0))
(let* ((entry-point (gen-label)))
(emit-label entry-point)
- (inst compute-code-from-fn code-tn lip-tn entry-point temp))
+ (inst compute-code-from-lip code-tn lip-tn entry-point temp))
;; FIXME alpha port has a ### note here saying we should "save it
;; on the stack" so that GC sees it. No idea what "it" is -dan 20020110
;; Build our stack frames.
,@(unless (or (eq return :tail) variable)
'((:move-args :full-call)))
- (:vop-var vop)
- (:info ,@(unless (or variable (eq return :tail)) '(arg-locs))
- ,@(unless variable '(nargs))
- ,@(when (eq return :fixed) '(nvals)))
+ (:vop-var vop)
+ (:info ,@(unless (or variable (eq return :tail)) '(arg-locs))
+ ,@(unless variable '(nargs))
+ ,@(when (eq return :fixed) '(nvals))
+ step-instrumenting)
(:ignore
,@(unless (or variable (eq return :tail)) '(arg-locs))
,@(when (eq return :fixed)
'((:temporary (:scs (descriptor-reg) :from :eval) move-temp)))
+ (:temporary (:scs (descriptor-reg) :to :eval) stepping)
+
,@(unless (eq return :tail)
'((:temporary (:scs (non-descriptor-reg)) temp)
(:temporary (:sc control-stack :offset nfp-save-offset) nfp-save)))
15
(if (eq return :unknown) 25 0))
(trace-table-entry trace-table-call-site)
+
(let* ((cur-nfp (current-nfp-tn vop))
,@(unless (eq return :tail)
'((lra-label (gen-label))))
+ (step-done-label (gen-label))
(filler
(remove nil
(list :load-nargs
'(if (> nargs register-arg-count)
(move cfp-tn new-fp)
(move cfp-tn csp-tn))))))
- ((nil))))))
+ ((nil)))))
+ (insert-step-instrumenting (callable-tn)
+ ;; Conditionally insert a conditional trap:
+ (when step-instrumenting
+ ;; Get the symbol-value of SB!IMPL::*STEPPING*
+ (loadw stepping
+ null-tn
+ (+ symbol-value-slot
+ (truncate (static-symbol-offset 'sb!impl::*stepping*)
+ n-word-bytes))
+ other-pointer-lowtag)
+ (inst cmpw stepping null-tn)
+ ;; If it's not null, trap.
+ (inst beq step-done-label)
+ ;; CONTEXT-PC will be pointing here when the
+ ;; interrupt is handled, not after the UNIMP.
+ (note-this-location vop :step-before-vop)
+ ;; Construct a trap code with the low bits from
+ ;; SINGLE-STEP-AROUND-TRAP and the high bits from
+ ;; the register number of CALLABLE-TN.
+ (inst unimp (logior single-step-around-trap
+ (ash (reg-tn-encoding callable-tn)
+ 5)))
+ (emit-label step-done-label))))
,@(if named
`((sc-case name
(descriptor-reg (move name-pass name))
(loadw name-pass code-tn (tn-offset name)
other-pointer-lowtag)
(do-next-filler)))
+ ;; The step instrumenting must be done after
+ ;; FUNCTION is loaded, but before ENTRY-POINT is
+ ;; calculated.
+ (insert-step-instrumenting name-pass)
(loadw entry-point name-pass fdefn-raw-addr-slot
other-pointer-lowtag)
(do-next-filler))
(loadw function lexenv closure-fun-slot
fun-pointer-lowtag)
(do-next-filler)
+ ;; The step instrumenting must be done before
+ ;; after FUNCTION is loaded, but before ENTRY-POINT
+ ;; is calculated.
+ (insert-step-instrumenting function)
(inst addi entry-point function
(- (ash simple-fun-code-offset word-shift)
fun-pointer-lowtag))
(define-full-call call-variable nil :fixed t)
(define-full-call multiple-call-variable nil :unknown t)
-
;;; Defined separately, since needs special code that BLT's the
;;; arguments down.
(define-vop (tail-call-variable)
(function-arg :scs (descriptor-reg) :target lexenv)
(old-fp-arg :scs (any-reg) :target old-fp)
(lra-arg :scs (descriptor-reg) :target lra))
-
(:temporary (:sc any-reg :offset nl0-offset :from (:argument 0)) args)
(:temporary (:sc any-reg :offset lexenv-offset :from (:argument 1)) lexenv)
(:temporary (:sc any-reg :offset ocfp-offset :from (:argument 2)) old-fp)
(:temporary (:sc any-reg :offset lra-offset :from (:argument 3)) lra)
-
-
+ (:temporary (:sc any-reg) temp)
(:vop-var vop)
-
(:generator 75
-
;; Move these into the passing locations if they are not already there.
(move args args-arg)
(move lexenv function-arg)
(move old-fp old-fp-arg)
(move lra lra-arg)
-
-
;; Clear the number stack if anything is there.
(let ((cur-nfp (current-nfp-tn vop)))
(when cur-nfp
(inst addi nsp-tn cur-nfp
(- (bytes-needed-for-non-descriptor-stack-frame)
number-stack-displacement))))
-
-
- (inst ba (make-fixup 'tail-call-variable :assembly-routine))))
+ (inst lr temp (make-fixup 'tail-call-variable :assembly-routine))
+ (inst mtlr temp)
+ (inst blr)))
\f
;;;; Unknown values return:
(lra-arg :scs (descriptor-reg) :to (:eval 1))
(vals-arg :scs (any-reg) :target vals)
(nvals-arg :scs (any-reg) :target nvals))
-
(:temporary (:sc any-reg :offset nl1-offset :from (:argument 0)) old-fp)
(:temporary (:sc descriptor-reg :offset lra-offset :from (:argument 1)) lra)
(:temporary (:sc any-reg :offset nl0-offset :from (:argument 2)) vals)
(:temporary (:sc any-reg :offset nargs-offset :from (:argument 3)) nvals)
(:temporary (:sc descriptor-reg :offset a0-offset) a0)
(:temporary (:scs (interior-reg)) lip)
-
-
+ (:temporary (:sc any-reg) temp)
(:vop-var vop)
-
(:generator 13
(trace-table-entry trace-table-fun-epilogue)
(let ((not-single (gen-label)))
(inst addi nsp-tn cur-nfp
(- (bytes-needed-for-non-descriptor-stack-frame)
number-stack-displacement))))
-
;; Check for the single case.
(inst cmpwi nvals-arg (fixnumize 1))
(inst lwz a0 vals-arg 0)
(inst bne not-single)
-
;; Return with one value.
(move csp-tn cfp-tn)
(move cfp-tn old-fp-arg)
(lisp-return lra-arg lip :offset 2)
-
;; Nope, not the single case.
(emit-label not-single)
(move old-fp old-fp-arg)
(move lra lra-arg)
(move vals vals-arg)
(move nvals nvals-arg)
- (inst ba (make-fixup 'return-multiple :assembly-routine)))
+ (inst lr temp (make-fixup 'return-multiple :assembly-routine))
+ (inst mtlr temp)
+ (inst blr))
(trace-table-entry trace-table-normal)))
\f
;;;; XEP hackery:
(emit-label loop)
;; *--dst = *--src, --count
- (inst addi src src (- n-word-bytes))
+ (inst lwzu temp src (- n-word-bytes))
(inst addic. count count (- (fixnumize 1)))
- (loadw temp src)
- (inst addi dst dst (- n-word-bytes))
- (storew temp dst)
+ (inst stwu temp dst (- n-word-bytes))
(inst bgt loop)
(emit-label do-regs)
(let* ((enter (gen-label))
(loop (gen-label))
(done (gen-label))
- (dx-p (node-stack-allocate-p node))
- (alloc-area-tn (if dx-p csp-tn alloc-tn)))
+ (dx-p (node-stack-allocate-p node)))
(move context context-arg)
(move count count-arg)
;; Check to see if there are any arguments.
;; We need to do this atomically.
(pseudo-atomic (pa-flag)
- (when dx-p
- (align-csp temp))
;; Allocate a cons (2 words) for each item.
- (inst clrrwi result alloc-area-tn n-lowtag-bits)
- (inst ori result result list-pointer-lowtag)
- (move dst result)
- (inst slwi temp count 1)
- (inst add alloc-area-tn alloc-area-tn temp)
+ (if dx-p
+ (progn
+ (align-csp temp)
+ (inst clrrwi result csp-tn n-lowtag-bits)
+ (inst ori result result list-pointer-lowtag)
+ (move dst result)
+ (inst slwi temp count 1)
+ (inst add csp-tn csp-tn temp))
+ (progn
+ (inst slwi temp count 1)
+ (allocation result temp list-pointer-lowtag
+ :temp-tn dst
+ :flag-tn pa-flag)
+ (move dst result)))
(inst b enter)
;; Compute the next cons and store it in the current one.
(frob unknown-key-arg-error unknown-key-arg-error
sb!c::%unknown-key-arg-error key)
(frob nil-fun-returned-error nil-fun-returned-error nil fun))
+
+(define-vop (step-instrument-before-vop)
+ (:temporary (:scs (descriptor-reg)) stepping)
+ (:policy :fast-safe)
+ (:vop-var vop)
+ (:generator 3
+ ;; Get the symbol-value of SB!IMPL::*STEPPING*
+ (loadw stepping
+ null-tn
+ (+ symbol-value-slot
+ (truncate (static-symbol-offset 'sb!impl::*stepping*)
+ n-word-bytes))
+ other-pointer-lowtag)
+ (inst cmpw stepping null-tn)
+ ;; If it's not null, trap.
+ (inst beq DONE)
+ ;; CONTEXT-PC will be pointing here when the interrupt is handled,
+ ;; not after the UNIMP.
+ (note-this-location vop :step-before-vop)
+ ;; CALLEE-REGISTER-OFFSET isn't needed for before-traps, so we
+ ;; can just use a bare SINGLE-STEP-BEFORE-TRAP as the code.
+ (inst unimp single-step-before-trap)
+ DONE))