(ASSIGN (REGISTER (? target))
(CONS-POINTER (REGISTER (? type))
(REGISTER (? datum))))
- (cond ((let ((type (register-known-value type)))
- (and type (zero? type)))
- (assign-register->register target datum))
- ((register-copy-if-available datum 'GENERAL target)
- => (lambda (get-target!)
- ;; If we already have a suitable register for the target,
- ;; use bit field insertion to set the type.
- (let* ((type (standard-source! type))
- (target (get-target!))
- (lsb scheme-datum-width)
- (width scheme-type-width))
- (LAP (BFI X ,target ,type (&U ,lsb) (&U ,width))))))
- (else
- ;; Otherwise, no advantage to using bit field insertion since
- ;; we'd need two instructions anyway, so just shift and or.
- (standard-binary target type datum
- (lambda (target type datum)
- (LAP (LSL X ,target ,type (&U ,scheme-datum-width))
- (ORR X ,target ,target ,datum)))))))
+ (reuse-pseudo-register-alias! datum 'GENERAL
+ (lambda (alias)
+ ;; If we already have a reusable machine register loaded with the
+ ;; datum, use bit field insertion to set the type, and treat it
+ ;; as an alias for the target.
+ (let ((type (standard-source! type))
+ (lsb scheme-datum-width)
+ (width scheme-type-width))
+ (delete-dead-registers!)
+ (add-pseudo-register-alias! target alias)
+ (LAP (BFI X ,alias ,type (&U ,lsb) (&U ,width)))))
+ (lambda ()
+ ;; No advantage to using bit field insertion since we'd need two
+ ;; instructions anyway, so just shift and or.
+ (standard-binary target type datum
+ (lambda (target type datum)
+ (LAP (LSL X ,target ,type (&U ,scheme-datum-width))
+ (ORR X ,target ,target ,datum)))))))
(define-rule statement
(ASSIGN (REGISTER (? target))
(define-rule predicate
(PRED-1-ARG INDEX-FIXNUM? (REGISTER (? register)))
- (let ((temp (standard-move-to-temporary! register)))
+ (define (operate temp source)
(set-equal-branches!)
- (LAP (LSR X ,temp (&U ,(- scheme-datum-width 1)))
- (CMP X ,temp (&U ,(* 2 type-code:fixnum))))))
+ (LAP (LSR X ,temp ,source (&U ,(- scheme-datum-width 1)))
+ (CMP X ,temp (&U ,(* 2 type-code:fixnum)))))
+ ;; This basically is WITH-TEMPORARY-REGISTER-COPY! but without
+ ;; register references getting in the way.
+ (reuse-pseudo-register-alias! register 'GENERAL
+ (lambda (temp)
+ (need-register! temp)
+ (operate temp temp))
+ (lambda ()
+ (let* ((source (standard-source! register))
+ (temp (allocate-temporary-register! 'GENERAL)))
+ (operate temp source)))))
(define (zero-test! register)
(set-equal-zero-branches! register)