root/arch/i386/math-emu/wm_shrx.S

/* [previous][next][first][last][top][bottom][index][help] */
   1         .file   "wm_shrx.S"
   2 /*---------------------------------------------------------------------------+
   3  |  wm_shrx.S                                                                |
   4  |                                                                           |
   5  | 64 bit right shift functions                                              |
   6  |                                                                           |
   7  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
   9  |                                                                           |
  10  | Call from C as:                                                           |
  11  |   unsigned shrx(void *arg1, unsigned arg2)                                |
  12  | and                                                                       |
  13  |   unsigned shrxs(void *arg1, unsigned arg2)                               |
  14  |                                                                           |
  15  +---------------------------------------------------------------------------*/
  16 
  17 #include "fpu_asm.h"
  18 
  19 .text
  20 /*---------------------------------------------------------------------------+
  21  |   unsigned shrx(void *arg1, unsigned arg2)                                |
  22  |                                                                           |
  23  |   Extended shift right function.                                          |
  24  |   Fastest for small shifts.                                               |
  25  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
  26  |   right by the number of bits specified by the second arg (arg2).         |
  27  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
  28  |                [  64 bit arg ][ eax ]                                     |
  29  |            shift right  --------->                                        |
  30  |   The eax register is initialized to 0 before the shifting.               |
  31  |   Results returned in the 64 bit arg and eax.                             |
  32  +---------------------------------------------------------------------------*/
  33 
  34 ENTRY(shrx)
  35         push    %ebp
  36         movl    %esp,%ebp
  37         pushl   %esi
  38         movl    PARAM2,%ecx
  39         movl    PARAM1,%esi
  40         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
  41         jnc     L_more_than_31
  42 
  43 /* less than 32 bits */
  44         pushl   %ebx
  45         movl    (%esi),%ebx     /* lsl */
  46         movl    4(%esi),%edx    /* msl */
  47         xorl    %eax,%eax       /* extension */
  48         shrd    %cl,%ebx,%eax
  49         shrd    %cl,%edx,%ebx
  50         shr     %cl,%edx
  51         movl    %ebx,(%esi)
  52         movl    %edx,4(%esi)
  53         popl    %ebx
  54         popl    %esi
  55         leave
  56         ret
  57 
  58 L_more_than_31:
  59         cmpl    $64,%ecx
  60         jnc     L_more_than_63
  61 
  62         subb    $32,%cl
  63         movl    (%esi),%eax     /* lsl */
  64         movl    4(%esi),%edx    /* msl */
  65         shrd    %cl,%edx,%eax
  66         shr     %cl,%edx
  67         movl    %edx,(%esi)
  68         movl    $0,4(%esi)
  69         popl    %esi
  70         leave
  71         ret
  72 
  73 L_more_than_63:
  74         cmpl    $96,%ecx
  75         jnc     L_more_than_95
  76 
  77         subb    $64,%cl
  78         movl    4(%esi),%eax    /* msl */
  79         shr     %cl,%eax
  80         xorl    %edx,%edx
  81         movl    %edx,(%esi)
  82         movl    %edx,4(%esi)
  83         popl    %esi
  84         leave
  85         ret
  86 
  87 L_more_than_95:
  88         xorl    %eax,%eax
  89         movl    %eax,(%esi)
  90         movl    %eax,4(%esi)
  91         popl    %esi
  92         leave
  93         ret
  94 
  95 
  96 /*---------------------------------------------------------------------------+
  97  |   unsigned shrxs(void *arg1, unsigned arg2)                               |
  98  |                                                                           |
  99  |   Extended shift right function (optimized for small floating point       |
 100  |   integers).                                                              |
 101  |   Shifts the 64 bit quantity pointed to by the first arg (arg1)           |
 102  |   right by the number of bits specified by the second arg (arg2).         |
 103  |   Forms a 96 bit quantity from the 64 bit arg and eax:                    |
 104  |                [  64 bit arg ][ eax ]                                     |
 105  |            shift right  --------->                                        |
 106  |   The eax register is initialized to 0 before the shifting.               |
 107  |   The lower 8 bits of eax are lost and replaced by a flag which is        |
 108  |   set (to 0x01) if any bit, apart from the first one, is set in the       |
 109  |   part which has been shifted out of the arg.                             |
 110  |   Results returned in the 64 bit arg and eax.                             |
 111  +---------------------------------------------------------------------------*/
 112 ENTRY(shrxs)
 113         push    %ebp
 114         movl    %esp,%ebp
 115         pushl   %esi
 116         pushl   %ebx
 117         movl    PARAM2,%ecx
 118         movl    PARAM1,%esi
 119         cmpl    $64,%ecx        /* shrd only works for 0..31 bits */
 120         jnc     Ls_more_than_63
 121 
 122         cmpl    $32,%ecx        /* shrd only works for 0..31 bits */
 123         jc      Ls_less_than_32
 124 
 125 /* We got here without jumps by assuming that the most common requirement
 126    is for small integers */
 127 /* Shift by [32..63] bits */
 128         subb    $32,%cl
 129         movl    (%esi),%eax     /* lsl */
 130         movl    4(%esi),%edx    /* msl */
 131         xorl    %ebx,%ebx
 132         shrd    %cl,%eax,%ebx
 133         shrd    %cl,%edx,%eax
 134         shr     %cl,%edx
 135         orl     %ebx,%ebx               /* test these 32 bits */
 136         setne   %bl
 137         test    $0x7fffffff,%eax        /* and 31 bits here */
 138         setne   %bh
 139         orw     %bx,%bx                 /* Any of the 63 bit set ? */
 140         setne   %al
 141         movl    %edx,(%esi)
 142         movl    $0,4(%esi)
 143         popl    %ebx
 144         popl    %esi
 145         leave
 146         ret
 147 
 148 /* Shift by [0..31] bits */
 149 Ls_less_than_32:
 150         movl    (%esi),%ebx     /* lsl */
 151         movl    4(%esi),%edx    /* msl */
 152         xorl    %eax,%eax       /* extension */
 153         shrd    %cl,%ebx,%eax
 154         shrd    %cl,%edx,%ebx
 155         shr     %cl,%edx
 156         test    $0x7fffffff,%eax        /* only need to look at eax here */
 157         setne   %al
 158         movl    %ebx,(%esi)
 159         movl    %edx,4(%esi)
 160         popl    %ebx
 161         popl    %esi
 162         leave
 163         ret
 164 
 165 /* Shift by [64..95] bits */
 166 Ls_more_than_63:
 167         cmpl    $96,%ecx
 168         jnc     Ls_more_than_95
 169 
 170         subb    $64,%cl
 171         movl    (%esi),%ebx     /* lsl */
 172         movl    4(%esi),%eax    /* msl */
 173         xorl    %edx,%edx       /* extension */
 174         shrd    %cl,%ebx,%edx
 175         shrd    %cl,%eax,%ebx
 176         shr     %cl,%eax
 177         orl     %ebx,%edx
 178         setne   %bl
 179         test    $0x7fffffff,%eax        /* only need to look at eax here */
 180         setne   %bh
 181         orw     %bx,%bx
 182         setne   %al
 183         xorl    %edx,%edx
 184         movl    %edx,(%esi)     /* set to zero */
 185         movl    %edx,4(%esi)    /* set to zero */
 186         popl    %ebx
 187         popl    %esi
 188         leave
 189         ret
 190 
 191 Ls_more_than_95:
 192 /* Shift by [96..inf) bits */
 193         xorl    %eax,%eax
 194         movl    (%esi),%ebx
 195         orl     4(%esi),%ebx
 196         setne   %al
 197         xorl    %ebx,%ebx
 198         movl    %ebx,(%esi)
 199         movl    %ebx,4(%esi)
 200         popl    %ebx
 201         popl    %esi
 202         leave
 203         ret

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