Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1863 yogev_ezra 1
;FpuAtoFL    PROTO :DWORD,:DWORD,:DWORD
2
;FpuFLtoA    PROTO :DWORD,:DWORD,:DWORD,:DWORD
3
 
4
;FpuAdd      PROTO :DWORD,:DWORD,:DWORD,:DWORD
5
;FpuSub      PROTO :DWORD,:DWORD,:DWORD,:DWORD
6
;FpuMul      PROTO :DWORD,:DWORD,:DWORD,:DWORD
7
;FpuDiv      PROTO :DWORD,:DWORD,:DWORD,:DWORD
8
;FpuSqrt     PROTO :DWORD,:DWORD,:DWORD
9
;FpuXexpY    PROTO :DWORD,:DWORD,:DWORD,:DWORD
10
;FpuAbs      PROTO :DWORD,:DWORD,:DWORD
11
;FpuTrunc    PROTO :DWORD,:DWORD,:DWORD
12
;FpuRound    PROTO :DWORD,:DWORD,:DWORD
13
;FpuChs      PROTO :DWORD,:DWORD,:DWORD
14
 
15
;FpuLnx      PROTO :DWORD,:DWORD,:DWORD
16
;FpuLogx     PROTO :DWORD,:DWORD,:DWORD
17
;FpuEexpX    PROTO :DWORD,:DWORD,:DWORD
18
;FpuTexpX    PROTO :DWORD,:DWORD,:DWORD
19
 
20
;FpuSin      PROTO :DWORD,:DWORD,:DWORD
21
;FpuCos      PROTO :DWORD,:DWORD,:DWORD
22
;FpuTan      PROTO :DWORD,:DWORD,:DWORD
23
;FpuArcsin   PROTO :DWORD,:DWORD,:DWORD
24
;FpuArccos   PROTO :DWORD,:DWORD,:DWORD
25
;FpuArctan   PROTO :DWORD,:DWORD,:DWORD
26
 
27
;FpuSinh     PROTO :DWORD,:DWORD,:DWORD
28
;FpuCosh     PROTO :DWORD,:DWORD,:DWORD
29
;FpuTanh     PROTO :DWORD,:DWORD,:DWORD
30
;FpuArcsinh  PROTO :DWORD,:DWORD,:DWORD
31
;FpuArccosh  PROTO :DWORD,:DWORD,:DWORD
32
;FpuArctanh  PROTO :DWORD,:DWORD,:DWORD
33
 
34
;FpuSize     PROTO :DWORD,:DWORD,:DWORD
35
;FpuComp     PROTO :DWORD,:DWORD,:DWORD
36
;FpuExam     PROTO :DWORD,:DWORD
37
;FpuState    PROTO :DWORD
38
 
39
SRC1_FPU    EQU   1
40
SRC1_REAL   EQU   2
41
SRC1_DMEM   EQU   4
42
SRC1_DIMM   EQU   8
43
SRC1_CONST  EQU   16
44
 
45
ANG_DEG     EQU   0
46
ANG_RAD     EQU   32
47
 
48
DEST_MEM    EQU   0
49
DEST_IMEM   EQU   64
50
DEST_FPU    EQU   128
51
 
52
SRC2_FPU    EQU   256
53
SRC2_REAL   EQU   512
54
SRC2_DMEM   EQU   1024
55
SRC2_DIMM   EQU   2048
56
SRC2_CONST  EQU   4096
57
 
58
STR_REG     EQU   0
59
STR_SCI     EQU   32768
60
 
61
FPU_PI      EQU   1
62
FPU_NAPIER  EQU   2
63
 
64
XAM_VALID   EQU   1
65
XAM_ZERO    EQU   2
66
XAM_NEG     EQU   4
67
XAM_SMALL   EQU   8
68
XAM_INFINIT EQU   16
69
 
70
CMP_EQU     EQU   1
71
CMP_GREATER EQU   2
72
CMP_LOWER   EQU   4
73
 
74
 
75
 
76
 
77
; #########################################################################
78
;
79
;                             FpuFLtoA
80
;
81
;##########################################################################
82
 
83
  ; -----------------------------------------------------------------------
84
  ; This procedure was written by Raymond Filiatreault, December 2002
85
  ; and modified April 2003. A minor flaw was corrected in July 2003.
86
  ; Modified March 2004 to avoid any potential data loss from the FPU
87
  ;
88
  ; This FpuFLtoA function converts an 80-bit REAL number (Src) to its
89
  ; decimal representation as a zero terminated alphanumeric string which
90
  ; is returned at the specified memory destination unless an invalid
91
  ; operation is reported by the FPU or the definition of the parameters
92
  ; (with uID) is invalid.
93
  ;
94
  ; The format of the string can be specified as regular (default) or
95
  ; scientific notation. The number of decimal places returned must also be
96
  ; specified but the total number of significant digits must not exceed 16.
97
  ; When the regular format is specified, the integer portion can also be
98
  ; padded with preceding spaces to position the decimal point at a
99
  ; specified location from the start of the string.
100
  ;
101
  ; The source can be an 80-bit REAL number from the FPU itself or from
102
  ; memory.
103
  ;
104
  ; The source is not checked for validity. This is the programmer's
105
  ; responsibility.
106
  ;
107
  ; This procedure is based on using an FPU instruction to convert the
108
  ; REAL number into a specific packed decimal format. After unpacking,
109
  ; the decimal point is positioned as required.
110
  ;
111
  ; Only EAX is used to return error or success. All other CPU registers
112
  ; are preserved. All FPU registers are preserved.
113
  ;
114
  ; -----------------------------------------------------------------------
115
 
116
 
117
; #########################################################################
118
align 4
119
proc  FpuFLtoA stdcall, lpSrc:DWORD, lpDecimal:DWORD, lpDest:DWORD, uID:DWORD
120
 
121
locals
122
 tempdw dd ?
123
 esize dd ?
124
 Padding dd ?
125
 Decimal dd ?
126
 content: times 108 db ?
127
 tempst dt ?
128
 bcdstr dt ?
129
 oldcw dw ?
130
 truncw dw ?
131
 unpacked: times 20 db ?
132
endl
133
 
134
;get the specified number of decimals for result
135
;and make corrections if necessary
136
 
137
      mov   eax,[lpDecimal]
138
      test  [uID],SRC2_DMEM
139
      jz    @F
140
      mov   eax,[eax]	      ;get the decimals from memory
141
   @@:
142
      push  eax
143
      movzx eax,al	      ;low byte - number of decimal digits
144
      cmp   eax,15
145
      jbe   @F
146
      mov   eax,15	      ;a maximum of 15 decimals is allowed
147
   @@:
148
      mov   [Decimal],eax
149
      pop   eax
150
      movzx eax,ah	      ;2nd byte - number of char before decimal point
151
      cmp   eax,17
152
      jbe   @F
153
      mov   eax,17	      ;a maximum of 17 characters is allowed
154
   @@:
155
      mov   [Padding],eax
156
 
157
      test  [uID],SRC1_FPU	;is data taken from FPU?
158
      jz    @F		      ;continue if not
159
 
160
;-------------------------------
161
;check if top register is empty
162
;-------------------------------
163
 
164
      fxam		      ;examine its content
165
      fstsw ax		      ;store results in AX
166
      fwait		      ;for precaution
167
      sahf		      ;transfer result bits to CPU flag
168
      jnc   @F		      ;not empty if Carry flag not set
169
      jpe   @F		      ;not empty if Parity flag set
170
      jz    srcerr1	      ;empty if Zero flag set
171
 
172
   @@:
173
      fsave [content]
174
 
175
;----------------------------------------
176
;check source for Src and load it to FPU
177
;----------------------------------------
178
 
179
      test  [uID],SRC1_FPU
180
      jz    @F
181
      lea   eax,[content]
182
      fld   tbyte [eax+28]
183
      jmp   dest0
184
 
185
   @@:
186
      test  [uID],SRC1_REAL	;is Src an 80-bit REAL in memory?
187
      jz    srcerr	      ;no proper source identificaiton
188
      mov   eax,[lpSrc]
189
      fld   tbyte [eax]
190
      jmp   dest0	      ;go complete process
191
 
192
srcerr:
193
      frstor [content]
194
srcerr1:
195
      push  edi
196
      mov   edi,[lpDest]
197
      mov   eax,"ERRO";ORRE"
198
      stosd
199
      mov   ax,"R"
200
      stosw
201
      pop   edi
202
      xor   eax,eax
203
      ret
204
 
205
dest0:
206
 
207
;-------------------------------------------
208
;first examine the value on FPU for validity
209
;-------------------------------------------
210
 
211
      fxam		      ;examine value on FPU
212
      fstsw ax		      ;get result
213
      fwait
214
      sahf		      ;transfer to CPU flags
215
      jz    maybezero
216
      jpo   srcerr	      ;C3=0 and C2=0 would be NAN or unsupported
217
      jnc   getnumsize	      ;continue if normal finite number
218
 
219
;--------------------------------
220
;value to be converted = INFINITY
221
;--------------------------------
222
 
223
      push  ecx
224
      push  esi
225
      push  edi
226
      mov   edi,[lpDest]
227
      mov   al,"+"
228
      test  ah,2	      ;C1 field = sign
229
      jz    @F
230
      mov   al,"-"
231
   @@:
232
      stosb
233
      mov   eax,"INFI";IFNI"
234
      stosd
235
      mov   eax,"NITY";YTIN"
236
      stosd
237
      jmp   finish
238
 
239
;-------------------------
240
;value to be converted = 0
241
;-------------------------
242
 
243
maybezero:
244
      jpe   getnumsize	      ;would be denormalized number
245
      fstp  st0 	    ;flush that 0 value off the FPU
246
      push  ecx
247
      push  esi
248
      push  edi
249
      mov   edi,[lpDest]
250
      test  [uID],STR_SCI	;scientific notation?
251
      jnz   @F		      ;no padding
252
      mov   ecx,[Padding]
253
      sub   ecx,2
254
      jle   @F		      ;no padding specified or necessary
255
      mov   al," "
256
      rep   stosb
257
   @@:
258
      mov   ax,3020h	      ;" 0" szstring
259
      stosw		      ;write it
260
      jmp   finish
261
 
262
;---------------------------
263
; get the size of the number
264
;---------------------------
265
 
266
getnumsize:
267
      fldlg2		      ;log10(2)
268
      fld   st1 	    ;copy Src
269
      fabs		      ;insures a positive value
270
      fyl2x		      ;->[log2(Src)]*[log10(2)] = log10(Src)
271
 
272
      fstcw [oldcw]		;get current control word
273
      fwait
274
      mov   ax,[oldcw]
275
      or    ax,0c00h	      ;code it for truncating
276
      mov   [truncw],ax
277
      fldcw [truncw]		;insure rounding code of FPU to truncating
278
 
279
      fist  [esize]		;store characteristic of logarithm
280
      fldcw [oldcw]		;load back the former control word
281
 
282
      ftst		      ;test logarithm for its sign
283
      fstsw ax		      ;get result
284
      fwait
285
      sahf		      ;transfer to CPU flags
286
      sbb   [esize],0		;decrement esize if log is negative
287
      fstp  st0 	    ;get rid of the logarithm
288
 
289
;-----------------------------------------------------------------------
290
; get the power of 10 required to generate an integer with the specified
291
; number of significant digits
292
;-----------------------------------------------------------------------
293
 
294
      mov   eax,[uID]
295
      and   eax,STR_SCI
296
	jnz .els0	 ;regular decimal notation
297
	    mov   eax,[esize]
298
	    or	  eax,eax     ;check if number is < 1
299
	    js	  @F
300
;            .if   eax > 15    ;if number is >= 10^16
301
		cmp eax,15
302
		jbe .endif0
303
		  or	[uID],STR_SCI ;switch to scientific notation
304
		  mov	[Decimal],15  ;insures 15 decimal places in result
305
		  jmp	scific
306
	    .endif0:
307
	    add   eax,[Decimal]
308
;            .if   eax > 15    ;if integer + decimal digits > 16
309
		cmp eax,15
310
		jbe .endif1
311
		  sub	eax,15
312
		  sub	[Decimal],eax ;reduce decimal digits as required
313
	    .endif1:
314
	 @@:
315
	    push  [Decimal]
316
	    pop   [tempdw]
317
		jmp @f
318
      .els0:		       ;scientific notation
319
      scific:
320
	    mov   eax,[Decimal]
321
	    sub   eax,[esize]
322
	    mov   [tempdw],eax
323
;      .endif
324
	@@:
325
 
326
;----------------------------------------------------------------------------------------
327
; multiply the number by the power of 10 to generate required integer and store it as BCD
328
;----------------------------------------------------------------------------------------
329
 
330
;.if   tempdw != 0
331
	cmp [tempdw],0
332
	je @f
333
      fild  [tempdw]
334
      fldl2t
335
      fmulp st1,st0		     ;->log2(10)*exponent
336
      fld   st0
337
      frndint		      ;get the characteristic of the log
338
      fxch
339
      fsub st,st1	    ;get only the fractional part but keep the characteristic
340
      f2xm1		      ;->2^(fractional part)-1
341
      fld1
342
      faddp st1,st0		     ;add 1 back
343
      fscale		      ;re-adjust the exponent part of the REAL number
344
      fstp  st1 	    ;get rid of the characteristic of the log
345
      fmulp st1,st0		     ;->16-digit integer
346
;.endif
347
	@@:
348
 
349
      fbstp [bcdstr]		;->TBYTE containing the packed digits
350
      fstsw ax		      ;retrieve exception flags from FPU
351
      fwait
352
      shr   eax,1	      ;test for invalid operation
353
      jc    srcerr	      ;clean-up and return error
354
 
355
;------------------------------------------------------------------------------
356
; unpack BCD, the 10 bytes returned by the FPU being in the little-endian style
357
;------------------------------------------------------------------------------
358
 
359
      push  ecx
360
      push  esi
361
      push  edi
362
      lea   esi,[bcdstr+9]      ;go to the most significant byte (sign byte)
363
      lea   edi,[unpacked]
364
      mov   eax,3020h
365
      mov   cl,byte [esi]  ;sign byte
366
;      .if   cl == 80h
367
	cmp cl,0x80
368
	jne @f
369
	    mov   al,"-"      ;insert sign if negative number
370
;      .endif
371
	@@:
372
      stosw
373
      mov   ecx,9
374
   @@:
375
      dec   esi
376
      movzx eax,byte [esi]
377
      ror   ax,4
378
      ror   ah,4
379
      add   ax,3030h
380
      stosw
381
      dec   ecx
382
      jnz   @B
383
 
384
      mov   edi,[lpDest]
385
      lea   esi,[unpacked]
386
      test  [uID],STR_SCI	;scientific notation?
387
      jnz   scientific
388
 
389
;************************
390
; REGULAR STRING NOTATION
391
;************************
392
 
393
;------------------------------
394
; check if padding is specified
395
;------------------------------
396
 
397
      mov   ecx,[Padding]
398
      or    ecx,ecx	      ;check if padding is specified
399
      jz    nopadding
400
 
401
      mov   edx,2	      ;at least 1 integer + sign
402
      mov   eax,[esize]
403
      or    eax,eax
404
      js    @F		      ;only 1 integer digit if size is < 1
405
      add   edx,eax	      ;->number of integer digits
406
   @@:
407
      sub   ecx,edx
408
      jle   nopadding
409
      mov   al," "
410
      rep   stosb
411
 
412
nopadding:
413
      pushfd		      ;save padding flags
414
      movsb		      ;insert sign
415
      mov   ecx,1	      ;at least 1 integer digit
416
      mov   eax,[esize]
417
      or    eax,eax	      ;is size negative (i.e. number smaller than 1)
418
      js    @F
419
      add   ecx,eax
420
   @@:
421
      mov   eax,[Decimal]
422
      add   eax,ecx	      ;->total number of digits to be displayed
423
      sub   eax,19
424
      sub   esi,eax	      ;address of 1st digit to be displayed
425
      pop   eax 	      ;retrieve padding flags in EAX
426
;      .if   byte ptr[esi-1] == "1"
427
	cmp byte [esi-1],"1"
428
	jne @f
429
	    dec   esi
430
	    inc   ecx
431
	    push  eax	      ;transfer padding flags through stack
432
	    popfd	      ;retrieve padding flags
433
	    jle   @F	      ;no padding was necessary
434
	    dec   edi	      ;adjust for one less padding byte
435
;      .endif
436
	@@:
437
   @@:
438
      rep   movsb	      ;copy required integer digits
439
      mov   ecx,[Decimal]
440
      or    ecx,ecx
441
      jz    @F
442
      mov   al,"."
443
      stosb
444
      rep   movsb	      ;copy required decimal digits
445
   @@:
446
      jmp   finish
447
 
448
;********************
449
; SCIENTIFIC NOTATION
450
;********************
451
 
452
scientific:
453
      movsb		      ;insert sign
454
      mov   ecx,[Decimal]
455
      mov   eax,18
456
      sub   eax,ecx
457
      add   esi,eax
458
      cmp   byte [esi-1],"1"
459
      pushfd		      ;save flags for extra "1"
460
      jnz   @F
461
      dec   esi
462
   @@:
463
      movsb		      ;copy the integer
464
      mov   al,"."
465
      stosb
466
      rep   movsb	      ;copy the decimal digits
467
 
468
      mov   al,"E"
469
      stosb
470
      mov   al,"+"
471
      mov   ecx,[esize]
472
      popfd		      ;retrieve flags for extra "1"
473
      jnz   @F		      ;no extra "1"
474
      inc   ecx 	      ;adjust exponent
475
   @@:
476
      or    ecx,ecx
477
      jns   @F
478
      mov   al,"-"
479
      neg   ecx 	      ;make number positive
480
   @@:
481
      stosb		      ;insert proper sign
482
 
483
;Note: the absolute value of the size could not exceed 4931
484
 
485
      mov   eax,ecx
486
      mov   cl,100
487
      div   cl		      ;->thousands & hundreds in AL, tens & units in AH
488
      push  eax
489
      and   eax,0ffh	      ;keep only the thousands & hundreds
490
      mov   cl,10
491
      div   cl		      ;->thousands in AL, hundreds in AH
492
      add   ax,3030h	      ;convert to characters
493
      stosw		      ;insert them
494
      pop   eax
495
      shr   eax,8	      ;get the tens & units in AL
496
      div   cl		      ;tens in AL, units in AH
497
      add   ax,3030h	      ;convert to characters
498
      stosw		      ;insert them
499
 
500
finish:
501
      xor   eax,eax
502
      stosb		      ;string terminating 0
503
      pop   edi
504
      pop   esi
505
      pop   ecx
506
 
507
      frstor [content]
508
 
509
      or    al,1	      ;to insure EAX!=0
510
      ret
511
 
512
endp
513
 
514
; #########################################################################
515
 
516
 
517
 align 4
518
 
519
; #########################################################################
520
;                             FpuCos
521
;##########################################################################
522
  ;
523
  ;                           cos(Src) -> Dest
524
FpuCos:
525
	test [flags],(1 shl 30)
526
	jz @f			;jump if angle already in radians
527
	fldpi			;load pi (3.14159...) on FPU
528
	fmulp
529
	test [flags],(1 shl 31)
530
	jnz .1
531
	pushd 200
532
	jmp .2
533
.1:	pushd 180
534
.2:	fidiv dword [esp]	;value now in radians
535
	fwait
536
	add esp,4		;clean the stack
537
@@:	fldpi
538
	fadd  st,st		;->2pi
539
	fxch
540
 
541
@@:	fprem			;reduce the angle
542
	fcos
543
	fstsw ax		;retrieve exception flags from FPU
544
	fwait
545
	shr al,1		;test for invalid operation
546
	sahf			;transfer to the CPU flags
547
	jpe	@B		;reduce angle again if necessary
548
	fstp st1		;get rid of the 2pi
549
ret
550
 
551
 align 4
552
; #########################################################################
553
;                             FpuSin
554
;##########################################################################
555
  ;
556
  ;                       sin(Src) -> Dest
557
FpuSin:
558
	test [flags],(1 shl 30)
559
	jz @f			;jump if angle already in radians
560
	fldpi			;load pi (3.14159...) on FPU
561
	fmulp
562
	test [flags],(1 shl 31)
563
	jnz .1
564
	pushd 200
565
	jmp .2
566
.1:	pushd 180
567
.2:	fidiv dword [esp]	;value now in radians
568
	fwait
569
	add esp,4		;clean the stack
570
   @@:
571
	fldpi
572
	fadd  st,st		;->2pi
573
	fxch
574
 
575
	fprem                   ;reduce the angle
576
	fsin
577
	fstp  st1             ;get rid of the 2pi
578
ret
579
 
580
 align 4
581
; #########################################################################
582
;                             FpuArctan
583
;##########################################################################
584
  ;
585
  ;                       atan(Src) -> Dest
586
FpuArctan:
587
	fld1
588
	fpatan
589
	test [flags],(1 shl 30)
590
	jz @F			;jump if angle is required in radians
591
	test [flags],(1 shl 31)
592
	jnz .1
593
	pushd 200
594
	jmp .2
595
.1:	pushd 180
596
.2:	fimul dword [esp]	;*180 degrees
597
	fldpi			;load pi (3.14159...) on FPU
598
	fdivp			;*180/pi, angle now in degrees
599
	add esp,4		;clean CPU stack
600
 
601
	ftst			;check for negative angle
602
	fstsw ax		;retrieve status word from FPU
603
	fwait
604
	sahf
605
	jnc  @F			;jump if positive number
606
	test [flags],(1 shl 31)
607
	jnz .3
608
	pushd 400
609
	jmp .4
610
.3:	pushd 360
611
.4:	fiadd dword [esp]	;angle now 0-360
612
	fwait
613
	add esp,4			;clean CPU stack
614
 
615
@@:
616
	ret
617
 
618
 align 4
619
; #########################################################################
620
;                             FpuTan
621
;##########################################################################
622
 
623
  ;                           a = tan(x)
624
FpuTan:
625
	fldpi			;load pi (3.14159...) on FPU
626
	fadd  st,st		;->2pi
627
	fxch
628
	test [flags],(1 shl 30)
629
	jz @F			;jump if angle already in radians
630
	test [flags],(1 shl 31)
631
	jnz .1
632
	pushd 400
633
	jmp .2
634
.1:	pushd 360
635
.2:	fmul st,st1
636
	fidiv dword [esp]	;value now in radians
637
	pop eax			;clean the stack
638
@@:	fprem			;reduce the angle
639
	fptan
640
 
641
	fstp st			;get rid of the 1
642
	fstp st1		;get rid of the 2pi
643
ret
644
 
645
 align 4
646
; #########################################################################
647
;                             FpuArccos
648
;##########################################################################
649
  ;                                sqrt(1-Src^2)
650
  ;               acos(Src) = atan -------------  -> Dest
651
  ;                                     Src
652
 
653
FpuArccos:
654
	fld st			;copy cosine value
655
	fmul st0,st1			;cos^2
656
	fld1
657
	fsubrp			;1-cos^2 = sin^2
658
	fsqrt			;->sin
659
	fxch
660
	fpatan			;i.e. arctan(sin/cos)
661
 
662
	test [flags],(1 shl 30)
663
	jz @F			;jump if angle is required in radians
664
	test [flags],(1 shl 31)
665
	jnz .1
666
	pushd 200
667
	jmp .2
668
.1:	pushd 180
669
.2:	fimul dword [esp]	;*180 degrees
670
	fldpi			;load pi (3.14159...) on FPU
671
	fdivp			;*180/pi, angle now in degrees
672
	pop eax			;clean CPU stack
673
@@:
674
ret
675
 
676
 align 4
677
; #########################################################################
678
;                             FpuArcsin
679
;##########################################################################
680
  ;                                  Src
681
  ;            asin(Src) = atan -------------  -> Dest
682
  ;                             sqrt(1-Src^2)
683
FpuArcsin:
684
	fld st0			;copy sine value
685
	fmul st0,st0			;sin^2
686
	fld1
687
	fsubrp			;1-sin^2 = cos^2
688
	fsqrt			;->cos
689
	fpatan			;i.e. arctan(sin/cos) = arcsin
690
	test [flags],(1 shl 30)
691
	jz @F			;jump if angle is required in radians
692
	test [flags],(1 shl 31)
693
	jnz .1
694
	pushd 200
695
	jmp .2
696
.1:	pushd 180
697
.2:	fimul dword [esp]	;*180 degrees
698
	fldpi			;load pi (3.14159...) on FPU
699
	fdivrp			;*180/pi, angle now in degrees
700
	add esp,4		;clean CPU stack
701
@@:
702
	ret
703
 
704
 align 4
705
; #########################################################################
706
;                             FpuEexpX
707
;##########################################################################
708
 
709
  ;              e^(Src) = antilog2[ log2(e) * Src ] -> Dest
710
 
711
FpuEexpX:
712
 
713
      fldl2e                  ;->log2(e)
714
      fmulp                    ;->log2(e)*Src
715
 
716
      fld   st0             ;copy the logarithm
717
      frndint                 ;keep only the characteristic
718
      fsub  st1,st          ;keeps only the mantissa
719
      fxch                    ;get the mantissa on top
720
 
721
      f2xm1                   ;->2^(mantissa)-1
722
      fld1
723
      faddp                    ;add 1 back
724
 
725
      fscale                  ;scale it with the characteristic
726
 
727
      fstp  st1             ;get rid of the characteristic
728
ret
729
 
730
 align 4
731
; #########################################################################
732
;                             FpuXexpY
733
;##########################################################################
734
 
735
  ;            Src1^Src2 = antilog2[ log2(Src1) * Src2 ] -> Dest
736
 
737
FpuXexpY:
738
      fxch                    ;set up FPU registers for next operation
739
      fyl2x                   ;->log2(Src1)*exponent
740
 
741
      fld   st0             ;copy the logarithm
742
      frndint                 ;keep only the characteristic
743
      fsub  st1,st          ;keeps only the mantissa
744
      fxch                    ;get the mantissa on top
745
 
746
      f2xm1                   ;->2^(mantissa)-1
747
      fld1
748
      faddp                    ;add 1 back
749
 
750
      fscale                  ;scale it with the characteristic
751
 
752
      fstp  st1             ;overwrite the characteristic
753
ret
754
 
755
 
756
if 0
757
exp:
758
.N equ 10
759
	xor eax,eax
760
	mov ecx,.N
761
	fld1
762
.0:	dec ecx
763
	jz .end
764
	mov eax,.N
765
	sub eax,ecx
766
	mov [.d],eax
767
	fild [.d]
768
@@:	dec eax
769
	jz @f
770
	mov [.d],eax
771
	fild [.d]
772
	fmulp
773
	jmp @b
774
@@:	mov eax,.N
775
	sub eax,ecx
776
	fld st2
777
@@:	dec eax
778
	jz @f
779
	fld st3
780
	fmulp
781
	jmp @b
782
@@:	fdivrp
783
	faddp
784
	jmp .0
785
.end:	fxch
786
	fstp st0
787
ret
788
.d dd 0
789
endf