This source file includes following definitions.
- get_short_real
- get_long_real
- get_temp_real
- get_short_int
- get_long_int
- get_longlong_int
- get_BCD
- put_short_real
- put_long_real
- put_temp_real
- put_short_int
- put_long_int
- put_longlong_int
- put_BCD
1
2
3
4
5
6
7
8
9
10
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,
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,
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,
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,
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,
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,
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)
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,
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,
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,
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,
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,
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,
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)
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 }