not need to do arithmetic at runtime to access them. (But beware:
this would complicate handling of the interior pointer).
-b. (Also note that raw slots are currently disabled on HPPA)
\ No newline at end of file
+b. (Also note that raw slots are currently disabled on HPPA)
+--------------------------------------------------------------------------------
+#29
+Python is overly zealous when converting high-level CL functions, such
+as MIN/MAX, LOGBITP, and LOGTEST, to low-level CL functions. Reducing
+Python's aggressiveness would make it easier to effect changes such as
+
+x86-64:
+* direct MIN/MAX on {SINGLE,DOUBLE}-FLOATs ({MIN,MAX}S{S,D})
+
+x86{,-64}:
+* direct LOGBITP on word-sized integers and fixnums (BT + JC)
+
+x86{,-64}/PPC:
+* branch-free MIN/MAX on word-sized integers and fixnums
+* efficient LOGTESTs on word-sized integers and fixnums (TEST / AND.)
+
+PPC:
+* efficient LDB on word-sized integers and fixnums (RLWINM)
+
+etc., etc.
+
+The "easier" part claimed above would come about because the functions
+would be available for :TRANSLATE through a VOP or similar, whereas with
+the current architecture, one would have to pattern-match IR1. While
+IR1 pattern-matching would be useful in other contexts, it seems better
+here to attempt the direct :TRANSLATE route.
+
+I (NJF) don't know how to implement such architecture-specific
+optimizations whilst keeping the high->low transformations for other
+architectures. Certainly adding #!+/- magic in compiler/*.lisp could be
+done, but such a solution is somewhat inelegant. Moving the relevant
+DEFTRANSFORMs to the architecture-specific compiler/* areas is also
+possible, but that would duplicate quite a bit of code.
(:policy :fast-safe)
(:args (arg :scs (signed-reg)))
(:arg-types signed-num)
- (:results (res :scs (any-reg)))
- (:result-types positive-fixnum)
- (:temporary (:scs (non-descriptor-reg) :to (:argument 0)) shift)
+ (:results (res :scs (unsigned-reg)))
+ (:result-types unsigned-num)
(:generator 6
; (integer-length arg) = (- 32 (cntlz (if (>= arg 0) arg (lognot arg))))
(let ((nonneg (gen-label)))
- (inst cntlzw. shift arg)
+ (inst cntlzw. res arg)
(inst bne nonneg)
- (inst not shift arg)
- (inst cntlzw shift shift)
+ (inst not res arg)
+ (inst cntlzw res res)
(emit-label nonneg)
- (inst slwi shift shift 2)
- (inst subfic res shift (fixnumize 32)))))
+ (inst subfic res res 32))))
+
+(define-vop (unsigned-byte-32-len)
+ (:translate integer-length)
+ (:note "inline (unsigned-byte 32) integer-length")
+ (:policy :fast-safe)
+ (:args (arg :scs (unsigned-reg)))
+ (:arg-types unsigned-num)
+ (:results (res :scs (unsigned-reg)))
+ (:result-types unsigned-num)
+ (:generator 4
+ (inst cntlzw res arg)
+ (inst subfic res res 32)))
(define-vop (unsigned-byte-32-count)
(:translate logcount)
(define-instruction-macro extlwi. (ra rs n b)
`(inst rlwinm. ,ra ,rs ,b 0 (1- ,n)))
+ (define-instruction-macro extrwi (ra rs n b)
+ `(inst rlwinm ,ra ,rs (mod (+ ,b ,n) 32) (- 32 ,n) 31))
+
+ (define-instruction-macro extrwi. (ra rs n b)
+ `(inst rlwinm. ,ra ,rs (mod (+ ,b ,n) 32) (- 32 ,n) 31))
+
(define-instruction-macro srwi (ra rs n)
`(inst rlwinm ,ra ,rs (- 32 ,n) ,n 31))
;;
;; Some code (the hash table code) depends on this returning a
;; positive number so make sure it does.
- (inst slwi res ptr 3)
- (inst srwi res res 1)))
+ (inst rlwinm res ptr n-fixnum-tag-bits 1 n-positive-fixnum-bits)))
(define-vop (make-other-immediate-type)
(:args (val :scs (any-reg descriptor-reg))
;;; 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".)
-"0.9.3.1"
+"0.9.3.2"