flat assembler
Message board for the users of flat assembler.

Index > Main > FPU Conditional Testing; What's wrong with this code?

Author
Thread Post new topic Reply to topic
fasmnub



Joined: 26 Jan 2010
Posts: 14
fasmnub
..apart from it being very unoptimized (it's clunky so I can understand what's happening).

This is a series of If float_variable=<>??? ... Endif type statements I wrote to help me learn this stuff, but it doesn't behave as expected. Can anyone spot what's going wrong? I commented it so you can tell what I'm trying to do here..

Code:
;--------------------------------------------If x#=1.0
mov  eax, dword [v_x]
push eax
mov  dword eax, 1.0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,40h
JE   cl_2
cmp  eax, 0
jz   cl_1
;--------------------------------------------Condition is true; y#=0
mov  dword eax, 0f
mov  [v_y], eax
;--------------------------------------------EndIf
cl_1:
;--------------------------------------------If x#>1.0
mov  eax, dword [v_x]
push eax
mov  dword eax, 1.0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,41h
JNE   cl_4
cmp  eax, 0
jz   cl_3
;--------------------------------------------Condition is true; x#=1.0
mov  dword eax, 1.0f
mov  [v_x], eax
;--------------------------------------------EndIf
cl_3:
;--------------------------------------------If x#>=1.0
mov  eax, dword [v_x]
push eax
mov  dword eax, 1.0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,1h
JNE   cl_6
cmp  eax, 0
jz   cl_5
;--------------------------------------------Condition is true; y#=0
mov  dword eax, 0f
mov  [v_y], eax
;--------------------------------------------EndIf
cl_5:
;--------------------------------------------If x#<0
mov  eax, dword [v_x]
push eax
mov  dword eax, 0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,1h
JE   cl_8
cmp  eax, 0
jz   cl_7
;--------------------------------------------Condition is true; x#=0
mov  dword eax, 0f
mov  [v_x], eax
;--------------------------------------------EndIf
cl_7:
;--------------------------------------------If x#<=0
mov  eax, dword [v_x]
push eax
mov  dword eax, 0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,41h
JE   cl_10
cmp  eax, 0
jz   cl_9
;--------------------------------------------Condition is true; y#=0
mov  dword eax, 0f
mov  [v_y], eax
;--------------------------------------------EndIf
cl_9:
;--------------------------------------------If x#=0.5
mov  eax, dword [v_x]
push eax
mov  dword eax, 0.5f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,40h
JE   cl_12
cmp  eax, 0
jz   cl_11
;--------------------------------------------Condition is true; y#=0.5
mov  dword eax, 0.5f
mov  [v_y], eax
;--------------------------------------------EndIf
cl_11:
;--------------------------------------------If x#<>0
mov  eax, dword [v_x]
push eax
mov  dword eax, 0f
pop  ebp
MOV  dword [FPV], ebp
MOV  dword [FPVn], eax
FLD    dword [FPV]
FCOMP  dword [FPVn]
FNSTSW ax
mov eax,0
TEST   ah,40h
JNE   cl_14
cmp  eax, 0
jz   cl_13
;--------------------------------------------Condition is true; y#=1
mov  dword eax, 1f
mov  [v_y], eax
;--------------------------------------------EndIf
cl_13:
    


I'm mainly concerned about the FCOMP, FNSTSW, TEST, JE stuff.. any help, code samples or related links would be hugely appreciated.

Thanks!

Edit to add: This isn't the whole code, just the bit that's not working, FPV and FPVn are declared elsewhere and used for conditional testing. The specific problem is that the condition tested is either always true, or never true.. so I've misunderstood something fundamental about FPU stuff. :(
Post 18 Feb 2010, 08:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17714
Location: In your JS exploiting you and your system
revolution
Hint: Look at the sahf opcode. It probably does everything you want without needing all those complicated 'test' instructions.
Post 18 Feb 2010, 09:05
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Or he could just take a look to FCOMI/FCOMIP, I think that very few still-working old computers won't work with it.
Post 18 Feb 2010, 16:55
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17714
Location: In your JS exploiting you and your system
revolution
BTW: Why do you have the 'mov eax,0' after every fnstsw?
Code:
FNSTSW ax
mov eax,0  ;<---- What is this for?    
Post 18 Feb 2010, 17:00
View user's profile Send private message Visit poster's website Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
Here a snippet...
Code:
        fld     [value]
        fld     [max] ; 60.0 for example (>0)
        fcom
        fnstsw  ax
        sahf
        jc      .clamp
        fstp    st0
        fld     [min] ; -60.0 for example (<0)
        fcom
        fnstsw  ax
        sahf
        jc      .noclamp
    .clamp:
        fxch
    .noclamp:
        fstp    st0
        fstp    [value]
    

Also you can gain speed in some cases by just checking sign bit...
Post 18 Feb 2010, 21:15
View user's profile Send private message Reply with quote
fasmnub



Joined: 26 Jan 2010
Posts: 14
fasmnub
@bitshifter, @revolution

perfect! just what i needed, thanks both!
Post 18 Feb 2010, 21:55
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Sorry to insist but is really so problematic FCOMI?

Code:
        fld     [value]
        fld     [max] ; 60.0 for example (>0)
        fcomi
        jc      .clamp

        fstp    st0
        fld     [min] ; -60.0 for example (<0)
        fcomi
        jc      .noclamp

    .clamp:
        fxch

    .noclamp:
        fstp    st0
        fstp    [value]    
Post 18 Feb 2010, 22:27
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
Thanks Loco!
No need to apologize when posting nicer code.
I wish you would insist a little more often Smile

Also, if you have SSE2 and can find some way to have
the need to min/max 4 floats at the same time (even in less clocks)
Code:
; data is assumed to be aligned on 16 byte boundary!
movaps xmm0,[_4values]
maxps  xmm0,[_4mins]
minps  xmm0,[_4maxes]
movaps [_4results],xmm0
    


So to make it work, the data need to be like this...
Code:
align 16
_4values  dd 0.0,0.0,0.0,0.0
_4mins    dd 0.0,0.0,0.0,0.0
_4maxes   dd 0.0,0.0,0.0,0.0
_4results dd 0.0,0.0,0.0,0.0
; TODO: Give values something valid...    


Have fun Smile
Post 19 Feb 2010, 02:28
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
Ooh, i just cant stop playing with this...
So now we use a conditional move (no jumping)
Code:
      fld     [value] 
    fld     [max]
        fcomi   st0,st1
        fcmovnb st0,st1
        fxch
        fstp    st0
        fld     [min]
        fcomi   st0,st1
        fcmovb  st0,st1
        fstp    [result]
        fstp    st0
    

Just for fun Smile
Post 19 Feb 2010, 14:44
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
And seems that fcmov was introduced in PPro too so you are not adding extra hardware requirements Very Happy
Post 19 Feb 2010, 15:27
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.