From cd23187a89f532f7b57e88b5392a7905e6ae3276 Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Fri, 5 Jun 2009 11:36:46 +0000 Subject: [PATCH] 1.0.29.2: implement fixnump/signed-word VOP on x86 and x86-64 * No need to cons up a bignum, and just one branch required. Eliminates a whole class of signed-word to integer coercions. --- NEWS | 2 ++ src/compiler/x86-64/type-vops.lisp | 16 ++++++++++++++++ src/compiler/x86/type-vops.lisp | 19 +++++++++++++++++++ version.lisp-expr | 2 +- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3f3fe5f8d..9e4f26528 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ;;;; -*- coding: utf-8; fill-column: 78 -*- + * optimization: more efficient type-checks for FIXNUMs when the value + is known to be a signed word on x86 and x86-64. * bug fix: on 64 bit platforms FILL worked incorrectly on arrays with upgraded element type (COMPLEX SINGLE-FLOAT), regression from 1.0.28.55. (thanks to Paul Khuong) diff --git a/src/compiler/x86-64/type-vops.lisp b/src/compiler/x86-64/type-vops.lisp index 1298a5e22..d8e49e0ac 100644 --- a/src/compiler/x86-64/type-vops.lisp +++ b/src/compiler/x86-64/type-vops.lisp @@ -190,6 +190,22 @@ (inst mov tmp value) (inst shr tmp n-positive-fixnum-bits))) +(define-vop (fixnump/signed-byte-64 type-predicate) + (:args (value :scs (signed-reg))) + (:info) + (:conditional :z) + (:arg-types signed-num) + (:translate fixnump) + (:generator 5 + ;; Hackers Delight, p. 53: signed + ;; a <= x <= a + 2^n - 1 + ;; is equivalent to unsigned + ;; ((x-a) >> n) = 0 + (inst mov rax-tn #.(- sb!xc:most-negative-fixnum)) + (inst add rax-tn value) + (inst shr rax-tn #.(integer-length (- sb!xc:most-positive-fixnum + sb!xc:most-negative-fixnum))))) + ;;; A (SIGNED-BYTE 64) can be represented with either fixnum or a bignum with ;;; exactly one digit. diff --git a/src/compiler/x86/type-vops.lisp b/src/compiler/x86/type-vops.lisp index 9d53fe955..0284ae4dd 100644 --- a/src/compiler/x86/type-vops.lisp +++ b/src/compiler/x86/type-vops.lisp @@ -212,8 +212,27 @@ (:arg-types unsigned-num) (:translate fixnump) (:generator 5 + ;; We could encode this with :Z and SHR, analogously to the signed-byte-32 + ;; case below -- as we do on x86-64 -- but that costs us an extra + ;; register. Compromises... (inst cmp value #.sb!xc:most-positive-fixnum))) +(define-vop (fixnump/signed-byte-32 type-predicate) + (:args (value :scs (signed-reg))) + (:info) + (:conditional :z) + (:arg-types signed-num) + (:translate fixnump) + (:generator 5 + ;; Hackers Delight, p. 53: signed + ;; a <= x <= a + 2^n - 1 + ;; is equivalent to unsigned + ;; ((x-a) >> n) = 0 + (inst mov eax-tn value) + (inst sub eax-tn #.sb!xc:most-negative-fixnum) + (inst shr eax-tn #.(integer-length (- sb!xc:most-positive-fixnum + sb!xc:most-negative-fixnum))))) + ;;; A (SIGNED-BYTE 32) can be represented with either fixnum or a bignum with ;;; exactly one digit. diff --git a/version.lisp-expr b/version.lisp-expr index ed252179c..9f9e8bfaa 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.29.1" +"1.0.29.2" -- 2.11.4.GIT