root/arch/alpha/lib/divide.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  * arch/alpha/lib/divide.S
   3  *
   4  * (C) 1995 Linus Torvalds
   5  *
   6  * Alpha division..
   7  */
   8 
   9 /*
  10  * The alpha chip doesn't provide hardware division, so we have to do it
  11  * by hand.  The compiler expects the functions
  12  *
  13  *      __divqu: 64-bit unsigned long divide
  14  *      __remqu: 64-bit unsigned long reminder
  15  *      __divqs/__remqs: signed 64-bit
  16  *      __divlu/__remlu: unsigned 32-bit
  17  *      __divls/__remls: signed 32-bit
  18  *
  19  * These are not normal C functions: instead of the normal
  20  * calling sequence, these expect their arguments in registers
  21  * $24 and $25, and return the result in $27. Register $28 may
  22  * be clobbered (assembly temprary), anything else must be saved. 
  23  *
  24  * In short: painful. I'm not going to try to be clever about it:
  25  * let somebody else optimize it if they will.
  26  */
  27 
  28 /*
  29  * My temporaries:
  30  *      $0 - current bit
  31  *      $1 - shifted divisor
  32  *      $2 - rest
  33  *      $3 - compare status
  34  *
  35  *      $23 - return address
  36  *      $24 - dividend
  37  *      $25 - divisor
  38  */
  39 
  40 /*
  41  * Select function type and registers
  42  */
  43 #ifdef DIV
  44 #define func(x) __div##x
  45 #define modulus $2
  46 #define quotient $27
  47 #else
  48 #define func(x) __rem##x
  49 #define modulus $27
  50 #define quotient $2
  51 #endif
  52 
  53 /*
  54  * For 32-bit operations, we need to extend to 64-bit
  55  */
  56 #ifdef INTSIZE
  57 #define function func(lu)
  58 #define LONGIFY(x) zapnot x,15,x
  59 #else
  60 #define function func(qu)
  61 #define LONGIFY(x)
  62 #endif
  63 
  64 .globl  function
  65 .ent    function
  66 function:
  67         lda     $30,-32($30)
  68         stq     $0, 0($30)
  69         stq     $1, 8($30)
  70         stq     $2,16($30)
  71         stq     $3,24($30)
  72         bis     $25,$25,$1
  73         bis     $24,$24,modulus
  74         bis     $31,$31,quotient
  75         LONGIFY($1)
  76         LONGIFY(modulus)
  77         beq     $1, 9f                  /* div by zero */
  78         bis     $31,1,$0
  79         blt     $1, 2f                  /* high bit set */
  80 1:      cmpult  modulus,$1,$3
  81         bne     $3,3f
  82         addq    $1,$1,$1
  83         addq    $0,$0,$0
  84         bge     $1,1b
  85 2:      cmpult  modulus,$1,$3
  86         bne     $3,3f
  87         subq    modulus,$1,modulus
  88         addq    $0,quotient,quotient
  89 3:      srl     $0,1,$0
  90         srl     $1,1,$1
  91         bne     $0,2b
  92 9:      ldq     $0, 0($30)
  93         ldq     $1, 8($30)
  94         ldq     $2, 16($30)
  95         ldq     $3, 32($30)
  96         lda     $30,32($30)
  97         ret     $31,($23),1
  98         .end    function

/* [previous][next][first][last][top][bottom][index][help] */