Changeset 9552 for branches/ia32/level0
 Timestamp:
 May 20, 2008, 6:01:33 AM (12 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/ia32/level0/X86/X8632/x8632bignum.lisp
r9539 r9552 654 654 (singlevaluereturn 3))) 655 655 656 ;;; shift bignum left by nbits bits (1 <= nbits < 32) 657 ;;; j is one more than the number of digits in bignum 656 658 (defx8632lapfunction bignumshiftleftloop ((nbits 12) (result 8) 657 659 (bignum 4) #(ra 0)# 658 660 (reslen1 arg_y) (j arg_z)) 659 (movl (@ nbits (% esp)) (% imm0)) 661 (movl (% ebp) (@ 16 (% esp))) 662 (leal (@ 16 (% esp)) (% ebp)) 663 (popl (@ 4 (% ebp))) 664 (push (% arg_y)) ;ebp  16 665 (push (% arg_z)) ;ebp  20 666 667 (movl (@ 4 (% ebp)) (% imm0)) 660 668 (sarl ($ x8632::fixnumshift) (% imm0)) 661 669 (movd (% imm0) (% mm7)) ;shift count 662 670 (negl (% imm0)) 663 (addl ($ 32) (% imm0)) ;remainingbits = 32  shiftcount671 (addl ($ 32) (% imm0)) 664 672 (movd (% imm0) (% mm6)) ;remaining bits 665 (movl (@ result (% esp)) (% temp0)) 666 (movl (@ bignum (% esp)) (% temp1)) 667 (push (% arg_z)) 668 (push (% arg_y)) 669 (xorl (% arg_y) (% arg_y)) ;i 670 (jmp @test) 671 @loop 672 (movd (@ x8632::miscdataoffset (% temp1) (% arg_y)) (% mm0)) ;b[i] 673 (psrlq (% mm6) (% mm0)) 674 (movd (@ (+ 4 x8632::miscdataoffset) (% temp1) (% arg_y)) (% mm1)) ;b[i+1] 675 (psllq (% mm7) (% mm1)) 676 (por (% mm1) (% mm0)) 677 (movd (% mm0) (@ x8632::miscdataoffset (% temp0) (% arg_z))) ;r[j] 678 (addl ($ '1) (% arg_y)) 679 (addl ($ '1) (% arg_z)) 680 @test 681 (cmpl (@ (% esp)) (% j)) ;pity reslen1 can't stay in a reg 682 (jne @loop) 683 (add ($ '1) (% esp)) ;discard pushed reslen1 684 (movd (@ x8632::miscdataoffset (% temp1) (% arg_y)) (% mm0)) ;b[i] 685 (psrlq (% mm6) (% mm0)) 686 (movd (% mm0) (@ x8632::miscdataoffset (% temp0) (% arg_z))) ;r[j] 687 ;; reconstitute "digits" arg to bignumashiftleftunaligned 688 (pop (% arg_z)) 689 (subl ($ '1) (% arg_z)) 690 (movd (@ x8632::miscdataoffset (% temp1)) (% mm0)) ;b[0] 691 (psllq (% mm7) (% mm0)) 692 (movd (% mm0) (@ x8632::miscdataoffset (% temp0) (% arg_z))) ;b[digits] 693 (singlevaluereturn 5)) 673 674 (let ((rl1 16) 675 (r temp0) 676 (b temp1) 677 (i arg_y) 678 (i+1 imm0)) 679 (movl (@ 8 (% ebp)) (% r)) 680 (movl (@ 12 (% ebp)) (% b)) 681 (xorl (% i) (% i)) 682 (movl ($ '1) (% i+1)) 683 ;; j (in arg_z) is already (1+ digits) 684 (jmp @test) 685 @loop 686 (movd (@ x8632::miscdataoffset (% b) (% i)) (% mm0)) 687 (psrlq (% mm6) (% mm0)) 688 (movd (@ x8632::miscdataoffset (% b) (% i+1)) (% mm1)) 689 (psllq (% mm7) (% mm1)) 690 (por (% mm1) (% mm0)) 691 (movd (% mm0) (@ x8632::miscdataoffset (% r) (% j))) 692 (movl (% i+1) (% i)) 693 (addl ($ '1) (% i)) 694 (addl ($ '1) (% j)) 695 @test 696 (cmpl (@ rl1 (% ebp)) (% j)) 697 (jne @loop) 698 (movd (@ x8632::miscdataoffset (% b)) (% mm0)) 699 (psllq (% mm7) (% mm0)) 700 (movl (@ 20 (% ebp)) (% imm0)) ;digits + 1 (that is, the original j) 701 (subl ($ '1) (% imm0)) ;digits 702 (movd (% mm0) (@ x8632::miscdataoffset (% r) (% imm0))) 703 (movd (@ x8632::miscdataoffset (% b) (% i)) (% mm0)) 704 (psrad (% mm6) (% mm0)) 705 (addl ($ '1) (% imm0)) ;original j again 706 (movd (% mm0) (@ x8632::miscdataoffset (% r) (% j)))) 707 (leave) 708 (ret)) 694 709 695 710 ;;; shift bignum right by i words plus nbits bits. … … 834 849 (jmpsubprim .SPvalues)) 835 850 851 ;;; transliterated from bignumtruncateguess in l0bignum64.lisp 852 ;;; this is not beautiful... 836 853 (defx8632lapfunction truncateguessloop ((guessh 16) (guessl 12) (x 8) 837 854 (xidx 4) #(ra 0)# 838 855 (yptr arg_y) (yidx arg_z)) 839 (int ($ 3))) 856 (movl (% ebp) (@ 20 (% esp))) 857 (leal (@ 20 (% esp)) (% ebp)) 858 (popl (@ 4 (% ebp))) 859 (push (% arg_y)) 860 (push (% arg_z)) 861 862 (movl (@ 4 (% ebp)) (% temp0)) ;guessh 863 (movl (@ 8 (% ebp)) (% temp1)) ;guessl 864 (composedigit temp0 temp1 imm0) 865 (movd (% imm0) (% mm0)) ;save guess 866 867 (movd (@ ( x8632::miscdataoffset 0) (% yptr) (% yidx)) (% mm1)) ;y1 (high) 868 ;; (%multiply guess y1) 869 (pmuludq (% mm0) (% mm1)) 870 ;; (%multiply guess y2) 871 (movd (@ ( x8632::miscdataoffset 4) (% yptr) (% yidx)) (% mm2)) ;y2 (low) 872 (pmuludq (% mm0) (% mm2)) 873 874 (movl (@ 12 (% ebp)) (% temp0)) ;x 875 (movl (@ 16 (% ebp)) (% arg_y)) ;xidx 876 (markasimm temp1) ;edx now unboxed 877 878 ;; (%subtractwithborrow xi1 lowguess*y1 1) 879 (movl (@ ( x8632::miscdataoffset 4) (% temp0) (% arg_y)) (% edx)) ;xi1 880 (movd (% mm1) (% eax)) ;low part of y1*guess 881 (subl (% eax) (% edx)) 882 (movd (% edx) (% mm6)) ;save middle digit 883 ;; (%subtractwithborrow xi highguess*y1 borrow) 884 (movl (@ ( x8632::miscdataoffset 0) (% temp0) (% arg_y)) (% edx)) ;xi 885 (movq (% mm1) (% mm3)) 886 (psrlq ($ 32) (% mm3)) ;get high part into low half 887 (movd (% mm3) (% eax)) ;high part of y1*guess 888 (sbbl (% eax) (% edx)) 889 (movd (% edx) (% mm7)) ;save high digit 890 ;; guess is now either good, or one too large 891 (setc (%b arg_z.bh)) ;save borrow (arg_z already tagfixnum) 892 ;; if (and (= highdigit 0) 893 (test (% edx) (% edx)) 894 (jne @return) 895 ;; (or (> highguess*y2 middledigit) 896 (movq (% mm2) (% mm3)) 897 (psrlq ($ 32) (% mm3)) 898 (movd (% mm3) (% eax)) ;high part of y2*guess 899 (movd (% mm6) (% edx)) ;middledigit 900 (cmpl (% edx) (% eax)) 901 (jg @decrement) 902 ;; (and (= middledigit highguess*y2) 903 (jne @decrement) 904 ;; (> lowguess*y2 xi2) 905 (movd (% mm2) (% eax)) ;low part of y2*guess 906 (movl (@ ( x8632::miscdataoffset 8) (% temp0) (% arg_y)) (% edx)) ;xi2 907 (cmpl (% edx) (% eax)) 908 (jg @decrement) 909 @return 910 (markasnode edx) 911 (leave) 912 (movl (% esp) (% temp0)) 913 (movd (% mm0) (% imm0)) 914 (shrl ($ 16) (% imm0)) 915 (shll ($ x8632::fixnumshift) (% imm0)) ;high half 916 (push (% imm0)) 917 (movd (% mm0) (% imm0)) 918 (shll ($ 16) (% imm0)) 919 (shrl ($ ( 16 x8632::fixnumshift)) (% imm0)) 920 (push (% imm0)) ;low half 921 (setnargs 2) 922 (jmpsubprim .SPvalues) 923 @decrement 924 (movd (% mm0) (% imm0)) ;guess 925 (btl ($ 8) (% temp0)) ;restore state of carry flag 926 (sbb ($ 1) (% imm0)) 927 (movd (% imm0) (% mm0)) 928 (jmp @return)) 840 929 841 930 ;;; If x[i] = y[j], return the all ones digit (as two halves). … … 847 936 (pop (% temp1)) 848 937 (discardreservedframe) 849 (push (% temp 1))850 (movl (% imm0) (% temp 1))851 (movl (@ (% temp0) (% temp1)) (% imm0)) ;x[i]852 (cmpl (% imm0) (@ (% yptr) (% yidx))) ;y[j]938 (push (% temp0)) 939 (movl (% imm0) (% temp0)) 940 (movl (@ x8632::miscdataoffset (% temp1) (% temp0)) (% imm0)) ;x[i] 941 (cmpl (% imm0) (@ x8632::miscdataoffset (% yptr) (% yidx))) ;y[j] 853 942 (jne @more) 854 943 (pushl ($ '#xffff)) … … 859 948 @more 860 949 (markasimm edx) ;aka temp1 (contains a fixnum) 861 (movl (@ 4 (% temp0) (% temp1)) (% eax)) ;low digit862 (movl (@ (% temp0) (% temp1)) (% edx)) ;high digit950 (movl (@ ( x8632::miscdataoffset 4) (% temp1) (% temp0)) (% eax)) ;low 951 (movl (@ x8632::miscdataoffset (% temp1) (% temp0)) (% edx)) ;high digit 863 952 (divl (@ (% yptr) (% yidx))) 864 953 (markasnode edx) … … 876 965 (jmpsubprim .SPvalues)) 877 966 967 ;;; x * y + carry 878 968 (defx8632lapfunction %multiplyandadd1 ((xhigh 16) 879 969 (xlow 12) … … 883 973 (carryinhigh arg_y) 884 974 (carryinlow arg_z)) 885 (int ($ 3))) 975 (movl (@ xhigh (% esp)) (% temp0)) 976 (movl (@ xlow (% esp)) (% temp1)) 977 (composedigit temp0 temp1 imm0) 978 (movd (% imm0) (% mm0)) 979 (movl (@ yhigh (% esp)) (% temp0)) 980 (movl (@ ylow (% esp)) (% temp1)) 981 (composedigit temp0 temp1 imm0) 982 (movd (% imm0) (% mm1)) 983 (pmuludq (% mm1) (% mm0)) ;x * y 984 (composedigit arg_y arg_z imm0) 985 (movd (% imm0) (% mm1)) 986 (paddq (% mm1) (% mm0)) ;add in carry digit 987 (movq (% mm0) (% mm1)) 988 (psrlq ($ 32) (% mm1)) ;resultant carry digit 989 ;; clean up stack 990 (pop (% temp0)) 991 (addl ($ '6) (% esp)) 992 (push (% temp0)) 993 ;; return (values carryh carryl resulth resultl) 994 (movl (% esp) (% temp0)) 995 (movd (% mm1) (% imm0)) 996 (shrl ($ 16) (% imm0)) 997 (shll ($ x8632::fixnumshift) (% imm0)) ;carryh 998 (push (% imm0)) 999 (movd (% mm1) (% imm0)) 1000 (shll ($ 16) (% imm0)) 1001 (shrl ($ ( 16 x8632::fixnumshift)) (% imm0)) ;carryl 1002 (push (% imm0)) 1003 (movd (% mm0) (% imm0)) 1004 (shrl ($ 16) (% imm0)) 1005 (shll ($ x8632::fixnumshift) (% imm0)) ;resulth 1006 (push (% imm0)) 1007 (movd (% mm0) (% imm0)) 1008 (shll ($ 16) (% imm0)) 1009 (shrl ($ ( 16 x8632::fixnumshift)) (% imm0)) ;resultl 1010 (push (% imm0)) 1011 (setnargs 4) 1012 (jmpsubprim .SPvalues)) 886 1013 887 1014 ;;; Copy the limb SRC points to to where DEST points.
Note: See TracChangeset
for help on using the changeset viewer.