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
......@@ -17,58 +17,7 @@
;;;
;;; Debugged by Paul F. Werkowski -- Spring 1995.
;;;
(in-package :x86)
;;;; From from signed/unsigned
(in-package "X86")
#+assembler ; we don't want a vop for this one.
(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))
;;; But we do everything inline now that we have a better pseudo-atomic.
......@@ -232,20 +232,17 @@
;;; Arg is a fixnum or bignum, figure out which and load if necessary.
(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)))
(: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
(move eax x)
(inst test al-tn 3)
(inst jmp :z fixnum)
(loadw y eax bignum-digits-offset other-pointer-type)
(inst test x 3)
(inst jmp :nz BIGNUM)
(move y x)
(inst sar y 2)
(inst jmp done)
FIXNUM
(inst sar eax 2)
(move y eax)
BIGNUM
(loadw y x bignum-digits-offset other-pointer-type)
DONE))
;;;
(define-move-vop move-to-word/integer :move
......@@ -278,43 +275,28 @@
;;; 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.
;;;
#+nil
(define-vop (move-from-signed)
(: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)
(:args (x :scs (signed-reg unsigned-reg) :to :save))
(:temporary (:sc unsigned-reg) temp)
(:results (y :scs (any-reg descriptor-reg)))
(: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)
(:generator 20
(assert (not (location= x y)))
(assert (not (location= x temp)))
(assert (not (location= y temp)))
(let ((bignum (gen-label))
(done (gen-label)))
(inst mov y x)
(inst shl y 1)
(inst jmp :o bignum)
(inst shl y 1)
(inst jmp :o bignum)
(inst lea temp (make-ea :dword :base x :disp #x20000000))
(inst cmp temp #x40000000)
(inst jmp :nb bignum)
(inst lea y (make-ea :dword :index x :scale 4))
(emit-label done)
(assemble (*elsewhere*)
(emit-label bignum)
(with-fixed-allocation
(y bignum-type (+ bignum-digits-offset 1) node)
(with-fixed-allocation (y bignum-type
(+ bignum-digits-offset 1) node)
(storew x y bignum-digits-offset other-pointer-type))
(inst jmp done)))))
;;;
......@@ -325,23 +307,6 @@
;;; 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.
;;;
#+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)
(:args (x :scs (signed-reg unsigned-reg) :to :save))
(: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