Changeset 14834


Ignore:
Timestamp:
Jun 21, 2011, 9:25:27 AM (8 years ago)
Author:
gb
Message:

Re-do the common FPR-tracking/targeting, so that aliased FPRs (as on
ARM and SPARC, for that matter) don't confict. (s0 and s1 conflict
with d0, s2 and s3 conflict with d1, etc.)

Fixes ticket:857 .

Consider s0-s15 (d0-d7) volatile on ARM.

Location:
trunk/source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/ARM/arm2.lisp

    r14823 r14834  
    28192819               (bregval (hard-regspec-value breg)))
    28202820          (if (eq bclass hard-reg-class-fpr)
    2821             (use-fp-temp bregval)
     2821            (use-fp-reg breg)
    28222822            (if (eq bclass hard-reg-class-gpr)
    28232823              (if (eq (get-regspec-mode breg) hard-reg-class-gpr-mode-node)
  • trunk/source/compiler/backend.lisp

    r14556 r14834  
    238238       (= (get-regspec-mode reg) hard-reg-class-fpr-mode-single)))
    239239
     240(defun target-fpr-mask (fpreg mode-name)
     241  (target-arch-case
     242   (:arm
     243    (ecase mode-name
     244      (:double-float (ash 3 (ash fpreg 1)))
     245      (:single-float (ash 1 fpreg))))
     246   (t
     247    (ash 1 fpreg))))
     248
     249
     250(defun use-fp-reg (fpr)
     251  (let* ((mode-name (if (eql (get-regspec-mode fpr) hard-reg-class-fpr-mode-single)
     252                      :single-float
     253                      :double-float))
     254         (regval (hard-regspec-value fpr)))
     255    (setq *available-backend-fp-temps* (logand *available-backend-fp-temps* (lognot (target-fpr-mask regval mode-name))))))
     256
    240257(defun use-fp-temp (n)
    241258    (setq *available-backend-fp-temps* (logand *available-backend-fp-temps* (lognot (ash 1 n))))
     
    243260
    244261(defun available-fp-temp (mask &optional (mode-name :double-float))
    245   (dotimes (bit (integer-length mask) (error "Bug: ran out of node fp registers."))
    246     (when (logbitp bit mask)
     262  (do* ((regno 0 (1+ regno))
     263        (regmask (target-fpr-mask regno mode-name)  (target-fpr-mask regno mode-name)))
     264       ((> regmask mask) (error "Bug: ran out of fp registers."))
     265    (when (eql regmask (logand mask regmask))
    247266      (let* ((mode (if (eq mode-name :double-float)
    248267                     hard-reg-class-fpr-mode-double
    249268                     hard-reg-class-fpr-mode-single)))
    250         (return (make-hard-fp-reg bit mode))))))
     269        (return (make-hard-fp-reg regno mode))))))
     270
     271(defun select-fp-temp (mode-name)
     272  (do* ((i 0 (1+ i))
     273        (fpr-mask (target-fpr-mask i mode-name) (target-fpr-mask i mode-name)))
     274       ((> fpr-mask *available-backend-fp-temps*) (compiler-bug "Bug: ran out of fp registers."))
     275    (when (= fpr-mask (logand fpr-mask *available-backend-fp-temps*))
     276      (return i))))
     277
    251278
    252279(defparameter *backend-all-lregs* ())
  • trunk/source/compiler/vinsn.lisp

    r14472 r14834  
    401401              (case class
    402402                (#.hard-reg-class-gpr (note-vinsn-sets-gpr vinsn value))
    403                 (#.hard-reg-class-fpr (note-vinsn-sets-fpr vinsn value))))
     403                (#.hard-reg-class-fpr (note-vinsn-sets-fpr-lreg vinsn lreg))))
    404404            (setf (svref vp i) lreg)
    405405            (pushnew vinsn (lreg-defs lreg))
     
    433433                            :class hard-reg-class-gpr
    434434                            :mode (gpr-mode-name-value class)))
     435        (:double-float
     436         (make-unwired-lreg (select-fp-temp :double-float)
     437                            :class hard-reg-class-fpr
     438                            :mode hard-reg-class-fpr-mode-double))
     439        (:single-float
     440         (make-unwired-lreg (select-fp-temp :single-float)
     441                            :class hard-reg-class-fpr
     442                            :mode hard-reg-class-fpr-mode-double))
    435443        (:lisp
    436444         (make-unwired-lreg
     
    471479          (logbitp value (vinsn-gprs-set element))
    472480          (if (eq class hard-reg-class-fpr)
    473             (logbitp value (vinsn-fprs-set element))))))))
     481            (let* ((mode-name (if (eql (get-regspec-mode reg) hard-reg-class-fpr-mode-single)
     482                                :single-float
     483                                :double-float))
     484                   (mask (target-fpr-mask value mode-name)))
     485              (eql mask (logand mask (vinsn-fprs-set element))))))))))
    474486
    475487;;; Return bitmasks of all GPRs and all FPRs set in the vinsns between
     
    480492         (fprs-set 0))
    481493    (do* ((element (dll-node-succ start) (dll-node-succ element)))
    482          ((eq element end) (values gprs-set fprs-set))n
     494         ((eq element end) (values gprs-set fprs-set))
    483495      (if (typep element 'vinsn)
    484496        (if (vinsn-attribute-p element :call)
  • trunk/source/compiler/vreg.lisp

    r13067 r14834  
    249249  (setf (vinsn-fprs-set vinsn) (logior (vinsn-fprs-set vinsn) (ash 1 fpr))))
    250250
     251(defun note-vinsn-sets-fpr-lreg (vinsn fpr)
     252  (setf (vinsn-fprs-set vinsn) (logior (vinsn-fprs-set vinsn)
     253                                       (target-fpr-mask (hard-regspec-value fpr)
     254                                                        (if (eql (get-regspec-mode fpr)
     255                                                                 hard-reg-class-fpr-mode-single)
     256                                                          :single-float
     257                                                          :double-float)))))
     258
     259
    251260(defun match-vreg (vreg spec vinsn vp n)
    252261  (declare (fixnum n))
     
    272281               (use-imm-temp vreg-value))
    273282              ((:single-float :double-float)
    274                (use-fp-temp vreg-value)
    275                (when result-p (note-vinsn-sets-fpr vinsn vreg-value)))
     283               (use-fp-reg vreg)
     284               (when result-p (note-vinsn-sets-fpr-lreg vinsn vreg)))
    276285              ((:imm t)
    277286               (when result-p (note-vinsn-sets-gpr vinsn vreg-value))
  • trunk/source/lib/armenv.lisp

    r14119 r14834  
    6161                            arm::imm2))
    6262
    63 (defconstant arm-temp-fp-regs (1- (ash 1 14)))
     63(defconstant arm-temp-fp-regs (1- (ash 1 16)))
    6464
    6565(defconstant arm-cr-fields (make-mask 0))
Note: See TracChangeset for help on using the changeset viewer.