/*
   This file is part of Numerix.  Numerix is free software; you can
   redistribute it and/or modify it under the terms of the GNU General
   Public License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA 
*/

/* +------------------------------------------------------------------------+
   |                                                                        |
   |                      Entiers de longueur arbitraire                    |
   |                                                                        |
   |                              Comparaisons                              |
   |                                                                        |
   +------------------------------------------------------------------------+ */

/* M. Quercia, 31/01/2001 */

#include "macros-s.h"


  /* +----------------------------------------------------------+
     |  compare a et b, retourne la longueur algébrique de a-b  |
     +----------------------------------------------------------+ */

/* longueur sn_cmp(naturel a, longueur la, naturel b, longueur lb) */
#ifdef have_sn_cmp
ENTER(sn_cmp)

        /* élimine les zéros de tête */
        movl   a,%esi
        movl   la,%ecx
        jecxz  .Lsn_cmp_a_ok
        .align 4

.Lsn_cmp_a_test:
        movl   -4(%esi,%ecx,4),%eax
        testl  %eax,%eax
        jnz    .Lsn_cmp_a_ok
        loop   .Lsn_cmp_a_test
.Lsn_cmp_a_ok:
        movl   %ecx,%edx
    
        movl   b,%edi
        movl   lb,%ecx
        jecxz  .Lsn_cmp_b_ok
        .align 4

.Lsn_cmp_b_test:
        movl   -4(%edi,%ecx,4),%eax
        testl  %eax,%eax
        jnz    .Lsn_cmp_b_ok
        loop   .Lsn_cmp_b_test
.Lsn_cmp_b_ok:
    
        /* si les longeurs sont égales, compare les chiffres */
        cmpl   %ecx,%edx
        jne    .Lsn_cmp_lg_diff
        jecxz  .Lsn_cmp_digits_eq
        .align 4

.Lsn_cmp_digits_test:
        movl   -4(%esi,%ecx,4),%eax
        cmpl   -4(%edi,%ecx,4),%eax
        jne    .Lsn_cmp_digits_diff
        loop   .Lsn_cmp_digits_test
.Lsn_cmp_digits_eq:
        xorl   %eax,%eax
        RETURN

.Lsn_cmp_digits_diff:
        movl   %ecx,%eax
        ja     .Lsn_cmp_exit
        negl   %eax
        RETURN

.Lsn_cmp_lg_diff:
        movl   %edx,%eax
        ja     .Lsn_cmp_exit
        movl   %ecx,%eax
        negl   %eax

EXIT(sn_cmp)
#endif

                 /* +----------------------------+
                    |  retourne le signe de a-b  |
                    +----------------------------+ */

/* long xz(cmp)(entier *a, entier *b) */
#ifdef have_sz_cmp
ENTER(sz_cmp)

        movl   za,%esi
        movl   zb,%edi
        movl   (%esi),%edx
        movl   (%edi),%ecx

        /* sépare les signes et les longueurs */
        movl   %edx,%eax
        andl   $LONG_m,%edx
        jnz    .Lsz_cmp_saok
        movl   %edx,%eax
.Lsz_cmp_saok:
        movl   %ecx,%ebx
        andl   $LONG_m,%ecx
        jnz    .Lsz_cmp_sbok
        movl   %ecx,%ebx
.Lsz_cmp_sbok:

        /* compare les signes */
        xorl   %eax,%ebx
        jns    .Lsz_cmp_signeq
        testl  %eax,%eax
        jns    .Lsz_cmp_a_smaller
        jmp    .Lsz_cmp_a_bigger

        /* compare les longueurs */
.Lsz_cmp_signeq:
        movl   %eax,%ebx
        cmpl   %ecx,%edx
        ja     .Lsz_cmp_a_bigger
        jb     .Lsz_cmp_a_smaller

        /* compare les chiffres de tête */
        jecxz  .Lsz_cmp_equal
        .align 4
.Lsz_cmp_digits:
        movl   (%esi,%ecx,4),%eax
        cmpl   (%edi,%ecx,4),%eax
        ja     .Lsz_cmp_a_bigger
        jb     .Lsz_cmp_a_smaller
        loop   .Lsz_cmp_digits
.Lsz_cmp_equal:
        xorl   %eax,%eax
        RETURN

.Lsz_cmp_a_bigger:
        movl   $1,%eax
        jmp    .Lsz_cmp_chgsgn
.Lsz_cmp_a_smaller:
        movl   $-1,%eax
.Lsz_cmp_chgsgn:
        testl  %ebx,%ebx
        jns    .Lsz_cmp_exit
        negl   %eax

EXIT(sz_cmp)
#endif
