News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

FPULIB update

Started by raymond, January 07, 2010, 04:43:28 AM

Previous topic - Next topic

raymond

With the increasing popularity of 64-bit computers, I thought that allowing the use of 64-bit integers as source/destination should be part of the Fpulib functions whenever integers can be used. While at it, I also added code to allow the use of 32-bit and 64-bit floats (REAL4 and REAL8). Furthermore, I included my procedures for converting dwords and qwords to ascii using "magic numbers".

With all the modifications, I needed something to test the library as much as posible before posting it. I thus designed a "tester". It did allow me to find some errors, some potential bugs, and one inadequate function (FpuArcsinh with a negative input). I included this tester into the new package on my site, i.e. FPULIB2_3.ZIP.
http://www.ray.masmcode.com/fpu.html#fpulib

For those who may only want to see the "tester", I'm attaching it here. The .zip file contains a text file giving a short explanation of how it works.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ecube

Thanks i'll grab it,I hope you added a MOD function :D

raymond

QuoteI hope you added a MOD function

I don't remember having seen such a request before. I'll give it some consideration.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ecube

MOD is a essential basic to mathematics, so is pretty vital, I wrote one below, which is just your FpuDiv slightly modified using dave's advice I believe.


FpuMod proc public lpSrc1:DWORD, lpSrc2:DWORD, lpDest:DWORD, uID:DWORD
       
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;
; Because a library is assembled before its functions are called, all
; references to external memory data must be qualified for the expected
; size of that data so that the proper code is generated.
;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

LOCAL content[108] :BYTE
LOCAL tempst       :TBYTE

      test  uID,SRC1_FPU or SRC2_FPU      ;is data taken from FPU?
      jz    continue

;-------------------------------
;check if top register is empty
;-------------------------------

      fxam                    ;examine its content
      fstsw ax                ;store results in AX
      fwait                   ;for precaution
      sahf                    ;transfer result bits to CPU flag
      jnc   continue          ;not empty if Carry flag not set
      jpe   continue          ;not empty if Parity flag set
      jz    srcerr1           ;empty if Zero flag set

continue:
      fsave content

      test  uID,SRC1_FPU
      jz    @F
      lea   eax,content
      fld   tbyte ptr[eax+28]
      jmp   src2

   @@:
      mov   eax,lpSrc1
      test  uID,SRC1_FPU      ;is Src1 taken from FPU?
      jnz   src2              ;check next parameter for Src2

      test  uID,SRC1_REAL     ;is Src1 an 80-bit REAL in memory?
      jz    @F                ;check next source for Src1
      fld   tbyte ptr [eax]
      jmp   src2              ;check next parameter for Src2

   @@:
      test  uID,SRC1_DMEM     ;is Src1 a 32-bit integer in memory?
      jz    @F                ;check next source for Src1
      fild  dword ptr [eax]
      jmp   src2              ;check next parameter for Src2

   @@:
      test  uID,SRC1_DIMM     ;is Src1 an immediate 32-bit integer?
      jz    @F                ;check next source for Src1
      fild  lpSrc1
      jmp   src2              ;check next parameter for Src2

   @@:
      test  uID,SRC1_CONST    ;is Src1 one of the FPU constants?
      jnz   @F                ;otherwise no valid ID for Src1

srcerr:
      frstor content
srcerr1:
      xor   eax,eax           ;error code
      ret

   @@:
      test  eax,FPU_PI
      jz    @F
      fldpi
      jmp   src2
   @@:
      test  eax,FPU_NAPIER
      jz    srcerr            ;no correct CONST flag for Src1
      fld1
      fldl2e
      fsub  st,st(1)
      f2xm1
      fadd  st,st(1)
      fscale
      fstp  st(1)

;----------------------------------------
;check source for Src2 and load it to FPU
;----------------------------------------

src2:
      test  uID,SRC2_FPU      ;is Src2 taken from FPU?
      jz    @F                ;check next source for Src2
      lea   eax,content
      fld   tbyte ptr[eax+28]
      jmp   dest0             ;go complete process
   @@:
      mov   eax,lpSrc2
      test  uID,SRC2_REAL     ;is Src2 an 80-bit REAL in memory?
      jz    @F
      fld   tbyte ptr [eax]
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC2_DMEM     ;is Src2 a 32-bit integer in memory?
      jz    @F
      fild  dword ptr [eax]
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC2_DIMM     ;is Src2 an immediate 32-bit integer?
      jz    @F
      fild  lpSrc2
      jmp   dest0             ;go complete process
   @@:
      test  uID,SRC2_CONST    ;is Src2 one of the FPU constants?
      jz    srcerr            ;no correct flag for Src2
      test  eax,FPU_PI
      jz    @F
      fldpi                   ;load pi (3.14159...) on FPU
      jmp   dest0             ;go complete process
   @@:
      test  eax,FPU_NAPIER
      jz    srcerr            ;no correct CONST flag for Src2
      fld1
      fldl2e
      fsub  st,st(1)
      f2xm1
      fadd  st,st(1)
      fscale
      fstp  st(1)

dest0:
      fprem
      fstsw ax                ;retrieve exception flags from FPU
      fwait
      shr   al,1              ;test for invalid operation
      jc    srcerr            ;clean-up and return error

      test  uID,DEST_FPU      ;check where result should be stored
      jnz   @F                ;destination is the FPU
      mov   eax,lpDest
      fstp  tbyte ptr[eax]    ;store result at specified address
      jmp   restore
   @@:
      fstp  tempst            ;store it temporarily

restore:
      frstor  content         ;restore all previous FPU registers

      test  uID,SRC1_FPU or SRC2_FPU      ;was any data taken from FPU?
      jz    @F
      fstp  st                ;remove source

   @@:
      test  uID,DEST_FPU
      jz    @F                ;the new value has been stored in memory
                              ;none of the FPU data was modified

      ffree st(7)             ;free it if not already empty
      fld   tempst            ;load the new value on the FPU
   @@:
      or    al,1              ;to insure EAX!=0
      ret
   
FpuMod endp

raymond

BEAUTIFUL!!! :clap: :clap: :clap:
Couldn't have done better myself. :P
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

dedndave

very cool, Cube   :U
i didn't think it would be that complicated, though - lol
but, your proc covers all the bases

jcfuller

I'm getting a 404 when clicking on the download on your page Ray.

James

dedndave

#7
try this link, James
it looks like Ray updated the file using lower case, but updated the link in the html using upper case  :P

http://www.ray.masmcode.com/downloads/Fpulib2_31.zip

UtillMasm

Network Timeout
The server at www.ray.masmcode.com is taking too long to respond.

dedndave

#9
i hope Ray doesn't mind if i put it here for you   :bg

jcfuller

Quote from: dedndave on January 07, 2010, 02:16:58 PM
i hope Ray doesn't mind if i put it here for you   :bg

Thanks. I got it from the link you supplied.
I've added E^ Cube's FpuMod, tweaked the include file , and produced a working library using JWasm on Ubuntu 32.
This version makes it quite usable on linux as the help file is in chm format. This is read nicely with the Firefox chm reader add on.

James

ecube

Great update Raymond  :U

and thanks but the FpuMod really is literally all of raymonds code, I copy pasted the FpuDiv and I think the only thing I changed was

dest0:
      fdiv

to

dest0:
      fprem


haha so thanks Raymond  :bg

raymond

Quoteit looks like Ray updated the file using lower case, but updated the link in the html using upper case

Thanks Dave for pointing out my stupid error. It's now corrected.

I have now uploaded an updated version 2_31 which contains the modikfied tester complete with the mod function. I've also corrected the mod function of the library because I was not loading the FPU correctly with the sources as in the description, yielding erroneous results (noticed that with the tester). I should never have uploaded the modified library in the middle of the night without fully testing it.  There's an old latin saying which translate loosely like this: HURRY UP SLOWLY!!!

Sorry for any inconvenience.

I'm also editing my first post to upload the modified tester package.

If I don't receive any error report within the next week, I'll also ask Hutch to update the other sites carrying the lib.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ecube

Quote from: raymond on January 07, 2010, 07:16:56 PM
Quoteit looks like Ray updated the file using lower case, but updated the link in the html using upper case

Thanks Dave for pointing out my stupid error. It's now corrected.

I have now uploaded an updated version 2_31 which contains the modikfied tester complete with the mod function. I've also corrected the mod function of the library because I was not loading the FPU correctly with the sources as in the description, yielding erroneous results (noticed that with the tester). I should never have uploaded the modified library in the middle of the night without fully testing it.  There's an old latin saying which translate loosely like this: HURRY UP SLOWLY!!!

Sorry for any inconvenience.

I'm also editing my first post to upload the modified tester package.

If I don't receive any error report within the next week, I'll also ask Hutch to update the other sites carrying the lib.


:(, i've used it only abit, thought it worked alright, my apologies, atleast you fixed it before it's mainstream

raymond

Quotethought it worked alright, my apologies,

There's no need to apologize. Your provided procedure would work perfectly by loading the moduolus first followed by the other source, yielding Src2 modulo Src1. There being no description of the order for the parameters, I simply made a wrong assumption before testing it. I for one should know about the risk of making assumptions. :snooty: :naughty: :bdg :eek
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com