Blame view

kernel/linux-imx6_3.14.28/arch/x86/math-emu/README 21.1 KB
6b13f685e   김민수   BSP 최초 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
   +---------------------------------------------------------------------------+
   |  wm-FPU-emu   an FPU emulator for 80386 and 80486SX microprocessors.      |
   |                                                                           |
   | Copyright (C) 1992,1993,1994,1995,1996,1997,1999                          |
   |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   |                       Australia.  E-mail billm@melbpc.org.au              |
   |                                                                           |
   |    This program is free software; you can redistribute it and/or modify   |
   |    it under the terms of the GNU General Public License version 2 as      |
   |    published by the Free Software Foundation.                             |
   |                                                                           |
   |    This program is distributed in the hope that it will be useful,        |
   |    but WITHOUT ANY WARRANTY; without even the implied warranty of         |
   |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          |
   |    GNU General Public License for more details.                           |
   |                                                                           |
   |    You should have received a copy of the GNU General Public License      |
   |    along with this program; if not, write to the Free Software            |
   |    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              |
   |                                                                           |
   +---------------------------------------------------------------------------+
  
  
  
  wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387
  which was my 80387 emulator for early versions of djgpp (gcc under
  msdos); wm-emu387 was in turn based upon emu387 which was written by
  DJ Delorie for djgpp.  The interface to the Linux kernel is based upon
  the original Linux math emulator by Linus Torvalds.
  
  My target FPU for wm-FPU-emu is that described in the Intel486
  Programmer's Reference Manual (1992 edition). Unfortunately, numerous
  facets of the functioning of the FPU are not well covered in the
  Reference Manual. The information in the manual has been supplemented
  with measurements on real 80486's. Unfortunately, it is simply not
  possible to be sure that all of the peculiarities of the 80486 have
  been discovered, so there is always likely to be obscure differences
  in the detailed behaviour of the emulator and a real 80486.
  
  wm-FPU-emu does not implement all of the behaviour of the 80486 FPU,
  but is very close.  See "Limitations" later in this file for a list of
  some differences.
  
  Please report bugs, etc to me at:
         billm@melbpc.org.au
  or     b.metzenthen@medoto.unimelb.edu.au
  
  For more information on the emulator and on floating point topics, see
  my web pages, currently at  http://www.suburbia.net/~billm/
  
  
  --Bill Metzenthen
    December 1999
  
  
  ----------------------- Internals of wm-FPU-emu -----------------------
  
  Numeric algorithms:
  (1) Add, subtract, and multiply. Nothing remarkable in these.
  (2) Divide has been tuned to get reasonable performance. The algorithm
      is not the obvious one which most people seem to use, but is designed
      to take advantage of the characteristics of the 80386. I expect that
      it has been invented many times before I discovered it, but I have not
      seen it. It is based upon one of those ideas which one carries around
      for years without ever bothering to check it out.
  (3) The sqrt function has been tuned to get good performance. It is based
      upon Newton's classic method. Performance was improved by capitalizing
      upon the properties of Newton's method, and the code is once again
      structured taking account of the 80386 characteristics.
  (4) The trig, log, and exp functions are based in each case upon quasi-
      "optimal" polynomial approximations. My definition of "optimal" was
      based upon getting good accuracy with reasonable speed.
  (5) The argument reducing code for the trig function effectively uses
      a value of pi which is accurate to more than 128 bits. As a consequence,
      the reduced argument is accurate to more than 64 bits for arguments up
      to a few pi, and accurate to more than 64 bits for most arguments,
      even for arguments approaching 2^63. This is far superior to an
      80486, which uses a value of pi which is accurate to 66 bits.
  
  The code of the emulator is complicated slightly by the need to
  account for a limited form of re-entrancy. Normally, the emulator will
  emulate each FPU instruction to completion without interruption.
  However, it may happen that when the emulator is accessing the user
  memory space, swapping may be needed. In this case the emulator may be
  temporarily suspended while disk i/o takes place. During this time
  another process may use the emulator, thereby perhaps changing static
  variables. The code which accesses user memory is confined to five
  files:
      fpu_entry.c
      reg_ld_str.c
      load_store.c
      get_address.c
      errors.c
  As from version 1.12 of the emulator, no static variables are used
  (apart from those in the kernel's per-process tables). The emulator is
  therefore now fully re-entrant, rather than having just the restricted
  form of re-entrancy which is required by the Linux kernel.
  
  ----------------------- Limitations of wm-FPU-emu -----------------------
  
  There are a number of differences between the current wm-FPU-emu
  (version 2.01) and the 80486 FPU (apart from bugs).  The differences
  are fewer than those which applied to the 1.xx series of the emulator.
  Some of the more important differences are listed below:
  
  The Roundup flag does not have much meaning for the transcendental
  functions and its 80486 value with these functions is likely to differ
  from its emulator value.
  
  In a few rare cases the Underflow flag obtained with the emulator will
  be different from that obtained with an 80486. This occurs when the
  following conditions apply simultaneously:
  (a) the operands have a higher precision than the current setting of the
      precision control (PC) flags.
  (b) the underflow exception is masked.
  (c) the magnitude of the exact result (before rounding) is less than 2^-16382.
  (d) the magnitude of the final result (after rounding) is exactly 2^-16382.
  (e) the magnitude of the exact result would be exactly 2^-16382 if the
      operands were rounded to the current precision before the arithmetic
      operation was performed.
  If all of these apply, the emulator will set the Underflow flag but a real
  80486 will not.
  
  NOTE: Certain formats of Extended Real are UNSUPPORTED. They are
  unsupported by the 80486. They are the Pseudo-NaNs, Pseudoinfinities,
  and Unnormals. None of these will be generated by an 80486 or by the
  emulator. Do not use them. The emulator treats them differently in
  detail from the way an 80486 does.
  
  Self modifying code can cause the emulator to fail. An example of such
  code is:
            movl %esp,[%ebx]
  	  fld1
  The FPU instruction may be (usually will be) loaded into the pre-fetch
  queue of the CPU before the mov instruction is executed. If the
  destination of the 'movl' overlaps the FPU instruction then the bytes
  in the prefetch queue and memory will be inconsistent when the FPU
  instruction is executed. The emulator will be invoked but will not be
  able to find the instruction which caused the device-not-present
  exception. For this case, the emulator cannot emulate the behaviour of
  an 80486DX.
  
  Handling of the address size override prefix byte (0x67) has not been
  extensively tested yet. A major problem exists because using it in
  vm86 mode can cause a general protection fault. Address offsets
  greater than 0xffff appear to be illegal in vm86 mode but are quite
  acceptable (and work) in real mode. A small test program developed to
  check the addressing, and which runs successfully in real mode,
  crashes dosemu under Linux and also brings Windows down with a general
  protection fault message when run under the MS-DOS prompt of Windows
  3.1. (The program simply reads data from a valid address).
  
  The emulator supports 16-bit protected mode, with one difference from
  an 80486DX.  A 80486DX will allow some floating point instructions to
  write a few bytes below the lowest address of the stack.  The emulator
  will not allow this in 16-bit protected mode: no instructions are
  allowed to write outside the bounds set by the protection.
  
  ----------------------- Performance of wm-FPU-emu -----------------------
  
  Speed.
  -----
  
  The speed of floating point computation with the emulator will depend
  upon instruction mix. Relative performance is best for the instructions
  which require most computation. The simple instructions are adversely
  affected by the FPU instruction trap overhead.
  
  
  Timing: Some simple timing tests have been made on the emulator functions.
  The times include load/store instructions. All times are in microseconds
  measured on a 33MHz 386 with 64k cache. The Turbo C tests were under
  ms-dos, the next two columns are for emulators running with the djgpp
  ms-dos extender. The final column is for wm-FPU-emu in Linux 0.97,
  using libm4.0 (hard).
  
  function      Turbo C        djgpp 1.06        WM-emu387     wm-FPU-emu
  
     +          60.5           154.8              76.5          139.4
     -          61.1-65.5      157.3-160.8        76.2-79.5     142.9-144.7
     *          71.0           190.8              79.6          146.6
     /          61.2-75.0      261.4-266.9        75.3-91.6     142.2-158.1
  
   sin()        310.8          4692.0            319.0          398.5
   cos()        284.4          4855.2            308.0          388.7
   tan()        495.0          8807.1            394.9          504.7
   atan()       328.9          4866.4            601.1          419.5-491.9
  
   sqrt()       128.7          crashed           145.2          227.0
   log()        413.1-419.1    5103.4-5354.21    254.7-282.2    409.4-437.1
   exp()        479.1          6619.2            469.1          850.8
  
  
  The performance under Linux is improved by the use of look-ahead code.
  The following results show the improvement which is obtained under
  Linux due to the look-ahead code. Also given are the times for the
  original Linux emulator with the 4.1 'soft' lib.
  
   [ Linus' note: I changed look-ahead to be the default under linux, as
     there was no reason not to use it after I had edited it to be
     disabled during tracing ]
  
              wm-FPU-emu w     original w
              look-ahead       'soft' lib
     +         106.4             190.2
     -         108.6-111.6      192.4-216.2
     *         113.4             193.1
     /         108.8-124.4      700.1-706.2
  
   sin()       390.5            2642.0
   cos()       381.5            2767.4
   tan()       496.5            3153.3
   atan()      367.2-435.5     2439.4-3396.8
  
   sqrt()      195.1            4732.5
   log()       358.0-387.5     3359.2-3390.3
   exp()       619.3            4046.4
  
  
  These figures are now somewhat out-of-date. The emulator has become
  progressively slower for most functions as more of the 80486 features
  have been implemented.
  
  
  ----------------------- Accuracy of wm-FPU-emu -----------------------
  
  
  The accuracy of the emulator is in almost all cases equal to or better
  than that of an Intel 80486 FPU.
  
  The results of the basic arithmetic functions (+,-,*,/), and fsqrt
  match those of an 80486 FPU. They are the best possible; the error for
  these never exceeds 1/2 an lsb. The fprem and fprem1 instructions
  return exact results; they have no error.
  
  
  The following table compares the emulator accuracy for the sqrt(),
  trig and log functions against the Turbo C "emulator". For this table,
  each function was tested at about 400 points. Ideal worst-case results
  would be 64 bits. The reduced Turbo C accuracy of cos() and tan() for
  arguments greater than pi/4 can be thought of as being related to the
  precision of the argument x; e.g. an argument of pi/2-(1e-10) which is
  accurate to 64 bits can result in a relative accuracy in cos() of
  about 64 + log2(cos(x)) = 31 bits.
  
  
  Function      Tested x range            Worst result                Turbo C
                                          (relative bits)
  
  sqrt(x)       1 .. 2                    64.1                         63.2
  atan(x)       1e-10 .. 200              64.2                         62.8
  cos(x)        0 .. pi/2-(1e-10)         64.4 (x <= pi/4)             62.4
                                          64.1 (x = pi/2-(1e-10))      31.9
  sin(x)        1e-10 .. pi/2             64.0                         62.8
  tan(x)        1e-10 .. pi/2-(1e-10)     64.0 (x <= pi/4)             62.1
                                          64.1 (x = pi/2-(1e-10))      31.9
  exp(x)        0 .. 1                    63.1 **                      62.9
  log(x)        1+1e-6 .. 2               63.8 **                      62.1
  
  ** The accuracy for exp() and log() is low because the FPU (emulator)
  does not compute them directly; two operations are required.
  
  
  The emulator passes the "paranoia" tests (compiled with gcc 2.3.3 or
  later) for 'float' variables (24 bit precision numbers) when precision
  control is set to 24, 53 or 64 bits, and for 'double' variables (53
  bit precision numbers) when precision control is set to 53 bits (a
  properly performing FPU cannot pass the 'paranoia' tests for 'double'
  variables when precision control is set to 64 bits).
  
  The code for reducing the argument for the trig functions (fsin, fcos,
  fptan and fsincos) has been improved and now effectively uses a value
  for pi which is accurate to more than 128 bits precision. As a
  consequence, the accuracy of these functions for large arguments has
  been dramatically improved (and is now very much better than an 80486
  FPU). There is also now no degradation of accuracy for fcos and fptan
  for operands close to pi/2. Measured results are (note that the
  definition of accuracy has changed slightly from that used for the
  above table):
  
  Function      Tested x range          Worst result
                                       (absolute bits)
  
  cos(x)        0 .. 9.22e+18              62.0
  sin(x)        1e-16 .. 9.22e+18          62.1
  tan(x)        1e-16 .. 9.22e+18          61.8
  
  It is possible with some effort to find very large arguments which
  give much degraded precision. For example, the integer number
             8227740058411162616.0
  is within about 10e-7 of a multiple of pi. To find the tan (for
  example) of this number to 64 bits precision it would be necessary to
  have a value of pi which had about 150 bits precision. The FPU
  emulator computes the result to about 42.6 bits precision (the correct
  result is about -9.739715e-8). On the other hand, an 80486 FPU returns
  0.01059, which in relative terms is hopelessly inaccurate.
  
  For arguments close to critical angles (which occur at multiples of
  pi/2) the emulator is more accurate than an 80486 FPU. For very large
  arguments, the emulator is far more accurate.
  
  
  Prior to version 1.20 of the emulator, the accuracy of the results for
  the transcendental functions (in their principal range) was not as
  good as the results from an 80486 FPU. From version 1.20, the accuracy
  has been considerably improved and these functions now give measured
  worst-case results which are better than the worst-case results given
  by an 80486 FPU.
  
  The following table gives the measured results for the emulator. The
  number of randomly selected arguments in each case is about half a
  million.  The group of three columns gives the frequency of the given
  accuracy in number of times per million, thus the second of these
  columns shows that an accuracy of between 63.80 and 63.89 bits was
  found at a rate of 133 times per one million measurements for fsin.
  The results show that the fsin, fcos and fptan instructions return
  results which are in error (i.e. less accurate than the best possible
  result (which is 64 bits)) for about one per cent of all arguments
  between -pi/2 and +pi/2.  The other instructions have a lower
  frequency of results which are in error.  The last two columns give
  the worst accuracy which was found (in bits) and the approximate value
  of the argument which produced it.
  
                                  frequency (per M)
                                 -------------------   ---------------
  instr   arg range    # tests   63.7   63.8    63.9   worst   at arg
                                 bits   bits    bits    bits
  -----  ------------  -------   ----   ----   -----   -----  --------
  fsin     (0,pi/2)     547756      0    133   10673   63.89  0.451317
  fcos     (0,pi/2)     547563      0    126   10532   63.85  0.700801
  fptan    (0,pi/2)     536274     11    267   10059   63.74  0.784876
  fpatan  4 quadrants   517087      0      8    1855   63.88  0.435121 (4q)
  fyl2x     (0,20)      541861      0      0    1323   63.94  1.40923  (x)
  fyl2xp1 (-.293,.414)  520256      0      0    5678   63.93  0.408542 (x)
  f2xm1     (-1,1)      538847      4    481    6488   63.79  0.167709
  
  
  Tests performed on an 80486 FPU showed results of lower accuracy. The
  following table gives the results which were obtained with an AMD
  486DX2/66 (other tests indicate that an Intel 486DX produces
  identical results).  The tests were basically the same as those used
  to measure the emulator (the values, being random, were in general not
  the same).  The total number of tests for each instruction are given
  at the end of the table, in case each about 100k tests were performed.
  Another line of figures at the end of the table shows that most of the
  instructions return results which are in error for more than 10
  percent of the arguments tested.
  
  The numbers in the body of the table give the approx number of times a
  result of the given accuracy in bits (given in the left-most column)
  was obtained per one million arguments. For three of the instructions,
  two columns of results are given: * The second column for f2xm1 gives
  the number cases where the results of the first column were for a
  positive argument, this shows that this instruction gives better
  results for positive arguments than it does for negative.  * In the
  cases of fcos and fptan, the first column gives the results when all
  cases where arguments greater than 1.5 were removed from the results
  given in the second column. Unlike the emulator, an 80486 FPU returns
  results of relatively poor accuracy for these instructions when the
  argument approaches pi/2. The table does not show those cases when the
  accuracy of the results were less than 62 bits, which occurs quite
  often for fsin and fptan when the argument approaches pi/2. This poor
  accuracy is discussed above in relation to the Turbo C "emulator", and
  the accuracy of the value of pi.
  
  
  bits   f2xm1  f2xm1 fpatan   fcos   fcos  fyl2x fyl2xp1  fsin  fptan  fptan
  62.0       0      0      0      0    437      0      0      0      0    925
  62.1       0      0     10      0    894      0      0      0      0   1023
  62.2      14      0      0      0   1033      0      0      0      0    945
  62.3      57      0      0      0   1202      0      0      0      0   1023
  62.4     385      0      0     10   1292      0     23      0      0   1178
  62.5    1140      0      0    119   1649      0     39      0      0   1149
  62.6    2037      0      0    189   1620      0     16      0      0   1169
  62.7    5086     14      0    646   2315     10    101     35     39   1402
  62.8    8818     86      0    984   3050     59    287    131    224   2036
  62.9   11340   1355      0   2126   4153     79    605    357    321   1948
  63.0   15557   4750      0   3319   5376    246   1281    862    808   2688
  63.1   20016   8288      0   4620   6628    511   2569   1723   1510   3302
  63.2   24945  11127     10   6588   8098   1120   4470   2968   2990   4724
  63.3   25686  12382     69   8774  10682   1906   6775   4482   5474   7236
  63.4   29219  14722     79  11109  12311   3094   9414   7259   8912  10587
  63.5   30458  14936    393  13802  15014   5874  12666   9609  13762  15262
  63.6   32439  16448   1277  17945  19028  10226  15537  14657  19158  20346
  63.7   35031  16805   4067  23003  23947  18910  20116  21333  25001  26209
  63.8   33251  15820   7673  24781  25675  24617  25354  24440  29433  30329
  63.9   33293  16833  18529  28318  29233  31267  31470  27748  29676  30601
  
  Per cent with error:
          30.9           3.2          18.5    9.8   13.1   11.6          17.4
  Total arguments tested:
         70194  70099 101784 100641 100641 101799 128853 114893 102675 102675
  
  
  ------------------------- Contributors -------------------------------
  
  A number of people have contributed to the development of the
  emulator, often by just reporting bugs, sometimes with suggested
  fixes, and a few kind people have provided me with access in one way
  or another to an 80486 machine. Contributors include (to those people
  who I may have forgotten, please forgive me):
  
  Linus Torvalds
  Tommy.Thorn@daimi.aau.dk
  Andrew.Tridgell@anu.edu.au
  Nick Holloway, alfie@dcs.warwick.ac.uk
  Hermano Moura, moura@dcs.gla.ac.uk
  Jon Jagger, J.Jagger@scp.ac.uk
  Lennart Benschop
  Brian Gallew, geek+@CMU.EDU
  Thomas Staniszewski, ts3v+@andrew.cmu.edu
  Martin Howell, mph@plasma.apana.org.au
  M Saggaf, alsaggaf@athena.mit.edu
  Peter Barker, PETER@socpsy.sci.fau.edu
  tom@vlsivie.tuwien.ac.at
  Dan Russel, russed@rpi.edu
  Daniel Carosone, danielce@ee.mu.oz.au
  cae@jpmorgan.com
  Hamish Coleman, t933093@minyos.xx.rmit.oz.au
  Bruce Evans, bde@kralizec.zeta.org.au
  Timo Korvola, Timo.Korvola@hut.fi
  Rick Lyons, rick@razorback.brisnet.org.au
  Rick, jrs@world.std.com
   
  ...and numerous others who responded to my request for help with
  a real 80486.