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 (:args (x ,@(unless restore-fixnum-mask `(:target r))
144 (:arg-types tagged-num (:constant ,tagged-type))
145 ,@(when restore-fixnum-mask
146 `((:temporary (:sc non-descriptor-reg) temp)))
147 (:translate ,translate)
149 (inst ,op x (fixnumize y) ,(if restore-fixnum-mask 'temp 'r))
150 ,@(when restore-fixnum-mask
151 `((inst bic temp #.(ash lowtag-mask -1) r)))))))
152 ,@(when (and untagged-type (not arg-swap))
153 `((define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
155 (:arg-types signed-num (:constant ,untagged-type))
156 (:translate ,translate)
157 (:generator ,untagged-cost
159 (define-vop (,(symbolicate "FAST-" translate
160 "-C/UNSIGNED=>UNSIGNED")
161 fast-unsigned-c-binop)
162 (:arg-types unsigned-num (:constant ,untagged-type))
163 (:translate ,translate)
164 (:generator ,untagged-cost
165 (inst ,op x y r)))))))
167 (define-binop + 1 5 addq (unsigned-byte 6) (unsigned-byte 8))
168 (define-binop - 1 5 subq (unsigned-byte 6) (unsigned-byte 8))
169 (define-binop logand 1 3 and (unsigned-byte 6) (unsigned-byte 8))
170 (define-binop logandc1 1 3 bic (unsigned-byte 6) (unsigned-byte 8) t)
171 (define-binop logandc2 1 3 bic (unsigned-byte 6) (unsigned-byte 8))
172 (define-binop logior 1 3 bis (unsigned-byte 6) (unsigned-byte 8))
173 (define-binop logorc1 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) t t)
174 (define-binop logorc2 1 3 ornot (unsigned-byte 6) (unsigned-byte 8) nil t)
175 (define-binop logxor 1 3 xor (unsigned-byte 6) (unsigned-byte 8))
176 (define-binop logeqv 1 3 eqv (unsigned-byte 6) (unsigned-byte 8) nil t)
178 ;;; special cases for LOGAND where we can use a mask operation
179 (define-vop (fast-logand-c-mask/unsigned=>unsigned fast-unsigned-c-binop)
181 (:arg-types unsigned-num
182 (:constant (or (integer #xffffffff #xffffffff)
183 (integer #xffffffff00000000 #xffffffff00000000))))
186 (#xffffffff (inst mskll x 4 r))
187 (#xffffffff00000000 (inst mskll x 0 r)))))
191 (define-vop (fast-ash/unsigned=>unsigned)
193 (:args (number :scs (unsigned-reg) :to :save)
194 (amount :scs (signed-reg)))
195 (:arg-types unsigned-num signed-num)
196 (:results (result :scs (unsigned-reg)))
197 (:result-types unsigned-num)
200 (:temporary (:sc non-descriptor-reg) ndesc)
201 (:temporary (:sc non-descriptor-reg) temp)
203 (inst bge amount positive)
204 (inst subq zero-tn amount ndesc)
205 (inst cmplt ndesc 64 temp)
206 (inst srl number ndesc result)
207 ;; FIXME: this looks like a candidate for a conditional move --
210 (move zero-tn result)
211 (inst br zero-tn done)
214 (inst sll number amount result)
218 (define-vop (fast-ash/signed=>signed)
220 (:args (number :scs (signed-reg) :to :save)
221 (amount :scs (signed-reg)))
222 (:arg-types signed-num signed-num)
223 (:results (result :scs (signed-reg)))
224 (:result-types signed-num)
227 (:temporary (:sc non-descriptor-reg) ndesc)
228 (:temporary (:sc non-descriptor-reg) temp)
230 (inst bge amount positive)
231 (inst subq zero-tn amount ndesc)
232 (inst cmplt ndesc 63 temp)
233 (inst sra number ndesc result)
235 (inst sra number 63 result)
236 (inst br zero-tn done)
239 (inst sll number amount result)
243 (define-vop (fast-ash-c/signed=>signed)
247 (:args (number :scs (signed-reg)))
249 (:arg-types signed-num (:constant integer))
250 (:results (result :scs (signed-reg)))
251 (:result-types signed-num)
254 ((< count 0) (inst sra number (min 63 (- count)) result))
255 ((> count 0) (inst sll number (min 63 count) result))
256 (t (bug "identity ASH not transformed away")))))
258 (define-vop (fast-ash-c/unsigned=>unsigned)
262 (:args (number :scs (unsigned-reg)))
264 (:arg-types unsigned-num (:constant integer))
265 (:results (result :scs (unsigned-reg)))
266 (:result-types unsigned-num)
269 ((< count -63) (move zero-tn result))
270 ((< count 0) (inst sra number (- count) result))
271 ((> count 0) (inst sll number (min 63 count) result))
272 (t (bug "identity ASH not transformed away")))))
274 (define-vop (signed-byte-64-len)
275 (:translate integer-length)
276 (:note "inline (signed-byte 64) integer-length")
278 (:args (arg :scs (signed-reg) :to (:argument 1)))
279 (:arg-types signed-num)
280 (:results (res :scs (any-reg)))
281 (:result-types positive-fixnum)
282 (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift)
285 (inst cmovge arg arg shift)
286 (inst subq zero-tn (fixnumize 1) res)
287 (inst sll shift 1 shift)
289 (inst addq res (fixnumize 1) res)
290 (inst srl shift 1 shift)
291 (inst bne shift loop)))
293 (define-vop (unsigned-byte-64-count)
294 (:translate logcount)
295 (:note "inline (unsigned-byte 64) logcount")
297 (:args (arg :scs (unsigned-reg)))
298 (:arg-types unsigned-num)
299 (:results (res :scs (unsigned-reg)))
300 (:result-types positive-fixnum)
301 (:guard (member :cix *backend-subfeatures*))
303 (inst ctpop zero-tn arg res)))
305 (define-vop (unsigned-byte-64-count)
306 (:translate logcount)
307 (:note "inline (unsigned-byte 64) logcount")
309 (:args (arg :scs (unsigned-reg) :target num))
310 (:arg-types unsigned-num)
311 (:results (res :scs (unsigned-reg)))
312 (:result-types positive-fixnum)
313 (:temporary (:scs (non-descriptor-reg) :from (:argument 0) :to (:result 0)
315 (:temporary (:scs (non-descriptor-reg)) mask temp)
317 ;; FIXME: now this looks expensive, what with these 64bit loads.
318 ;; Maybe a loop and count would be faster? -- CSR, 2003-09-10
319 (inst li #x5555555555555555 mask)
320 (inst srl arg 1 temp)
321 (inst and arg mask num)
322 (inst and temp mask temp)
323 (inst addq num temp num)
324 (inst li #x3333333333333333 mask)
325 (inst srl num 2 temp)
326 (inst and num mask num)
327 (inst and temp mask temp)
328 (inst addq num temp num)
329 (inst li #x0f0f0f0f0f0f0f0f mask)
330 (inst srl num 4 temp)
331 (inst and num mask num)
332 (inst and temp mask temp)
333 (inst addq num temp num)
334 (inst li #x00ff00ff00ff00ff mask)
335 (inst srl num 8 temp)
336 (inst and num mask num)
337 (inst and temp mask temp)
338 (inst addq num temp num)
339 (inst li #x0000ffff0000ffff mask)
340 (inst srl num 16 temp)
341 (inst and num mask num)
342 (inst and temp mask temp)
343 (inst addq num temp num)
344 (inst li #x00000000ffffffff mask)
345 (inst srl num 32 temp)
346 (inst and num mask num)
347 (inst and temp mask temp)
348 (inst addq num temp res)))
352 (define-vop (fast-*/fixnum=>fixnum fast-fixnum-binop)
353 (:temporary (:scs (non-descriptor-reg)) temp)
356 (inst sra y n-fixnum-tag-bits temp)
357 (inst mulq x temp r)))
359 (define-vop (fast-*/signed=>signed fast-signed-binop)
364 (define-vop (fast-*/unsigned=>unsigned fast-unsigned-binop)
369 ;;;; Modular functions:
370 (define-modular-fun lognot-mod64 (x) lognot 64)
371 (define-vop (lognot-mod64/unsigned=>unsigned)
372 (:translate lognot-mod64)
373 (:args (x :scs (unsigned-reg)))
374 (:arg-types unsigned-num)
375 (:results (res :scs (unsigned-reg)))
376 (:result-types unsigned-num)
381 (define-vop (fast-ash-left-mod64-c/unsigned=>unsigned
382 fast-ash-c/unsigned=>unsigned)
383 (:translate ash-left-mod64))
386 ((define-modular-backend (fun &optional constantp)
387 (let ((mfun-name (symbolicate fun '-mod64))
388 (modvop (symbolicate 'fast- fun '-mod64/unsigned=>unsigned))
389 (modcvop (symbolicate 'fast- fun '-mod64-c/unsigned=>unsigned))
390 (vop (symbolicate 'fast- fun '/unsigned=>unsigned))
391 (cvop (symbolicate 'fast- fun '-c/unsigned=>unsigned)))
393 (define-modular-fun ,mfun-name (x y) ,fun 64)
394 (define-vop (,modvop ,vop)
395 (:translate ,mfun-name))
397 `((define-vop (,modcvop ,cvop)
398 (:translate ,mfun-name))))))))
399 (define-modular-backend + t)
400 (define-modular-backend - t)
401 (define-modular-backend logxor t)
402 (define-modular-backend logeqv t)
403 (define-modular-backend logandc1)
404 (define-modular-backend logandc2 t)
405 (define-modular-backend logorc1)
406 (define-modular-backend logorc2 t))
408 (define-source-transform lognand (x y)
409 `(lognot (logand ,x ,y)))
410 (define-source-transform lognor (x y)
411 `(lognot (logior ,x ,y)))
413 ;;;; binary conditional VOPs
415 (define-vop (fast-conditional)
420 (:temporary (:scs (non-descriptor-reg)) temp)
421 (:policy :fast-safe))
423 (define-vop (fast-conditional/fixnum fast-conditional)
424 (:args (x :scs (any-reg))
426 (:arg-types tagged-num tagged-num)
427 (:note "inline fixnum comparison"))
429 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
430 (:args (x :scs (any-reg)))
431 (:arg-types tagged-num (:constant (unsigned-byte-with-a-bite-out 6 4)))
432 (:info target not-p y))
434 (define-vop (fast-conditional/signed fast-conditional)
435 (:args (x :scs (signed-reg))
436 (y :scs (signed-reg)))
437 (:arg-types signed-num signed-num)
438 (:note "inline (signed-byte 64) comparison"))
440 (define-vop (fast-conditional-c/signed fast-conditional/signed)
441 (:args (x :scs (signed-reg)))
442 (:arg-types signed-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
443 (:info target not-p y))
445 (define-vop (fast-conditional/unsigned fast-conditional)
446 (:args (x :scs (unsigned-reg))
447 (y :scs (unsigned-reg)))
448 (:arg-types unsigned-num unsigned-num)
449 (:note "inline (unsigned-byte 64) comparison"))
451 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
452 (:args (x :scs (unsigned-reg)))
453 (:arg-types unsigned-num (:constant (unsigned-byte-with-a-bite-out 8 1)))
454 (:info target not-p y))
457 (defmacro define-conditional-vop (translate &rest generator)
459 ,@(mapcar (lambda (suffix cost signed)
460 (unless (and (member suffix '(/fixnum -c/fixnum))
462 `(define-vop (,(intern (format nil "~:@(FAST-IF-~A~A~)"
465 (format nil "~:@(FAST-CONDITIONAL~A~)"
467 (:translate ,translate)
469 (let* ((signed ,signed)
470 (-c/fixnum ,(eq suffix '-c/fixnum))
471 (y (if -c/fixnum (fixnumize y) y)))
473 '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
475 '(t t t t nil nil))))
477 (define-conditional-vop <
478 (cond ((and signed (eql y 0))
481 (inst blt x target)))
484 (inst cmplt x y temp)
485 (inst cmpult x y temp))
487 (inst beq temp target)
488 (inst bne temp target)))))
490 (define-conditional-vop >
491 (cond ((and signed (eql y 0))
494 (inst bgt x target)))
496 (let ((y (+ y (if -c/fixnum (fixnumize 1) 1))))
498 (inst cmplt x y temp)
499 (inst cmpult x y temp))
501 (inst bne temp target)
502 (inst beq temp target))))
505 (inst cmplt y x temp)
506 (inst cmpult y x temp))
508 (inst beq temp target)
509 (inst bne temp target)))))
511 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not
512 ;;; just a known fixnum.
514 (define-conditional-vop eql
515 (declare (ignore signed))
519 (inst cmpeq x y temp)
521 (inst beq temp target)
522 (inst bne temp target)))
524 ;;; These versions specify a fixnum restriction on their first arg. We
525 ;;; have also generic-eql/fixnum VOPs which are the same, but have no
526 ;;; restriction on the first arg and a higher cost. The reason for
527 ;;; doing this is to prevent fixnum specific operations from being
528 ;;; used on word integers, spuriously consing the argument.
529 (define-vop (fast-eql/fixnum fast-conditional)
530 (:args (x :scs (any-reg))
532 (:arg-types tagged-num tagged-num)
533 (:note "inline fixnum comparison")
536 (cond ((equal y zero-tn)
539 (inst beq x target)))
541 (inst cmpeq x y temp)
543 (inst beq temp target)
544 (inst bne temp target))))))
547 (define-vop (generic-eql/fixnum fast-eql/fixnum)
548 (:args (x :scs (any-reg descriptor-reg))
550 (:arg-types * tagged-num)
553 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
554 (:args (x :scs (any-reg)))
555 (:arg-types tagged-num (:constant (signed-byte 6)))
556 (:temporary (:scs (non-descriptor-reg)) temp)
557 (:info target not-p y)
560 (let ((y (cond ((eql y 0) zero-tn)
562 (inst li (fixnumize y) temp)
564 (inst cmpeq x y temp)
566 (inst beq temp target)
567 (inst bne temp target)))))
569 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
570 (:args (x :scs (any-reg descriptor-reg)))
571 (:arg-types * (:constant (signed-byte 6)))
575 ;;;; 32-bit logical operations
577 (define-vop (merge-bits)
578 (:translate merge-bits)
579 (:args (shift :scs (signed-reg unsigned-reg))
580 (prev :scs (unsigned-reg))
581 (next :scs (unsigned-reg)))
582 (:arg-types tagged-num unsigned-num unsigned-num)
583 (:temporary (:scs (unsigned-reg) :to (:result 0)) temp)
584 (:temporary (:scs (unsigned-reg) :to (:result 0) :target result) res)
585 (:results (result :scs (unsigned-reg)))
586 (:result-types unsigned-num)
589 (let ((done (gen-label)))
590 (inst srl next shift res)
591 (inst beq shift done)
592 (inst subq zero-tn shift temp)
593 (inst sll prev temp temp)
594 (inst bis res temp res)
598 (define-vop (shift-towards-someplace)
600 (:args (num :scs (unsigned-reg))
601 (amount :scs (signed-reg)))
602 (:arg-types unsigned-num tagged-num)
603 (:results (r :scs (unsigned-reg)))
604 (:result-types unsigned-num))
606 (define-vop (shift-towards-start shift-towards-someplace)
607 (:translate shift-towards-start)
608 (:note "SHIFT-TOWARDS-START")
609 (:temporary (:sc non-descriptor-reg) temp)
611 (inst and amount #x1f temp)
612 (inst srl num temp r)))
614 (define-vop (shift-towards-end shift-towards-someplace)
615 (:translate shift-towards-end)
616 (:note "SHIFT-TOWARDS-END")
617 (:temporary (:sc non-descriptor-reg) temp)
619 (inst and amount #x1f temp)
620 (inst sll num temp r)))
624 (define-vop (bignum-length get-header-data)
625 (:translate sb!bignum:%bignum-length)
626 (:policy :fast-safe))
628 (define-vop (bignum-set-length set-header-data)
629 (:translate sb!bignum:%bignum-set-length)
630 (:policy :fast-safe))
632 (define-full-reffer bignum-ref * bignum-digits-offset other-pointer-lowtag
633 (unsigned-reg) unsigned-num sb!bignum:%bignum-ref)
635 (define-full-setter bignum-set * bignum-digits-offset other-pointer-lowtag
636 (unsigned-reg) unsigned-num sb!bignum:%bignum-set #!+gengc nil)
638 (define-vop (digit-0-or-plus)
639 (:translate sb!bignum:%digit-0-or-plusp)
641 (:args (digit :scs (unsigned-reg)))
642 (:arg-types unsigned-num)
643 (:temporary (:sc non-descriptor-reg) temp)
647 (inst sll digit 32 temp)
649 (inst blt temp target)
650 (inst bge temp target))))
652 (define-vop (add-w/carry)
653 (:translate sb!bignum:%add-with-carry)
655 (:args (a :scs (unsigned-reg))
656 (b :scs (unsigned-reg))
657 (c :scs (unsigned-reg)))
658 (:arg-types unsigned-num unsigned-num positive-fixnum)
659 (:results (result :scs (unsigned-reg) :from :load)
660 (carry :scs (unsigned-reg) :from :eval))
661 (:result-types unsigned-num positive-fixnum)
663 (inst addq a b result)
664 (inst addq result c result)
665 (inst sra result 32 carry)
666 (inst mskll result 4 result)))
668 (define-vop (sub-w/borrow)
669 (:translate sb!bignum:%subtract-with-borrow)
671 (:args (a :scs (unsigned-reg))
672 (b :scs (unsigned-reg))
673 (c :scs (unsigned-reg)))
674 (:arg-types unsigned-num unsigned-num positive-fixnum)
675 (:results (result :scs (unsigned-reg) :from :load)
676 (borrow :scs (unsigned-reg) :from :eval))
677 (:result-types unsigned-num positive-fixnum)
679 (inst xor c 1 result)
680 (inst subq a result result)
681 (inst subq result b result)
682 (inst srl result 63 borrow)
683 (inst xor borrow 1 borrow)
684 (inst mskll result 4 result)))
686 (define-vop (bignum-mult-and-add-3-arg)
687 (:translate sb!bignum:%multiply-and-add)
689 (:args (x :scs (unsigned-reg))
690 (y :scs (unsigned-reg))
691 (carry-in :scs (unsigned-reg) :to :save))
692 (:arg-types unsigned-num unsigned-num unsigned-num)
693 (:results (hi :scs (unsigned-reg))
694 (lo :scs (unsigned-reg)))
695 (:result-types unsigned-num unsigned-num)
698 (inst addq lo carry-in lo)
700 (inst mskll lo 4 lo)))
703 (define-vop (bignum-mult-and-add-4-arg)
704 (:translate sb!bignum:%multiply-and-add)
706 (:args (x :scs (unsigned-reg))
707 (y :scs (unsigned-reg))
708 (prev :scs (unsigned-reg))
709 (carry-in :scs (unsigned-reg) :to :save))
710 (:arg-types unsigned-num unsigned-num unsigned-num unsigned-num)
711 (:results (hi :scs (unsigned-reg))
712 (lo :scs (unsigned-reg)))
713 (:result-types unsigned-num unsigned-num)
716 (inst addq lo prev lo)
717 (inst addq lo carry-in lo)
719 (inst mskll lo 4 lo)))
721 (define-vop (bignum-mult)
722 (:translate sb!bignum:%multiply)
724 (:args (x :scs (unsigned-reg))
725 (y :scs (unsigned-reg)))
726 (:arg-types unsigned-num unsigned-num)
727 (:results (hi :scs (unsigned-reg))
728 (lo :scs (unsigned-reg)))
729 (:result-types unsigned-num unsigned-num)
733 (inst mskll lo 4 lo)))
735 (define-vop (bignum-lognot)
736 (:translate sb!bignum:%lognot)
738 (:args (x :scs (unsigned-reg)))
739 (:arg-types unsigned-num)
740 (:results (r :scs (unsigned-reg)))
741 (:result-types unsigned-num)
746 (define-vop (fixnum-to-digit)
747 (:translate sb!bignum:%fixnum-to-digit)
749 (:args (fixnum :scs (any-reg)))
750 (:arg-types tagged-num)
751 (:results (digit :scs (unsigned-reg)))
752 (:result-types unsigned-num)
754 (inst sra fixnum n-fixnum-tag-bits digit)))
756 (define-vop (bignum-floor)
757 (:translate sb!bignum:%floor)
759 (:args (num-high :scs (unsigned-reg))
760 (num-low :scs (unsigned-reg))
761 (denom-arg :scs (unsigned-reg) :target denom))
762 (:arg-types unsigned-num unsigned-num unsigned-num)
763 (:temporary (:scs (unsigned-reg) :from (:argument 2)) denom)
764 (:temporary (:scs (unsigned-reg) :from (:eval 0)) temp)
765 (:results (quo :scs (unsigned-reg) :from (:eval 0))
766 (rem :scs (unsigned-reg) :from (:argument 0)))
767 (:result-types unsigned-num unsigned-num)
768 (:generator 325 ; number of inst assuming targeting works.
769 (inst sll num-high 32 rem)
770 (inst bis rem num-low rem)
771 (inst sll denom-arg 32 denom)
772 (inst cmpule denom rem quo)
773 (inst beq quo shift1)
774 (inst subq rem denom rem)
777 (let ((shift2 (gen-label)))
778 (inst srl denom 1 denom)
779 (inst cmpule denom rem temp)
781 (inst beq temp shift2)
782 (inst subq rem denom rem)
784 (emit-label shift2)))))
786 (define-vop (signify-digit)
787 (:translate sb!bignum:%fixnum-digit-with-correct-sign)
789 (:args (digit :scs (unsigned-reg) :target res))
790 (:arg-types unsigned-num)
791 (:results (res :scs (any-reg signed-reg)))
792 (:result-types signed-num)
796 (inst sll digit 34 res)
797 (inst sra res 32 res))
799 (inst sll digit 32 res)
800 (inst sra res 32 res)))))
803 (define-vop (digit-ashr)
804 (:translate sb!bignum:%ashr)
806 (:args (digit :scs (unsigned-reg))
807 (count :scs (unsigned-reg)))
808 (:arg-types unsigned-num positive-fixnum)
809 (:results (result :scs (unsigned-reg) :from (:argument 0)))
810 (:result-types unsigned-num)
812 (inst sll digit 32 result)
813 (inst sra result count result)
814 (inst srl result 32 result)))
816 (define-vop (digit-lshr digit-ashr)
817 (:translate sb!bignum:%digit-logical-shift-right)
819 (inst srl digit count result)))
821 (define-vop (digit-ashl digit-ashr)
822 (:translate sb!bignum:%ashl)
824 (inst sll digit count result)))
826 ;;;; static functions
828 (define-static-fun two-arg-gcd (x y) :translate gcd)
829 (define-static-fun two-arg-lcm (x y) :translate lcm)
831 (define-static-fun two-arg-+ (x y) :translate +)
832 (define-static-fun two-arg-- (x y) :translate -)
833 (define-static-fun two-arg-* (x y) :translate *)
834 (define-static-fun two-arg-/ (x y) :translate /)
836 (define-static-fun two-arg-< (x y) :translate <)
837 (define-static-fun two-arg-<= (x y) :translate <=)
838 (define-static-fun two-arg-> (x y) :translate >)
839 (define-static-fun two-arg->= (x y) :translate >=)
840 (define-static-fun two-arg-= (x y) :translate =)
841 (define-static-fun two-arg-/= (x y) :translate /=)
843 (define-static-fun %negate (x) :translate %negate)
845 (define-static-fun two-arg-and (x y) :translate logand)
846 (define-static-fun two-arg-ior (x y) :translate logior)
847 (define-static-fun two-arg-xor (x y) :translate logxor)
848 (define-static-fun two-arg-eqv (x y) :translate logeqv)