1 ;;;; the VM definition arithmetic VOPs for the Alpha
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
16 (define-vop (fixnum-unop)
17 (:args (x :scs (any-reg)))
18 (:results (res :scs (any-reg)))
19 (:note "inline fixnum arithmetic")
20 (:arg-types tagged-num)
21 (:result-types tagged-num)
24 (define-vop (signed-unop)
25 (:args (x :scs (signed-reg)))
26 (:results (res :scs (signed-reg)))
27 (:note "inline (signed-byte 64) arithmetic")
28 (:arg-types signed-num)
29 (:result-types signed-num)
32 (define-vop (fast-negate/fixnum fixnum-unop)
35 (inst subq zero-tn x res)))
37 (define-vop (fast-negate/signed signed-unop)
40 (inst subq zero-tn x res)))
42 (define-vop (fast-lognot/fixnum fixnum-unop)
45 (inst eqv x zero-tn res)))
47 (define-vop (fast-lognot/signed signed-unop)
52 ;;;; binary fixnum operations
54 ;;; Assume that any constant operand is the second arg...
56 (define-vop (fast-fixnum-binop)
57 (:args (x :target r :scs (any-reg))
58 (y :target r :scs (any-reg)))
59 (:arg-types tagged-num tagged-num)
60 (:results (r :scs (any-reg)))
61 (:result-types tagged-num)
62 (:note "inline fixnum arithmetic")
67 (define-vop (fast-unsigned-binop)
68 (:args (x :target r :scs (unsigned-reg))
69 (y :target r :scs (unsigned-reg)))
70 (:arg-types unsigned-num unsigned-num)
71 (:results (r :scs (unsigned-reg)))
72 (:result-types unsigned-num)
73 (:note "inline (unsigned-byte 64) arithmetic")
78 (define-vop (fast-signed-binop)
79 (:args (x :target r :scs (signed-reg))
80 (y :target r :scs (signed-reg)))
81 (:arg-types signed-num signed-num)
82 (:results (r :scs (signed-reg)))
83 (:result-types signed-num)
84 (:note "inline (signed-byte 64) arithmetic")
89 (define-vop (fast-fixnum-c-binop fast-fixnum-binop)
90 (:args (x :target r :scs (any-reg)))
92 (:arg-types tagged-num (:constant integer)))
94 (define-vop (fast-signed-c-binop fast-signed-binop)
95 (:args (x :target r :scs (signed-reg)))
97 (:arg-types signed-num (:constant integer)))
99 (define-vop (fast-unsigned-c-binop fast-unsigned-binop)
100 (:args (x :target r :scs (unsigned-reg)))
102 (:arg-types unsigned-num (:constant integer)))
104 (defmacro define-binop (translate cost untagged-cost op
105 tagged-type untagged-type
106 &optional arg-swap restore-fixnum-mask)
108 (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")
110 ,@(when restore-fixnum-mask
111 `((:temporary (:sc non-descriptor-reg) temp)))
112 (:args (x ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg))
113 (y ,@(unless restore-fixnum-mask `(:target r)) :scs (any-reg)))
114 (:translate ,translate)
115 (:generator ,(1+ cost)
117 `(inst ,op y x ,(if restore-fixnum-mask 'temp 'r))
118 `(inst ,op x y ,(if restore-fixnum-mask 'temp 'r)))
119 ,@(when restore-fixnum-mask
120 `((inst bic temp #.(ash lowtag-mask -1) r)))))
121 (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")
123 (:args (x :target r :scs (signed-reg))
124 (y :target r :scs (signed-reg)))
125 (:translate ,translate)
126 (:generator ,(1+ untagged-cost)
130 (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED")
132 (:args (x :target r :scs (unsigned-reg))
133 (y :target r :scs (unsigned-reg)))
134 (:translate ,translate)
135 (:generator ,(1+ untagged-cost)
139 ,@(when (and tagged-type (not arg-swap))
140 `((define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")
142 (:arg-types tagged-num (:constant ,tagged-type))
143 ,@(when restore-fixnum-mask
144 `((:temporary (:sc non-descriptor-reg) temp)))
145 (:translate ,translate)
147 (inst ,op x (fixnumize y) ,(if restore-fixnum-mask 'temp 'r))
148 ,@(when restore-fixnum-mask
149 `((inst bic temp #.(ash lowtag-mask -1) r)))))))
150 ,@(when (and untagged-type (not arg-swap))
151 `((define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
153 (:arg-types signed-num (:constant ,untagged-type))
154 (:translate ,translate)
155 (:generator ,untagged-cost
157 (define-vop (,(symbolicate "FAST-" translate
158 "-C/UNSIGNED=>UNSIGNED")
159 fast-unsigned-c-binop)
160 (:arg-types unsigned-num (:constant ,untagged-type))
161 (:translate ,translate)
162 (:generator ,untagged-cost
163 (inst ,op x y r)))))))
165 (define-binop + 1 5 addq (unsigned-byte 6) (unsigned-byte 8))
166 (define-binop - 1 5 subq (unsigned-byte 6) (unsigned-byte 8))
167 (define-binop logand 1 3 and (unsigned-byte 6) (unsigned-byte 8))
168 (define-binop logandc1 1 3 bic (unsigned-byte 6) (unsigned-byte 8) t)
169 (define-binop logandc2 1 3 bic (unsigned-byte 6) (unsigned-byte 8))
170 (define-binop logior 1 3 bis (unsigned-byte 6) (unsigned-byte 8))
171 (define-binop logorc1 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) t t)
172 (define-binop logorc2 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) nil t)
173 (define-binop logxor 1 3 xor (unsigned-byte 6) (unsigned-byte 8))
174 (define-binop logeqv 1 3 eqv (unsigned-byte 6) (unsigned-byte 8) nil t)
176 ;;; special cases for LOGAND where we can use a mask operation
177 (define-vop (fast-logand-c-mask/unsigned=>unsigned fast-unsigned-c-binop)
179 (:arg-types unsigned-num
180 (:constant (or (integer #xffffffff #xffffffff)
181 (integer #xffffffff00000000 #xffffffff00000000))))
184 (#xffffffff (inst mskll x 4 r))
185 (#xffffffff00000000 (inst mskll x 0 r)))))
189 (define-vop (fast-ash/unsigned=>unsigned)
191 (:args (number :scs (unsigned-reg) :to :save)
192 (amount :scs (signed-reg)))
193 (:arg-types unsigned-num signed-num)
194 (:results (result :scs (unsigned-reg)))
195 (:result-types unsigned-num)
198 (:temporary (:sc non-descriptor-reg) ndesc)
199 (:temporary (:sc non-descriptor-reg) temp)
201 (inst bge amount positive)
202 (inst subq zero-tn amount ndesc)
203 (inst cmplt ndesc 64 temp)
204 (inst srl number ndesc result)
205 ;; FIXME: this looks like a candidate for a conditional move --
208 (move zero-tn result)
209 (inst br zero-tn done)
212 (inst sll number amount result)
216 (define-vop (fast-ash/signed=>signed)
218 (:args (number :scs (signed-reg) :to :save)
219 (amount :scs (signed-reg)))
220 (:arg-types signed-num signed-num)
221 (:results (result :scs (signed-reg)))
222 (:result-types signed-num)
225 (:temporary (:sc non-descriptor-reg) ndesc)
226 (:temporary (:sc non-descriptor-reg) temp)
228 (inst bge amount positive)
229 (inst subq zero-tn amount ndesc)
230 (inst cmplt ndesc 63 temp)
231 (inst sra number ndesc result)
233 (inst sra number 63 result)
234 (inst br zero-tn done)
237 (inst sll number amount result)
241 (define-vop (fast-ash-c/signed=>signed)
245 (:args (number :scs (signed-reg)))
247 (:arg-types signed-num (:constant integer))
248 (:results (result :scs (signed-reg)))
249 (:result-types signed-num)
252 ((< count 0) (inst sra number (min 63 (- count)) result))
253 ((> count 0) (inst sll number (min 63 count) result))
254 (t (bug "identity ASH not transformed away")))))
256 (define-vop (fast-ash-c/unsigned=>unsigned)
260 (:args (number :scs (unsigned-reg)))
262 (:arg-types unsigned-num (:constant integer))
263 (:results (result :scs (unsigned-reg)))
264 (:result-types unsigned-num)
267 ((< count -63) (move zero-tn result))
268 ((< count 0) (inst sra number (- count) result))
269 ((> count 0) (inst sll number (min 63 count) result))
270 (t (bug "identity ASH not transformed away")))))
272 (define-vop (signed-byte-64-len)
273 (:translate integer-length)
274 (:note "inline (signed-byte 64) integer-length")
276 (:args (arg :scs (signed-reg) :to (:argument 1)))
277 (:arg-types signed-num)
278 (:results (res :scs (any-reg)))
279 (:result-types positive-fixnum)
280 (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift)
283 (inst cmovge arg arg shift)
284 (inst subq zero-tn (fixnumize 1) res)
285 (inst sll shift 1 shift)
287 (inst addq res (fixnumize 1) res)
288 (inst srl shift 1 shift)
289 (inst bne shift loop)))
291 (define-vop (unsigned-byte-64-count)
292 (:translate logcount)
293 (:note "inline (unsigned-byte 64) logcount")
295 (:args (arg :scs (unsigned-reg) :target num))
296 (:arg-types unsigned-num)
297 (:results (res :scs (unsigned-reg)))
298 (:result-types positive-fixnum)
299 (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)
301 (:temporary (:scs (non-descriptor-reg)) mask temp)
303 ;; FIXME: now this looks expensive, what with these 64bit loads.
304 ;; Maybe a loop and count would be faster? -- CSR, 2003-09-10
305 (inst li #x5555555555555555 mask)
306 (inst srl arg 1 temp)
307 (inst and arg mask num)
308 (inst and temp mask temp)
309 (inst addq num temp num)
310 (inst li #x3333333333333333 mask)
311 (inst srl num 2 temp)
312 (inst and num mask num)
313 (inst and temp mask temp)
314 (inst addq num temp num)
315 (inst li #x0f0f0f0f0f0f0f0f mask)
316 (inst srl num 4 temp)
317 (inst and num mask num)
318 (inst and temp mask temp)
319 (inst addq num temp num)
320 (inst li #x00ff00ff00ff00ff mask)
321 (inst srl num 8 temp)
322 (inst and num mask num)
323 (inst and temp mask temp)
324 (inst addq num temp num)
325 (inst li #x0000ffff0000ffff mask)
326 (inst srl num 16 temp)
327 (inst and num mask num)
328 (inst and temp mask temp)
329 (inst addq num temp num)
330 (inst li #x00000000ffffffff mask)
331 (inst srl num 32 temp)
332 (inst and num mask num)
333 (inst and temp mask temp)
334 (inst addq num temp res)))
338 (define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)
339 (:temporary (:scs (non-descriptor-reg)) temp)
343 (inst mulq x temp r)))
345 (define-vop (fast-*/signed=>signed fast-signed-binop)
350 (define-vop (fast-*/unsigned=>unsigned fast-unsigned-binop)
355 ;;;; Modular functions:
356 (define-modular-fun lognot-mod64 (x) lognot 64)
357 (define-vop (lognot-mod64/unsigned=>unsigned)
358 (:translate lognot-mod64)
359 (:args (x :scs (unsigned-reg)))
360 (:arg-types unsigned-num)
361 (:results (res :scs (unsigned-reg)))
362 (:result-types unsigned-num)
367 (define-vop (fast-ash-left-mod64-c/unsigned=>unsigned
368 fast-ash-c/unsigned=>unsigned)
369 (:translate ash-left-mod64))
372 ((define-modular-backend (fun &optional constantp)
373 (let ((mfun-name (symbolicate fun '-mod64))
374 (modvop (symbolicate 'fast- fun '-mod64/unsigned=>unsigned))
375 (modcvop (symbolicate 'fast- fun '-mod64-c/unsigned=>unsigned))
376 (vop (symbolicate 'fast- fun '/unsigned=>unsigned))
377 (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned)))
379 (define-modular-fun ,mfun-name (x y) ,fun 64)
380 (define-vop (,modvop ,vop)
381 (:translate ,mfun-name))
383 `((define-vop (,modcvop ,cvop)
384 (:translate ,mfun-name))))))))
385 (define-modular-backend + t)
386 (define-modular-backend - t)
387 (define-modular-backend logxor t)
388 (define-modular-backend logeqv t)
389 (define-modular-backend logandc1)
390 (define-modular-backend logandc2 t)
391 (define-modular-backend logorc1)
392 (define-modular-backend logorc2 t))
394 (define-source-transform lognand (x y)
395 `(lognot (logand ,x ,y)))
396 (define-source-transform lognor (x y)
397 `(lognot (logior ,x ,y)))
399 ;;;; binary conditional VOPs
401 (define-vop (fast-conditional)
406 (:temporary (:scs (non-descriptor-reg)) temp)
407 (:policy :fast-safe))
409 (define-vop (fast-conditional/fixnum fast-conditional)
410 (:args (x :scs (any-reg))
412 (:arg-types tagged-num tagged-num)
413 (:note "inline fixnum comparison"))
415 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
416 (:args (x :scs (any-reg)))
417 (:arg-types tagged-num (:constant (unsigned-byte-with-a-bite-out 6 4)))
418 (:info target not-p y))
420 (define-vop (fast-conditional/signed fast-conditional)
421 (:args (x :scs (signed-reg))
422 (y :scs (signed-reg)))
423 (:arg-types signed-num signed-num)
424 (:note "inline (signed-byte 64) comparison"))
426 (define-vop (fast-conditional-c/signed fast-conditional/signed)
427 (:args (x :scs (signed-reg)))
428 (:arg-types signed-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
429 (:info target not-p y))
431 (define-vop (fast-conditional/unsigned fast-conditional)
432 (:args (x :scs (unsigned-reg))
433 (y :scs (unsigned-reg)))
434 (:arg-types unsigned-num unsigned-num)
435 (:note "inline (unsigned-byte 64) comparison"))
437 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
438 (:args (x :scs (unsigned-reg)))
439 (:arg-types unsigned-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
440 (:info target not-p y))
443 (defmacro define-conditional-vop (translate &rest generator)
445 ,@(mapcar (lambda (suffix cost signed)
446 (unless (and (member suffix '(/fixnum -c/fixnum))
448 `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"
451 (format nil "~:@(FAST-CONDITIONAL~A~)"
453 (:translate ,translate)
455 (let* ((signed ,signed)
456 (-c/fixnum ,(eq suffix '-c/fixnum))
457 (y (if -c/fixnum (fixnumize y) y)))
459 '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
461 '(t t t t nil nil))))
463 (define-conditional-vop <
464 (cond ((and signed (eql y 0))
467 (inst blt x target)))
470 (inst cmplt x y temp)
471 (inst cmpult x y temp))
473 (inst beq temp target)
474 (inst bne temp target)))))
476 (define-conditional-vop >
477 (cond ((and signed (eql y 0))
480 (inst bgt x target)))
482 (let ((y (+ y (if -c/fixnum (fixnumize 1) 1))))
484 (inst cmplt x y temp)
485 (inst cmpult x y temp))
487 (inst bne temp target)
488 (inst beq temp target))))
491 (inst cmplt y x temp)
492 (inst cmpult y x temp))
494 (inst beq temp target)
495 (inst bne temp target)))))
497 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not
498 ;;; just a known fixnum.
500 (define-conditional-vop eql
501 (declare (ignore signed))
505 (inst cmpeq x y temp)
507 (inst beq temp target)
508 (inst bne temp target)))
510 ;;; These versions specify a fixnum restriction on their first arg. We
511 ;;; have also generic-eql/fixnum VOPs which are the same, but have no
512 ;;; restriction on the first arg and a higher cost. The reason for
513 ;;; doing this is to prevent fixnum specific operations from being
514 ;;; used on word integers, spuriously consing the argument.
515 (define-vop (fast-eql/fixnum fast-conditional)
516 (:args (x :scs (any-reg))
518 (:arg-types tagged-num tagged-num)
519 (:note "inline fixnum comparison")
522 (cond ((equal y zero-tn)
525 (inst beq x target)))
527 (inst cmpeq x y temp)
529 (inst beq temp target)
530 (inst bne temp target))))))
533 (define-vop (generic-eql/fixnum fast-eql/fixnum)
534 (:args (x :scs (any-reg descriptor-reg))
536 (:arg-types * tagged-num)
539 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
540 (:args (x :scs (any-reg)))
541 (:arg-types tagged-num (:constant (signed-byte 6)))
542 (:temporary (:scs (non-descriptor-reg)) temp)
543 (:info target not-p y)
546 (let ((y (cond ((eql y 0) zero-tn)
548 (inst li (fixnumize y) temp)
550 (inst cmpeq x y temp)
552 (inst beq temp target)
553 (inst bne temp target)))))
555 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
556 (:args (x :scs (any-reg descriptor-reg)))
557 (:arg-types * (:constant (signed-byte 6)))
561 ;;;; 32-bit logical operations
563 (define-vop (merge-bits)
564 (:translate merge-bits)
565 (:args (shift :scs (signed-reg unsigned-reg))
566 (prev :scs (unsigned-reg))
567 (next :scs (unsigned-reg)))
568 (:arg-types tagged-num unsigned-num unsigned-num)
569 (:temporary (:scs (unsigned-reg) :to (:result 0)) temp)
570 (:temporary (:scs (unsigned-reg) :to (:result 0) :target result) res)
571 (:results (result :scs (unsigned-reg)))
572 (:result-types unsigned-num)
575 (let ((done (gen-label)))
576 (inst srl next shift res)
577 (inst beq shift done)
578 (inst subq zero-tn shift temp)
579 (inst sll prev temp temp)
580 (inst bis res temp res)
584 (define-source-transform 32bit-logical-not (x)
585 `(logand (lognot (the (unsigned-byte 32) ,x)) #.(1- (ash 1 32))))
587 (deftransform 32bit-logical-and ((x y))
590 (define-source-transform 32bit-logical-nand (x y)
591 `(32bit-logical-not (32bit-logical-and ,x ,y)))
593 (deftransform 32bit-logical-or ((x y))
596 (define-source-transform 32bit-logical-nor (x y)
597 `(logand (lognor (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
600 (deftransform 32bit-logical-xor ((x y))
603 (define-source-transform 32bit-logical-eqv (x y)
604 `(logand (logeqv (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
607 (define-source-transform 32bit-logical-orc1 (x y)
608 `(logand (logorc1 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
611 (define-source-transform 32bit-logical-orc2 (x y)
612 `(logand (logorc2 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y))
615 (define-source-transform 32bit-logical-andc1 (x y)
616 `(logandc1 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y)))
618 (define-source-transform 32bit-logical-andc2 (x y)
619 `(logandc2 (the (unsigned-byte 32) ,x) (the (unsigned-byte 32) ,y)))
621 (define-vop (shift-towards-someplace)
623 (:args (num :scs (unsigned-reg))
624 (amount :scs (signed-reg)))
625 (:arg-types unsigned-num tagged-num)
626 (:results (r :scs (unsigned-reg)))
627 (:result-types unsigned-num))
629 (define-vop (shift-towards-start shift-towards-someplace)
630 (:translate shift-towards-start)
631 (:note "SHIFT-TOWARDS-START")
632 (:temporary (:sc non-descriptor-reg) temp)
634 (inst and amount #x1f temp)
635 (inst srl num temp r)))
637 (define-vop (shift-towards-end shift-towards-someplace)
638 (:translate shift-towards-end)
639 (:note "SHIFT-TOWARDS-END")
640 (:temporary (:sc non-descriptor-reg) temp)
642 (inst and amount #x1f temp)
643 (inst sll num temp r)))
647 (define-vop (bignum-length get-header-data)
648 (:translate sb!bignum:%bignum-length)
649 (:policy :fast-safe))
651 (define-vop (bignum-set-length set-header-data)
652 (:translate sb!bignum:%bignum-set-length)
653 (:policy :fast-safe))
655 (define-full-reffer bignum-ref * bignum-digits-offset other-pointer-lowtag
656 (unsigned-reg) unsigned-num sb!bignum:%bignum-ref)
658 (define-full-setter bignum-set * bignum-digits-offset other-pointer-lowtag
659 (unsigned-reg) unsigned-num sb!bignum:%bignum-set #!+gengc nil)
661 (define-vop (digit-0-or-plus)
662 (:translate sb!bignum:%digit-0-or-plusp)
664 (:args (digit :scs (unsigned-reg)))
665 (:arg-types unsigned-num)
666 (:temporary (:sc non-descriptor-reg) temp)
670 (inst sll digit 32 temp)
672 (inst blt temp target)
673 (inst bge temp target))))
675 (define-vop (add-w/carry)
676 (:translate sb!bignum:%add-with-carry)
678 (:args (a :scs (unsigned-reg))
679 (b :scs (unsigned-reg))
680 (c :scs (unsigned-reg)))
681 (:arg-types unsigned-num unsigned-num positive-fixnum)
682 (:results (result :scs (unsigned-reg) :from :load)
683 (carry :scs (unsigned-reg) :from :eval))
684 (:result-types unsigned-num positive-fixnum)
686 (inst addq a b result)
687 (inst addq result c result)
688 (inst sra result 32 carry)
689 (inst mskll result 4 result)))
691 (define-vop (sub-w/borrow)
692 (:translate sb!bignum:%subtract-with-borrow)
694 (:args (a :scs (unsigned-reg))
695 (b :scs (unsigned-reg))
696 (c :scs (unsigned-reg)))
697 (:arg-types unsigned-num unsigned-num positive-fixnum)
698 (:results (result :scs (unsigned-reg) :from :load)
699 (borrow :scs (unsigned-reg) :from :eval))
700 (:result-types unsigned-num positive-fixnum)
702 (inst xor c 1 result)
703 (inst subq a result result)
704 (inst subq result b result)
705 (inst srl result 63 borrow)
706 (inst xor borrow 1 borrow)
707 (inst mskll result 4 result)))
709 (define-vop (bignum-mult-and-add-3-arg)
710 (:translate sb!bignum:%multiply-and-add)
712 (:args (x :scs (unsigned-reg))
713 (y :scs (unsigned-reg))
714 (carry-in :scs (unsigned-reg) :to :save))
715 (:arg-types unsigned-num unsigned-num unsigned-num)
716 (:results (hi :scs (unsigned-reg))
717 (lo :scs (unsigned-reg)))
718 (:result-types unsigned-num unsigned-num)
721 (inst addq lo carry-in lo)
723 (inst mskll lo 4 lo)))
726 (define-vop (bignum-mult-and-add-4-arg)
727 (:translate sb!bignum:%multiply-and-add)
729 (:args (x :scs (unsigned-reg))
730 (y :scs (unsigned-reg))
731 (prev :scs (unsigned-reg))
732 (carry-in :scs (unsigned-reg) :to :save))
733 (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num)
734 (:results (hi :scs (unsigned-reg))
735 (lo :scs (unsigned-reg)))
736 (:result-types unsigned-num unsigned-num)
739 (inst addq lo prev lo)
740 (inst addq lo carry-in lo)
742 (inst mskll lo 4 lo)))
744 (define-vop (bignum-mult)
745 (:translate sb!bignum:%multiply)
747 (:args (x :scs (unsigned-reg))
748 (y :scs (unsigned-reg)))
749 (:arg-types unsigned-num unsigned-num)
750 (:results (hi :scs (unsigned-reg))
751 (lo :scs (unsigned-reg)))
752 (:result-types unsigned-num unsigned-num)
756 (inst mskll lo 4 lo)))
758 (define-vop (bignum-lognot)
759 (:translate sb!bignum:%lognot)
761 (:args (x :scs (unsigned-reg)))
762 (:arg-types unsigned-num)
763 (:results (r :scs (unsigned-reg)))
764 (:result-types unsigned-num)
769 (define-vop (fixnum-to-digit)
770 (:translate sb!bignum:%fixnum-to-digit)
772 (:args (fixnum :scs (any-reg)))
773 (:arg-types tagged-num)
774 (:results (digit :scs (unsigned-reg)))
775 (:result-types unsigned-num)
777 (inst sra fixnum 2 digit)))
779 (define-vop (bignum-floor)
780 (:translate sb!bignum:%floor)
782 (:args (num-high :scs (unsigned-reg))
783 (num-low :scs (unsigned-reg))
784 (denom-arg :scs (unsigned-reg) :target denom))
785 (:arg-types unsigned-num unsigned-num unsigned-num)
786 (:temporary (:scs (unsigned-reg) :from (:argument 2)) denom)
787 (:temporary (:scs (unsigned-reg) :from (:eval 0)) temp)
788 (:results (quo :scs (unsigned-reg) :from (:eval 0))
789 (rem :scs (unsigned-reg) :from (:argument 0)))
790 (:result-types unsigned-num unsigned-num)
791 (:generator 325 ; number of inst assuming targeting works.
792 (inst sll num-high 32 rem)
793 (inst bis rem num-low rem)
794 (inst sll denom-arg 32 denom)
795 (inst cmpule denom rem quo)
796 (inst beq quo shift1)
797 (inst subq rem denom rem)
800 (let ((shift2 (gen-label)))
801 (inst srl denom 1 denom)
802 (inst cmpule denom rem temp)
804 (inst beq temp shift2)
805 (inst subq rem denom rem)
807 (emit-label shift2)))))
809 (define-vop (signify-digit)
810 (:translate sb!bignum:%fixnum-digit-with-correct-sign)
812 (:args (digit :scs (unsigned-reg) :target res))
813 (:arg-types unsigned-num)
814 (:results (res :scs (any-reg signed-reg)))
815 (:result-types signed-num)
819 (inst sll digit 34 res)
820 (inst sra res 32 res))
822 (inst sll digit 32 res)
823 (inst sra res 32 res)))))
826 (define-vop (digit-ashr)
827 (:translate sb!bignum:%ashr)
829 (:args (digit :scs (unsigned-reg))
830 (count :scs (unsigned-reg)))
831 (:arg-types unsigned-num positive-fixnum)
832 (:results (result :scs (unsigned-reg) :from (:argument 0)))
833 (:result-types unsigned-num)
835 (inst sll digit 32 result)
836 (inst sra result count result)
837 (inst srl result 32 result)))
839 (define-vop (digit-lshr digit-ashr)
840 (:translate sb!bignum:%digit-logical-shift-right)
842 (inst srl digit count result)))
844 (define-vop (digit-ashl digit-ashr)
845 (:translate sb!bignum:%ashl)
847 (inst sll digit count result)))
849 ;;;; static functions
851 (define-static-fun two-arg-gcd (x y) :translate gcd)
852 (define-static-fun two-arg-lcm (x y) :translate lcm)
854 (define-static-fun two-arg-+ (x y) :translate +)
855 (define-static-fun two-arg-- (x y) :translate -)
856 (define-static-fun two-arg-* (x y) :translate *)
857 (define-static-fun two-arg-/ (x y) :translate /)
859 (define-static-fun two-arg-< (x y) :translate <)
860 (define-static-fun two-arg-<= (x y) :translate <=)
861 (define-static-fun two-arg-> (x y) :translate >)
862 (define-static-fun two-arg->= (x y) :translate >=)
863 (define-static-fun two-arg-= (x y) :translate =)
864 (define-static-fun two-arg-/= (x y) :translate /=)
866 (define-static-fun %negate (x) :translate %negate)
868 (define-static-fun two-arg-and (x y) :translate logand)
869 (define-static-fun two-arg-ior (x y) :translate logior)
870 (define-static-fun two-arg-xor (x y) :translate logxor)
871 (define-static-fun two-arg-eqv (x y) :translate logeqv)