Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | There seems to be a problem with exp(double) and our emulator. I haven't |
| 2 | been able to track it down yet. This does not occur with the emulator |
| 3 | supplied by Russell King. |
| 4 | |
| 5 | I also found one oddity in the emulator. I don't think it is serious but |
| 6 | will point it out. The ARM calling conventions require floating point |
| 7 | registers f4-f7 to be preserved over a function call. The compiler quite |
| 8 | often uses an stfe instruction to save f4 on the stack upon entry to a |
| 9 | function, and an ldfe instruction to restore it before returning. |
| 10 | |
| 11 | I was looking at some code, that calculated a double result, stored it in f4 |
| 12 | then made a function call. Upon return from the function call the number in |
| 13 | f4 had been converted to an extended value in the emulator. |
| 14 | |
| 15 | This is a side effect of the stfe instruction. The double in f4 had to be |
| 16 | converted to extended, then stored. If an lfm/sfm combination had been used, |
| 17 | then no conversion would occur. This has performance considerations. The |
| 18 | result from the function call and f4 were used in a multiplication. If the |
| 19 | emulator sees a multiply of a double and extended, it promotes the double to |
| 20 | extended, then does the multiply in extended precision. |
| 21 | |
| 22 | This code will cause this problem: |
| 23 | |
| 24 | double x, y, z; |
| 25 | z = log(x)/log(y); |
| 26 | |
| 27 | The result of log(x) (a double) will be calculated, returned in f0, then |
| 28 | moved to f4 to preserve it over the log(y) call. The division will be done |
| 29 | in extended precision, due to the stfe instruction used to save f4 in log(y). |