hexstr / cold-print fixes from Douglas Katzman
[sbcl.git] / src / assembly / hppa / arith.lisp
index 4929582..0a378e4 100644 (file)
@@ -49,8 +49,6 @@
   (inst xor res sign res)
   (inst add res sign res))
 
-
-#+sb-assembling
 (define-assembly-routine
     (truncate)
     ((:arg dividend signed-reg nl0-offset)
@@ -58,7 +56,6 @@
 
      (:res quo signed-reg nl2-offset)
      (:res rem signed-reg nl3-offset))
-  
   ;; Move abs(divident) into quo.
   (inst move dividend quo :>=)
   (inst sub zero-tn quo quo)
   (inst move dividend zero-tn :>=)
   (inst sub zero-tn rem rem))
 
-
 \f
 ;;;; Generic arithmetic.
 
 (define-assembly-routine (generic-+
-                         (:cost 10)
-                         (:return-style :full-call)
-                         (:translate +)
-                         (:policy :safe)
-                         (:save-p t))
-                        ((:arg x (descriptor-reg any-reg) a0-offset)
-                         (:arg y (descriptor-reg any-reg) a1-offset)
-
-                         (:res res (descriptor-reg any-reg) a0-offset)
-
-                         (:temp lip interior-reg lip-offset)
-                         (:temp lra descriptor-reg lra-offset)
-                         (:temp nargs any-reg nargs-offset)
-                         (:temp ocfp any-reg ocfp-offset))
-  (inst extru x 31 2 zero-tn :=)
-  (inst b do-static-fun :nullify t)
-  (inst extru y 31 2 zero-tn :=)
-  (inst b do-static-fun :nullify t)
-  (inst addo x y res)
+                          (:cost 10)
+                          (:return-style :full-call)
+                          (:translate +)
+                          (:policy :safe)
+                          (:save-p t))
+                         ((:arg x (descriptor-reg any-reg) a0-offset)
+                          (:arg y (descriptor-reg any-reg) a1-offset)
+                          (:res res (descriptor-reg any-reg) a0-offset)
+                          (:temp temp non-descriptor-reg nl0-offset)
+                          (:temp temp1 non-descriptor-reg nl1-offset)
+                          (:temp temp2 non-descriptor-reg nl2-offset)
+                          (:temp lra descriptor-reg lra-offset)
+                          (:temp lip interior-reg lip-offset)
+                          (:temp nargs any-reg nargs-offset)
+                          (:temp ocfp any-reg ocfp-offset))
+  ;; If either arg is not fixnum, use two-arg-+ to summarize
+  (inst or x y temp)
+  (inst extru temp 31 3 zero-tn :=)
+  (inst b DO-STATIC-FUN :nullify t)
+  ;; check for overflow
+  (inst add x y temp)
+  (inst xor temp x temp1)
+  (inst xor temp y temp2)
+  (inst and temp1 temp2 temp1)
+  (inst bc :< nil temp1 zero-tn DO-OVERFLOW)
+  (inst move temp res)
+  (lisp-return lra :offset 1)
+
+  DO-OVERFLOW
+  ;; We did overflow, so do the bignum version
+  (inst sra x n-fixnum-tag-bits temp1)
+  (inst sra y n-fixnum-tag-bits temp2)
+  (inst add temp1 temp2 temp)
+  (with-fixed-allocation (res nil temp2 bignum-widetag
+                          (1+ bignum-digits-offset) nil)
+    (storew temp res bignum-digits-offset other-pointer-lowtag))
   (lisp-return lra :offset 1)
 
   DO-STATIC-FUN
   (inst ldw (static-fun-offset 'two-arg-+) null-tn lip)
   (inst li (fixnumize 2) nargs)
-  (inst move cfp-tn ocfp)
+  (move cfp-tn ocfp)
   (inst bv lip)
-  (inst move csp-tn cfp-tn))
+  (move csp-tn cfp-tn t))
 
 (define-assembly-routine (generic--
-                         (:cost 10)
-                         (:return-style :full-call)
-                         (:translate -)
-                         (:policy :safe)
-                         (:save-p t))
-                        ((:arg x (descriptor-reg any-reg) a0-offset)
-                         (:arg y (descriptor-reg any-reg) a1-offset)
-
-                         (:res res (descriptor-reg any-reg) a0-offset)
-
-                         (:temp lip interior-reg lip-offset)
-                         (:temp lra descriptor-reg lra-offset)
-                         (:temp nargs any-reg nargs-offset)
-                         (:temp ocfp any-reg ocfp-offset))
-  (inst extru x 31 2 zero-tn :=)
-  (inst b do-static-fun :nullify t)
-  (inst extru y 31 2 zero-tn :=)
-  (inst b do-static-fun :nullify t)
-  (inst subo x y res)
+                          (:cost 10)
+                          (:return-style :full-call)
+                          (:translate -)
+                          (:policy :safe)
+                          (:save-p t))
+                         ((:arg x (descriptor-reg any-reg) a0-offset)
+                          (:arg y (descriptor-reg any-reg) a1-offset)
+
+                          (:res res (descriptor-reg any-reg) a0-offset)
+
+                          (:temp temp non-descriptor-reg nl0-offset)
+                          (:temp temp1 non-descriptor-reg nl1-offset)
+                          (:temp temp2 non-descriptor-reg nl2-offset)
+                          (:temp lra descriptor-reg lra-offset)
+                          (:temp lip interior-reg lip-offset)
+                          (:temp nargs any-reg nargs-offset)
+                          (:temp ocfp any-reg ocfp-offset))
+  ;; If either arg is not fixnum, use two-arg-+ to summarize
+  (inst or x y temp)
+  (inst extru temp 31 3 zero-tn :=)
+  (inst b DO-STATIC-FUN :nullify t)
+  (inst sub x y temp)
+  ;; check for overflow
+  (inst xor x y temp1)
+  (inst xor x temp temp2)
+  (inst and temp2 temp1 temp1)
+  (inst bc :< nil temp1 zero-tn DO-OVERFLOW)
+  (inst move temp res)
+  (lisp-return lra :offset 1)
+
+  DO-OVERFLOW
+  ;; We did overflow, so do the bignum version
+  (inst sra x n-fixnum-tag-bits temp1)
+  (inst sra y n-fixnum-tag-bits temp2)
+  (inst sub temp1 temp2 temp)
+  (with-fixed-allocation (res nil temp2 bignum-widetag
+                          (1+ bignum-digits-offset) nil)
+    (storew temp res bignum-digits-offset other-pointer-lowtag))
   (lisp-return lra :offset 1)
 
   DO-STATIC-FUN
   (inst ldw (static-fun-offset 'two-arg--) null-tn lip)
   (inst li (fixnumize 2) nargs)
-  (inst move cfp-tn ocfp)
+  (move cfp-tn ocfp)
   (inst bv lip)
-  (inst move csp-tn cfp-tn))
-
+  (move csp-tn cfp-tn t))
 
 \f
 ;;;; Comparison routines.
 (macrolet
     ((define-cond-assem-rtn (name translate static-fn cond)
        `(define-assembly-routine (,name
-                                 (:cost 10)
-                                 (:return-style :full-call)
-                                 (:policy :safe)
-                                 (:translate ,translate)
-                                 (:save-p t))
-                                ((:arg x (descriptor-reg any-reg) a0-offset)
-                                 (:arg y (descriptor-reg any-reg) a1-offset)
-                                 
-                                 (:res res descriptor-reg a0-offset)
-                                 
-                                 (:temp lip interior-reg lip-offset)
-                                 (:temp lra descriptor-reg lra-offset)
-                                 (:temp nargs any-reg nargs-offset)
-                                 (:temp ocfp any-reg ocfp-offset))
-         (inst extru x 31 2 zero-tn :=)
-         (inst b do-static-fn :nullify t)
-         (inst extru y 31 2 zero-tn :=)
-         (inst b do-static-fn :nullify t)
-
-         (inst comclr x y zero-tn ,cond)
-         (inst move null-tn res :tr)
-         (load-symbol res t)
-         (lisp-return lra :offset 1)
-
-         DO-STATIC-FN
-         (inst ldw (static-fun-offset ',static-fn) null-tn lip)
-         (inst li (fixnumize 2) nargs)
-         (inst move cfp-tn ocfp)
-         (inst bv lip)
-         (inst move csp-tn cfp-tn))))
+                                  (:cost 10)
+                                  (:return-style :full-call)
+                                  (:policy :safe)
+                                  (:translate ,translate)
+                                  (:save-p t))
+                                 ((:arg x (descriptor-reg any-reg) a0-offset)
+                                  (:arg y (descriptor-reg any-reg) a1-offset)
+
+                                  (:res res descriptor-reg a0-offset)
+
+                                  (:temp lip interior-reg lip-offset)
+                                  (:temp lra descriptor-reg lra-offset)
+                                  (:temp nargs any-reg nargs-offset)
+                                  (:temp ocfp any-reg ocfp-offset))
+          (inst extru x 31 2 zero-tn :=)
+          (inst b do-static-fn :nullify t)
+          (inst extru y 31 2 zero-tn :=)
+          (inst b do-static-fn :nullify t)
+
+          (inst comclr x y zero-tn ,cond)
+          (inst move null-tn res :tr)
+          (load-symbol res t)
+          (lisp-return lra :offset 1)
+
+          DO-STATIC-FN
+          (inst ldw (static-fun-offset ',static-fn) null-tn lip)
+          (inst li (fixnumize 2) nargs)
+          (inst move cfp-tn ocfp)
+          (inst bv lip)
+          (inst move csp-tn cfp-tn))))
 
   (define-cond-assem-rtn generic-< < two-arg-< :<)
   (define-cond-assem-rtn generic-> > two-arg-> :>))
      (:save-p t))
     ((:arg x (descriptor-reg any-reg) a0-offset)
      (:arg y (descriptor-reg any-reg) a1-offset)
-     
+
      (:res res descriptor-reg a0-offset)
-     
+
      (:temp lip interior-reg lip-offset)
      (:temp lra descriptor-reg lra-offset)
      (:temp nargs any-reg nargs-offset)
      (:save-p t))
     ((:arg x (descriptor-reg any-reg) a0-offset)
      (:arg y (descriptor-reg any-reg) a1-offset)
-     
+
      (:res res descriptor-reg a0-offset)
-     
+
      (:temp lip interior-reg lip-offset)
      (:temp lra descriptor-reg lra-offset)
      (:temp nargs any-reg nargs-offset)