Skip to content
Permalink
Browse files

x86-64: Add better abstraction for CPU register in the assembler

Any TN which refers to a register is converted to an instance of REG
just prior to calling the instruction emitter. This makes it simple
to distinguish registers from stack locations. Additionally the function
which returns a register in a different size no longer has anything
to do with the VM's storage classes.

We can henceforth remove all of the global variables which hold
TNs in sizes other than :qword (e.g. AL-TN, AX-TN, EAX-TN)
and we can probably remove their storage classes, except for potential
problems with third-party libraries that use define-vop and assume
that they can request vop temporaries in arbitrary sizes.
  • Loading branch information...
snuglas committed Sep 6, 2018
1 parent 9b116ec commit adc83086ff26c46e647b22d76fe22d57889b6ace
@@ -251,12 +251,13 @@
sb-vm::map-stack-references
sb-vm::thread-profile-data-slot
sb-vm::thread-alloc-region-slot
sb-vm::primitive-object-size
;; need this for defining a vop which
;; tests the x86-64 allocation profiler
sb-vm::pseudo-atomic
;; Naughty outside-world code uses this.
sb-vm::thread-control-stack-start-slot
sb-vm::primitive-object-size))
;; Naughty outside-world code uses these.
#+x86-64 sb-vm::reg-in-size
sb-vm::thread-control-stack-start-slot))
(search "-OFFSET" (string symbol))
(search "-TN" (string symbol))))
((#.(find-package "SB-C")
@@ -1361,12 +1361,20 @@
(return-from op))
(.comment ; ignore it
(return-from op))))
(apply mnemonic operands segment operands))))
(apply mnemonic operands segment
(perform-operand-lowering operands)))))
(label (%emit-label segment **current-vop** operation))
(function (%emit-postit segment operation)))))
(finalize-segment segment)
segment))

;;; Most backends do not convert register TNs into a different type of
;;; internal object prior to handing the operands off to the emitter.
;;; x86-64 does have a different representation, which makes some of
;;; the emitter logic easier to understand.
#!-x86-64
(defun perform-operand-lowering (operands) operands)

(defun truncate-section-to-length (section)
(setf (section-last-buf section)
(subseq (section-last-buf section) 0 (section-buf-index section))))
@@ -1454,7 +1462,7 @@
;; operands prior to calling any instruction hooks. The spread arguments
;; allow the compiler to generate normal &OPTIONAL / &KEY parsing code
;; in lieu of our generating a destructuring-bind to achieve the same.
(apply mnemonic operands dest operands))))
(apply mnemonic operands dest (perform-operand-lowering operands)))))
(values))

(defun emit-label (label)
@@ -237,7 +237,7 @@
(define-binop logior 2 or
:c/unsigned=>unsigned
((let ((y (constantize y)))
(cond ((and (register-p r) (eql y -1)) ; special-case "OR reg, all-ones"
(cond ((and (gpr-tn-p r) (eql y -1)) ; special-case "OR reg, all-ones"
;; I have yet to elicit this case. Can it happen?
(inst mov r -1))
(t
@@ -1238,7 +1238,7 @@ constant shift greater than word length")))
(inst mov :dword temp-reg-tn y)
(return-from ensure-not-mem+mem (values x temp-reg-tn))))
(setq y (register-inline-constant :qword y)))
(cond ((or (gpr-p x) (gpr-p y))
(cond ((or (gpr-tn-p x) (gpr-tn-p y))
(values x y))
(t
(inst mov temp-reg-tn x)
@@ -1296,7 +1296,7 @@ constant shift greater than word length")))
(setq size :byte disp (1+ disp) y (ash y -8)))
(inst test size (ea disp rbp-tn) y)))
(t
(aver (gpr-p x))
(aver (gpr-tn-p x))
(if (and reducible-to-byte-p (<= (tn-offset x) 6)) ; 0, 2, 4, 6
;; Use upper byte of word reg (AX -> AH, BX -> BX ...)
(inst test :byte `(,x . :high-byte) (ash y -8))
@@ -1387,7 +1387,7 @@ constant shift greater than word length")))
(inst bt x y)))

(defun emit-optimized-cmp (x y)
(if (and (gpr-p x) (eql y 0))
(if (and (gpr-tn-p x) (eql y 0))
;; Amazingly (to me), use of TEST in lieu of CMP produces all the correct
;; flag bits for inequality comparison as well as EQL comparison.
;; You'd think that the Jxx instruction should examine _only_ the S flag,
@@ -955,8 +955,7 @@
(:vop-var vop)
(:generator 3
(when (or (location= y xmm)
(and (not (xmm-register-p x))
(xmm-register-p y)))
(and (not (xmm-tn-p x)) (xmm-tn-p y)))
(rotatef x y))
(sc-case x
(single-reg (setf xmm x))
@@ -988,8 +987,7 @@
(:vop-var vop)
(:generator 3
(when (or (location= y xmm)
(and (not (xmm-register-p x))
(xmm-register-p y)))
(and (not (xmm-tn-p x)) (xmm-tn-p y)))
(rotatef x y))
(sc-case x
(double-reg

0 comments on commit adc8308

Please sign in to comment.
You can’t perform that action at this time.