Commit 60d810f9 authored by Carl Shapiro's avatar Carl Shapiro
Browse files

Improve and clean-up some move VOPs.

* Remove the name dependence on EAX in move-to-word/integer.

* Change move-from-signed to do a fixnum check using one branch
  instead of two.

* Remove move-from-signed and move-from-unsigned assembly routines and
  the commented out code that refers to them.
parent f36a31aa
;;; -*- Mode: LISP; Syntax: Common-Lisp; Base: 10; Package: x86 -*- ;;; -*- Package: X86 -*-
;;; ;;;
;;; ********************************************************************** ;;; **********************************************************************
;;; This code was written as part of the CMU Common Lisp project at ;;; This code was written as part of the CMU Common Lisp project at
...@@ -17,58 +17,7 @@ ...@@ -17,58 +17,7 @@
;;; ;;;
;;; Debugged by Paul F. Werkowski -- Spring 1995. ;;; Debugged by Paul F. Werkowski -- Spring 1995.
;;; ;;;
(in-package :x86)
(in-package "X86")
;;;; From from signed/unsigned
#+assembler ; we don't want a vop for this one. ;;; But we do everything inline now that we have a better pseudo-atomic.
(define-assembly-routine
(move-from-signed)
((:temp eax unsigned-reg eax-offset)
(:temp ebx unsigned-reg ebx-offset))
(inst mov ebx eax)
(inst shl ebx 1)
(inst jmp :o bignum)
(inst shl ebx 1)
(inst jmp :o bignum)
(inst ret)
BIGNUM
(with-fixed-allocation (ebx bignum-type (+ bignum-digits-offset 1))
(storew eax ebx bignum-digits-offset other-pointer-type))
(inst ret))
#+assembler ; we don't want a vop for this one either.
(define-assembly-routine
(move-from-unsigned)
((:temp eax unsigned-reg eax-offset)
(:temp ebx unsigned-reg ebx-offset))
(inst test eax #xe0000000)
(inst jmp :nz bignum)
;; Fixnum
(inst mov ebx eax)
(inst shl ebx 2)
(inst ret)
BIGNUM
;;; Note: On the mips port space for a two word bignum is always
;;; allocated and the header size is set to either one or two words
;;; as appropriate. On the mips port this is faster, and smaller
;;; inline, but produces more garbage. The inline x86 version uses
;;; the same approach, but here we save garbage and allocate the
;;; smallest possible bignum.
(inst jmp :ns one-word-bignum)
(inst mov ebx eax)
;; Two word bignum
(with-fixed-allocation (ebx bignum-type (+ bignum-digits-offset 2))
(storew eax ebx bignum-digits-offset other-pointer-type))
(inst ret)
ONE-WORD-BIGNUM
(with-fixed-allocation (ebx bignum-type (+ bignum-digits-offset 1))
(storew eax ebx bignum-digits-offset other-pointer-type))
(inst ret))
...@@ -232,20 +232,17 @@ ...@@ -232,20 +232,17 @@
;;; Arg is a fixnum or bignum, figure out which and load if necessary. ;;; Arg is a fixnum or bignum, figure out which and load if necessary.
(define-vop (move-to-word/integer) (define-vop (move-to-word/integer)
(:args (x :scs (descriptor-reg) :target eax)) (:args (x :scs (descriptor-reg) :target y))
(:results (y :scs (signed-reg unsigned-reg))) (:results (y :scs (signed-reg unsigned-reg)))
(:note _N"integer to untagged word coercion") (:note _N"integer to untagged word coercion")
(:temporary (:sc unsigned-reg :offset eax-offset
:from (:argument 0) :to (:result 0) :target y) eax)
(:generator 4 (:generator 4
(move eax x) (inst test x 3)
(inst test al-tn 3) (inst jmp :nz BIGNUM)
(inst jmp :z fixnum) (move y x)
(loadw y eax bignum-digits-offset other-pointer-type) (inst sar y 2)
(inst jmp done) (inst jmp done)
FIXNUM BIGNUM
(inst sar eax 2) (loadw y x bignum-digits-offset other-pointer-type)
(move y eax)
DONE)) DONE))
;;; ;;;
(define-move-vop move-to-word/integer :move (define-move-vop move-to-word/integer :move
...@@ -278,45 +275,30 @@ ...@@ -278,45 +275,30 @@
;;; Result may be a bignum, so we have to check. Use a worst-case cost to make ;;; Result may be a bignum, so we have to check. Use a worst-case cost to make
;;; sure people know they may be number consing. ;;; sure people know they may be number consing.
;;; ;;;
#+nil
(define-vop (move-from-signed) (define-vop (move-from-signed)
(:args (x :scs (signed-reg unsigned-reg) :target eax)) (:args (x :scs (signed-reg unsigned-reg) :to :save))
(:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0)) eax) (:temporary (:sc unsigned-reg) temp)
(:temporary (:sc unsigned-reg :offset ebx-offset :to (:result 0) :target y)
ebx)
(:temporary (:sc unsigned-reg :offset ecx-offset
:from (:argument 0) :to (:result 0)) ecx)
(:ignore ecx)
(:results (y :scs (any-reg descriptor-reg))) (:results (y :scs (any-reg descriptor-reg)))
(:note _N"signed word to integer coercion") (:note _N"signed word to integer coercion")
(:generator 20
(move eax x)
(inst call (make-fixup 'move-from-signed :assembly-routine))
(move y ebx)))
;;;
;;; Faster inline version,
(define-vop (move-from-signed)
(:args (x :scs (signed-reg unsigned-reg) :to :result))
(:results (y :scs (any-reg descriptor-reg) :from :argument))
(:note _N"signed word to integer coercion")
(:node-var node) (:node-var node)
(:generator 20 (:generator 20
(assert (not (location= x y))) (assert (not (location= x y)))
(let ((bignum (gen-label)) (assert (not (location= x temp)))
(done (gen-label))) (assert (not (location= y temp)))
(inst mov y x) (let ((bignum (gen-label))
(inst shl y 1) (done (gen-label)))
(inst jmp :o bignum) (inst lea temp (make-ea :dword :base x :disp #x20000000))
(inst shl y 1) (inst cmp temp #x40000000)
(inst jmp :o bignum) (inst jmp :nb bignum)
(emit-label done) (inst lea y (make-ea :dword :index x :scale 4))
(emit-label done)
(assemble (*elsewhere*)
(emit-label bignum) (assemble (*elsewhere*)
(with-fixed-allocation (emit-label bignum)
(y bignum-type (+ bignum-digits-offset 1) node) (with-fixed-allocation (y bignum-type
(storew x y bignum-digits-offset other-pointer-type)) (+ bignum-digits-offset 1) node)
(inst jmp done))))) (storew x y bignum-digits-offset other-pointer-type))
(inst jmp done)))))
;;; ;;;
(define-move-vop move-from-signed :move (define-move-vop move-from-signed :move
(signed-reg) (descriptor-reg)) (signed-reg) (descriptor-reg))
...@@ -325,23 +307,6 @@ ...@@ -325,23 +307,6 @@
;;; Check for fixnum, and possibly allocate one or two word bignum result. Use ;;; Check for fixnum, and possibly allocate one or two word bignum result. Use
;;; a worst-case cost to make sure people know they may be number consing. ;;; a worst-case cost to make sure people know they may be number consing.
;;; ;;;
#+nil
(define-vop (move-from-unsigned)
(:args (x :scs (signed-reg unsigned-reg) :target eax))
(:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0)) eax)
(:temporary (:sc unsigned-reg :offset ebx-offset :to (:result 0) :target y)
ebx)
(:temporary (:sc unsigned-reg :offset ecx-offset
:from (:argument 0) :to (:result 0)) ecx)
(:ignore ecx)
(:results (y :scs (any-reg descriptor-reg)))
(:note _N"unsigned word to integer coercion")
(:generator 20
(move eax x)
(inst call (make-fixup 'move-from-unsigned :assembly-routine))
(move y ebx)))
;;;
;;; Faster inline version.
(define-vop (move-from-unsigned) (define-vop (move-from-unsigned)
(:args (x :scs (signed-reg unsigned-reg) :to :save)) (:args (x :scs (signed-reg unsigned-reg) :to :save))
(:temporary (:sc unsigned-reg) alloc) (:temporary (:sc unsigned-reg) alloc)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment