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

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

/* [<][>][^][v][top][bottom][index][help] */