root/kernel/math/get_put.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_short_real
  2. get_long_real
  3. get_temp_real
  4. get_short_int
  5. get_long_int
  6. get_longlong_int
  7. get_BCD
  8. put_short_real
  9. put_long_real
  10. put_temp_real
  11. put_short_int
  12. put_long_int
  13. put_longlong_int
  14. put_BCD

   1 /*
   2  * linux/kernel/math/get_put.c
   3  *
   4  * (C) 1991 Linus Torvalds
   5  */
   6 
   7 /*
   8  * This file handles all accesses to user memory: getting and putting
   9  * ints/reals/BCD etc. This is the only part that concerns itself with
  10  * other than temporary real format. All other cals are strictly temp_real.
  11  */
  12 #include <signal.h>
  13 
  14 #include <linux/math_emu.h>
  15 #include <linux/kernel.h>
  16 #include <asm/segment.h>
  17 
  18 void get_short_real(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  19         struct info * info, unsigned short code)
  20 {
  21         char * addr;
  22         short_real sr;
  23 
  24         addr = ea(info,code);
  25         sr = get_fs_long((unsigned long *) addr);
  26         short_to_temp(&sr,tmp);
  27 }
  28 
  29 void get_long_real(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  30         struct info * info, unsigned short code)
  31 {
  32         char * addr;
  33         long_real lr;
  34 
  35         addr = ea(info,code);
  36         lr.a = get_fs_long((unsigned long *) addr);
  37         lr.b = get_fs_long(1 + (unsigned long *) addr);
  38         long_to_temp(&lr,tmp);
  39 }
  40 
  41 void get_temp_real(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  42         struct info * info, unsigned short code)
  43 {
  44         char * addr;
  45 
  46         addr = ea(info,code);
  47         tmp->a = get_fs_long((unsigned long *) addr);
  48         tmp->b = get_fs_long(1 + (unsigned long *) addr);
  49         tmp->exponent = get_fs_word(4 + (unsigned short *) addr);
  50 }
  51 
  52 void get_short_int(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  53         struct info * info, unsigned short code)
  54 {
  55         char * addr;
  56         temp_int ti;
  57 
  58         addr = ea(info,code);
  59         ti.a = (signed short) get_fs_word((unsigned short *) addr);
  60         ti.b = 0;
  61         if (ti.sign = (ti.a < 0))
  62                 ti.a = - ti.a;
  63         int_to_real(&ti,tmp);
  64 }
  65 
  66 void get_long_int(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  67         struct info * info, unsigned short code)
  68 {
  69         char * addr;
  70         temp_int ti;
  71 
  72         addr = ea(info,code);
  73         ti.a = get_fs_long((unsigned long *) addr);
  74         ti.b = 0;
  75         if (ti.sign = (ti.a < 0))
  76                 ti.a = - ti.a;
  77         int_to_real(&ti,tmp);
  78 }
  79 
  80 void get_longlong_int(temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
  81         struct info * info, unsigned short code)
  82 {
  83         char * addr;
  84         temp_int ti;
  85 
  86         addr = ea(info,code);
  87         ti.a = get_fs_long((unsigned long *) addr);
  88         ti.b = get_fs_long(1 + (unsigned long *) addr);
  89         if (ti.sign = (ti.b < 0))
  90                 __asm__("notl %0 ; notl %1\n\t"
  91                         "addl $1,%0 ; adcl $0,%1"
  92                         :"=r" (ti.a),"=r" (ti.b)
  93                         :"0" (ti.a),"1" (ti.b));
  94         int_to_real(&ti,tmp);
  95 }
  96 
  97 #define MUL10(low,high) \
  98 __asm__("addl %0,%0 ; adcl %1,%1\n\t" \
  99 "movl %0,%%ecx ; movl %1,%%ebx\n\t" \
 100 "addl %0,%0 ; adcl %1,%1\n\t" \
 101 "addl %0,%0 ; adcl %1,%1\n\t" \
 102 "addl %%ecx,%0 ; adcl %%ebx,%1" \
 103 :"=a" (low),"=d" (high) \
 104 :"0" (low),"1" (high):"cx","bx")
 105 
 106 #define ADD64(val,low,high) \
 107 __asm__("addl %4,%0 ; adcl $0,%1":"=r" (low),"=r" (high) \
 108 :"0" (low),"1" (high),"r" ((unsigned long) (val)))
 109 
 110 void get_BCD(temp_real * tmp, struct info * info, unsigned short code)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         int k;
 113         char * addr;
 114         temp_int i;
 115         unsigned char c;
 116 
 117         addr = ea(info,code);
 118         addr += 9;
 119         i.sign = 0x80 & get_fs_byte(addr--);
 120         i.a = i.b = 0;
 121         for (k = 0; k < 9; k++) {
 122                 c = get_fs_byte(addr--);
 123                 MUL10(i.a, i.b);
 124                 ADD64((c>>4), i.a, i.b);
 125                 MUL10(i.a, i.b);
 126                 ADD64((c&0xf), i.a, i.b);
 127         }
 128         int_to_real(&i,tmp);
 129 }
 130 
 131 void put_short_real(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 132         struct info * info, unsigned short code)
 133 {
 134         char * addr;
 135         short_real sr;
 136 
 137         addr = ea(info,code);
 138         verify_area(addr,4);
 139         temp_to_short(tmp,&sr);
 140         put_fs_long(sr,(unsigned long *) addr);
 141 }
 142 
 143 void put_long_real(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 144         struct info * info, unsigned short code)
 145 {
 146         char * addr;
 147         long_real lr;
 148 
 149         addr = ea(info,code);
 150         verify_area(addr,8);
 151         temp_to_long(tmp,&lr);
 152         put_fs_long(lr.a, (unsigned long *) addr);
 153         put_fs_long(lr.b, 1 + (unsigned long *) addr);
 154 }
 155 
 156 void put_temp_real(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 157         struct info * info, unsigned short code)
 158 {
 159         char * addr;
 160 
 161         addr = ea(info,code);
 162         verify_area(addr,10);
 163         put_fs_long(tmp->a, (unsigned long *) addr);
 164         put_fs_long(tmp->b, 1 + (unsigned long *) addr);
 165         put_fs_word(tmp->exponent, 4 + (short *) addr);
 166 }
 167 
 168 void put_short_int(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 169         struct info * info, unsigned short code)
 170 {
 171         char * addr;
 172         temp_int ti;
 173 
 174         addr = ea(info,code);
 175         real_to_int(tmp,&ti);
 176         verify_area(addr,2);
 177         if (ti.sign)
 178                 ti.a = -ti.a;
 179         put_fs_word(ti.a,(short *) addr);
 180 }
 181 
 182 void put_long_int(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 183         struct info * info, unsigned short code)
 184 {
 185         char * addr;
 186         temp_int ti;
 187 
 188         addr = ea(info,code);
 189         real_to_int(tmp,&ti);
 190         verify_area(addr,4);
 191         if (ti.sign)
 192                 ti.a = -ti.a;
 193         put_fs_long(ti.a,(unsigned long *) addr);
 194 }
 195 
 196 void put_longlong_int(const temp_real * tmp,
     /* [previous][next][first][last][top][bottom][index][help] */
 197         struct info * info, unsigned short code)
 198 {
 199         char * addr;
 200         temp_int ti;
 201 
 202         addr = ea(info,code);
 203         real_to_int(tmp,&ti);
 204         verify_area(addr,8);
 205         if (ti.sign)
 206                 __asm__("notl %0 ; notl %1\n\t"
 207                         "addl $1,%0 ; adcl $0,%1"
 208                         :"=r" (ti.a),"=r" (ti.b)
 209                         :"0" (ti.a),"1" (ti.b));
 210         put_fs_long(ti.a,(unsigned long *) addr);
 211         put_fs_long(ti.b,1 + (unsigned long *) addr);
 212 }
 213 
 214 #define DIV10(low,high,rem) \
 215 __asm__("divl %6 ; xchgl %1,%2 ; divl %6" \
 216         :"=d" (rem),"=a" (low),"=r" (high) \
 217         :"0" (0),"1" (high),"2" (low),"c" (10))
 218 
 219 void put_BCD(const temp_real * tmp,struct info * info, unsigned short code)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221         int k,rem;
 222         char * addr;
 223         temp_int i;
 224         unsigned char c;
 225 
 226         addr = ea(info,code);
 227         verify_area(addr,10);
 228         real_to_int(tmp,&i);
 229         if (i.sign)
 230                 put_fs_byte(0x80, addr+9);
 231         else
 232                 put_fs_byte(0, addr+9);
 233         for (k = 0; k < 9; k++) {
 234                 DIV10(i.a,i.b,rem);
 235                 c = rem;
 236                 DIV10(i.a,i.b,rem);
 237                 c += rem<<4;
 238                 put_fs_byte(c,addr++);
 239         }
 240 }

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