X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fppc%2Farith.lisp;h=336033d6dc42bc77e452fba5c4de810e158132e4;hb=4ed3f0d08c3a57a6762018d9622f253ab9d0f2b6;hp=9bbc6cd373f30e826fcdc4ba6835c77868d4c897;hpb=57e21c4b62e8c1a1ee7ef59ed2abb0c864fb06bc;p=sbcl.git diff --git a/src/compiler/ppc/arith.lisp b/src/compiler/ppc/arith.lisp index 9bbc6cd..336033d 100644 --- a/src/compiler/ppc/arith.lisp +++ b/src/compiler/ppc/arith.lisp @@ -137,23 +137,36 @@ (eval-when (:compile-toplevel :load-toplevel :execute) -(defmacro define-var-binop (translate untagged-penalty op) +(defmacro define-var-binop (translate untagged-penalty op + &optional arg-swap restore-fixnum-mask) `(progn (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM") fast-fixnum-binop) + ,@(when restore-fixnum-mask + `((:temporary (:sc non-descriptor-reg) temp))) (:translate ,translate) (:generator 2 - (inst ,op r x y))) + ,(if arg-swap + `(inst ,op ,(if restore-fixnum-mask 'temp 'r) y x) + `(inst ,op ,(if restore-fixnum-mask 'temp 'r) x y)) + ;; FIXME: remind me what convention we used for 64bitizing + ;; stuff? -- CSR, 2003-08-27 + ,@(when restore-fixnum-mask + `((inst clrrwi r temp (1- n-lowtag-bits)))))) (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED") fast-signed-binop) (:translate ,translate) (:generator ,(1+ untagged-penalty) - (inst ,op r x y))) + ,(if arg-swap + `(inst ,op r y x) + `(inst ,op r x y)))) (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED") fast-unsigned-binop) (:translate ,translate) (:generator ,(1+ untagged-penalty) - (inst ,op r x y))))) + ,(if arg-swap + `(inst ,op r y x) + `(inst ,op r x y)))))) (defmacro define-const-binop (translate untagged-penalty op) @@ -199,11 +212,15 @@ (define-var-binop + 4 add) (define-var-binop - 4 sub) (define-var-binop logand 2 and) +(define-var-binop logandc1 2 andc t) (define-var-binop logandc2 2 andc) (define-var-binop logior 2 or) -(define-var-binop logorc2 2 orc) +(define-var-binop logorc1 2 orc t t) +(define-var-binop logorc2 2 orc nil t) (define-var-binop logxor 2 xor) -(define-var-binop logeqv 2 eqv) +(define-var-binop logeqv 2 eqv nil t) +(define-var-binop lognand 2 nand nil t) +(define-var-binop lognor 2 nor nil t) (define-const-binop + 4 addi) (define-const-binop - 4 subi) @@ -222,7 +239,7 @@ (:note "safe inline fixnum arithmetic") (:generator 4 (let* ((no-overflow (gen-label))) - (inst mcrxr :cr0) + (inst mtxer zero-tn) (inst addo. r x y) (inst bns no-overflow) (inst unimp (logior (ash (reg-tn-encoding r) 5) @@ -237,7 +254,7 @@ (:note "safe inline fixnum arithmetic") (:generator 4 (let* ((no-overflow (gen-label))) - (inst mcrxr :cr0) + (inst mtxer zero-tn) (inst subo. r x y) (inst bns no-overflow) (inst unimp (logior (ash (reg-tn-encoding r) 5) @@ -316,38 +333,45 @@ (define-vop (fast-ash/unsigned=>unsigned) (:note "inline ASH") (:args (number :scs (unsigned-reg) :to :save) - (amount :scs (signed-reg immediate))) + (amount :scs (signed-reg))) (:arg-types (:or unsigned-num) signed-num) (:results (result :scs (unsigned-reg))) (:result-types unsigned-num) (:translate ash) (:policy :fast-safe) (:temporary (:sc non-descriptor-reg) ndesc) - (:generator 3 - (sc-case amount - (signed-reg - (let ((positive (gen-label)) - (done (gen-label))) - (inst cmpwi amount 0) - (inst neg ndesc amount) - (inst bge positive) - (inst cmpwi ndesc 31) - (inst srw result number ndesc) - (inst ble done) - (move result zero-tn) - (inst b done) - - (emit-label positive) - ;; The result-type assures us that this shift will not overflow. - (inst slw result number amount) + (:generator 5 + (let ((positive (gen-label)) + (done (gen-label))) + (inst cmpwi amount 0) + (inst neg ndesc amount) + (inst bge positive) + (inst cmpwi ndesc 31) + (inst srw result number ndesc) + (inst ble done) + (move result zero-tn) + (inst b done) + + (emit-label positive) + ;; The result-type assures us that this shift will not overflow. + (inst slw result number amount) + + (emit-label done)))) - (emit-label done))) - (immediate - (let ((amount (tn-value amount))) - (cond - ((and (minusp amount) (< amount -31)) (move result zero-tn)) - ((minusp amount) (inst srwi result number (- amount))) - (t (inst slwi result number amount)))))))) +(define-vop (fast-ash-c/unsigned=>unsigned) + (:note "inline constant ASH") + (:args (number :scs (unsigned-reg))) + (:info amount) + (:arg-types unsigned-num (:constant integer)) + (:results (result :scs (unsigned-reg))) + (:result-types unsigned-num) + (:translate ash) + (:policy :fast-safe) + (:generator 4 + (cond + ((and (minusp amount) (< amount -31)) (move result zero-tn)) + ((minusp amount) (inst srwi result number (- amount))) + (t (inst slwi result number amount))))) (define-vop (fast-ash/signed=>signed) (:note "inline ASH") @@ -433,6 +457,47 @@ (emit-label done)))) +;;;; Modular functions: +(define-modular-fun lognot-mod32 (x) lognot 32) +(define-vop (lognot-mod32/unsigned=>unsigned) + (:translate lognot-mod32) + (:args (x :scs (unsigned-reg))) + (:arg-types unsigned-num) + (:results (res :scs (unsigned-reg))) + (:result-types unsigned-num) + (:policy :fast-safe) + (:generator 1 + (inst not res x))) + +(define-vop (fast-ash-left-mod32-c/unsigned=>unsigned + fast-ash-c/unsigned=>unsigned) + (:translate ash-left-mod32)) + +(macrolet + ((define-modular-backend (fun &optional constantp) + (let ((mfun-name (symbolicate fun '-mod32)) + (modvop (symbolicate 'fast- fun '-mod32/unsigned=>unsigned)) + (modcvop (symbolicate 'fast- fun 'mod32-c/unsigned=>unsigned)) + (vop (symbolicate 'fast- fun '/unsigned=>unsigned)) + (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned))) + `(progn + (define-modular-fun ,mfun-name (x y) ,fun 32) + (define-vop (,modvop ,vop) + (:translate ,mfun-name)) + ,@(when constantp + `((define-vop (,modcvop ,cvop) + (:translate ,mfun-name)))))))) + (define-modular-backend + t) + (define-modular-backend - t) + (define-modular-backend logxor t) + (define-modular-backend logeqv) + (define-modular-backend lognand) + (define-modular-backend lognor) + (define-modular-backend logandc1) + (define-modular-backend logandc2) + (define-modular-backend logorc1) + (define-modular-backend logorc2)) + ;;;; Binary conditional VOPs: (define-vop (fast-conditional) @@ -635,64 +700,38 @@ (emit-label done) (move result res)))) +(define-source-transform 32bit-logical-not (x) + `(logand (lognot (the (unsigned-byte 32) ,x)) #.(1- (ash 1 32)))) -(define-vop (32bit-logical) - (:args (x :scs (unsigned-reg zero)) - (y :scs (unsigned-reg zero))) - (:arg-types unsigned-num unsigned-num) - (:results (r :scs (unsigned-reg))) - (:result-types unsigned-num) - (:policy :fast-safe)) - -(define-vop (32bit-logical-not 32bit-logical) - (:translate 32bit-logical-not) - (:args (x :scs (unsigned-reg zero))) - (:arg-types unsigned-num) - (:generator 1 - (inst not r x))) - -(define-vop (32bit-logical-and 32bit-logical) - (:translate 32bit-logical-and) - (:generator 1 - (inst and r x y))) - -(deftransform 32bit-logical-nand ((x y) (* *)) - '(32bit-logical-not (32bit-logical-and x y))) +(deftransform 32bit-logical-and ((x y)) + '(logand x y)) -(define-vop (32bit-logical-or 32bit-logical) - (:translate 32bit-logical-or) - (:generator 1 - (inst or r x y))) +(deftransform 32bit-logical-nand ((x y)) + '(logand (lognand x y) #.(1- (ash 1 32)))) -(deftransform 32bit-logical-nor ((x y) (* *)) - '(32bit-logical-not (32bit-logical-or x y))) +(deftransform 32bit-logical-or ((x y)) + '(logior x y)) -(define-vop (32bit-logical-xor 32bit-logical) - (:translate 32bit-logical-xor) - (:generator 1 - (inst xor r x y))) +(deftransform 32bit-logical-nor ((x y)) + '(logand (lognor x y) #.(1- (ash 1 32)))) -(define-vop (32bit-logical-eqv 32bit-logical) - (:translate 32bit-logical-eqv) - (:generator 1 - (inst eqv r x y))) +(deftransform 32bit-logical-xor ((x y)) + '(logxor x y)) -(define-vop (32bit-logical-orc2 32bit-logical) - (:translate 32bit-logical-orc2) - (:generator 1 - (inst orc r x y))) +(deftransform 32bit-logical-eqv ((x y)) + '(logand (logeqv x y) #.(1- (ash 1 32)))) -(deftransform 32bit-logical-orc1 ((x y) (* *)) - '(32bit-logical-orc2 y x)) +(deftransform 32bit-logical-orc1 ((x y)) + '(logand (logorc1 x y) #.(1- (ash 1 32)))) -(define-vop (32bit-logical-andc2 32bit-logical) - (:translate 32bit-logical-andc2) - (:generator 1 - (inst andc r x y))) +(deftransform 32bit-logical-orc2 ((x y)) + '(logand (logorc2 x y) #.(1- (ash 1 32)))) -(deftransform 32bit-logical-andc1 ((x y) (* *)) - '(32bit-logical-andc2 y x)) +(deftransform 32bit-logical-andc1 ((x y)) + '(logand (logandc1 x y) #.(1- (ash 1 32)))) +(deftransform 32bit-logical-andc2 ((x y)) + '(logand (logandc2 x y) #.(1- (ash 1 32)))) (define-vop (shift-towards-someplace) (:policy :fast-safe) @@ -715,29 +754,26 @@ (:generator 1 (inst rlwinm amount amount 0 27 31) (inst srw r num amount))) - - - ;;;; Bignum stuff. (define-vop (bignum-length get-header-data) - (:translate sb!bignum::%bignum-length) + (:translate sb!bignum:%bignum-length) (:policy :fast-safe)) (define-vop (bignum-set-length set-header-data) - (:translate sb!bignum::%bignum-set-length) + (:translate sb!bignum:%bignum-set-length) (:policy :fast-safe)) (define-vop (bignum-ref word-index-ref) - (:variant sb!vm:bignum-digits-offset sb!vm:other-pointer-lowtag) - (:translate sb!bignum::%bignum-ref) + (:variant bignum-digits-offset other-pointer-lowtag) + (:translate sb!bignum:%bignum-ref) (:results (value :scs (unsigned-reg))) (:result-types unsigned-num)) (define-vop (bignum-set word-index-set) - (:variant sb!vm:bignum-digits-offset sb!vm:other-pointer-lowtag) - (:translate sb!bignum::%bignum-set) + (:variant bignum-digits-offset other-pointer-lowtag) + (:translate sb!bignum:%bignum-set) (:args (object :scs (descriptor-reg)) (index :scs (any-reg immediate zero)) (value :scs (unsigned-reg))) @@ -746,7 +782,7 @@ (:result-types unsigned-num)) (define-vop (digit-0-or-plus) - (:translate sb!bignum::%digit-0-or-plusp) + (:translate sb!bignum:%digit-0-or-plusp) (:policy :fast-safe) (:args (digit :scs (unsigned-reg))) (:arg-types unsigned-num) @@ -760,7 +796,7 @@ (emit-label done)))) (define-vop (add-w/carry) - (:translate sb!bignum::%add-with-carry) + (:translate sb!bignum:%add-with-carry) (:policy :fast-safe) (:args (a :scs (unsigned-reg)) (b :scs (unsigned-reg)) @@ -776,7 +812,7 @@ (inst addze carry zero-tn))) (define-vop (sub-w/borrow) - (:translate sb!bignum::%subtract-with-borrow) + (:translate sb!bignum:%subtract-with-borrow) (:policy :fast-safe) (:args (a :scs (unsigned-reg)) (b :scs (unsigned-reg)) @@ -792,7 +828,7 @@ (inst addze borrow zero-tn))) (define-vop (bignum-mult-and-add-3-arg) - (:translate sb!bignum::%multiply-and-add) + (:translate sb!bignum:%multiply-and-add) (:policy :fast-safe) (:args (x :scs (unsigned-reg)) (y :scs (unsigned-reg)) @@ -811,7 +847,7 @@ (inst addze hi hi-temp))) (define-vop (bignum-mult-and-add-4-arg) - (:translate sb!bignum::%multiply-and-add) + (:translate sb!bignum:%multiply-and-add) (:policy :fast-safe) (:args (x :scs (unsigned-reg)) (y :scs (unsigned-reg)) @@ -833,7 +869,7 @@ (inst addze hi hi-temp))) (define-vop (bignum-mult) - (:translate sb!bignum::%multiply) + (:translate sb!bignum:%multiply) (:policy :fast-safe) (:args (x :scs (unsigned-reg) :to (:eval 1)) (y :scs (unsigned-reg) :to (:eval 1))) @@ -845,18 +881,11 @@ (inst mullw lo x y) (inst mulhwu hi x y))) -(define-vop (bignum-lognot) - (:translate sb!bignum::%lognot) - (:policy :fast-safe) - (:args (x :scs (unsigned-reg))) - (:arg-types unsigned-num) - (:results (r :scs (unsigned-reg))) - (:result-types unsigned-num) - (:generator 1 - (inst not r x))) +(define-vop (bignum-lognot lognot-mod32/unsigned=>unsigned) + (:translate sb!bignum:%lognot)) (define-vop (fixnum-to-digit) - (:translate sb!bignum::%fixnum-to-digit) + (:translate sb!bignum:%fixnum-to-digit) (:policy :fast-safe) (:args (fixnum :scs (any-reg))) (:arg-types tagged-num) @@ -867,7 +896,7 @@ (define-vop (bignum-floor) - (:translate sb!bignum::%floor) + (:translate sb!bignum:%floor) (:policy :fast-safe) (:args (num-high :scs (unsigned-reg) :target rem) (num-low :scs (unsigned-reg) :target rem-low) @@ -905,7 +934,7 @@ #| (define-vop (bignum-floor) - (:translate sb!bignum::%floor) + (:translate sb!bignum:%floor) (:policy :fast-safe) (:args (div-high :scs (unsigned-reg) :target rem) (div-low :scs (unsigned-reg) :target quo) @@ -921,7 +950,7 @@ |# (define-vop (signify-digit) - (:translate sb!bignum::%fixnum-digit-with-correct-sign) + (:translate sb!bignum:%fixnum-digit-with-correct-sign) (:policy :fast-safe) (:args (digit :scs (unsigned-reg) :target res)) (:arg-types unsigned-num) @@ -936,7 +965,7 @@ (define-vop (digit-ashr) - (:translate sb!bignum::%ashr) + (:translate sb!bignum:%ashr) (:policy :fast-safe) (:args (digit :scs (unsigned-reg)) (count :scs (unsigned-reg))) @@ -947,12 +976,12 @@ (inst sraw result digit count))) (define-vop (digit-lshr digit-ashr) - (:translate sb!bignum::%digit-logical-shift-right) + (:translate sb!bignum:%digit-logical-shift-right) (:generator 1 (inst srw result digit count))) (define-vop (digit-ashl digit-ashr) - (:translate sb!bignum::%ashl) + (:translate sb!bignum:%ashl) (:generator 1 (inst slw result digit count))) @@ -979,6 +1008,7 @@ (define-static-fun two-arg-and (x y) :translate logand) (define-static-fun two-arg-ior (x y) :translate logior) (define-static-fun two-arg-xor (x y) :translate logxor) +(define-static-fun two-arg-eqv (x y) :translate logeqv) (in-package "SB!C")