Page 3 of 6

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 9:10 pm
by idle
User_Russian wrote:Let's say that it is difficult to put unsigned variables due to libraries. But probably add a function Unsigned(expression), similar Bool().

Code: Select all

x.l=0
y.l=$FFFFFFFF

If Unsigned(x<y) ; unsigned comparison.
  Debug "OK"
EndIf
It is not difficult to do and does not require global modifications libraries.
I have already suggested, but it was not done.

Also, pay attention to this topic. If unsigned variables are not added, it is necessary to add a logical shift for signed variables.
test this:

Code: Select all

CompilerIf SizeOf(Integer) = 4 
  Macro rax : eax : EndMacro 
CompilerEndIf   
Procedure Unsigned(arg1.i,op1.l,arg2.i) 
  Select op1 
    Case '<'
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setb al 
      ProcedureReturn 
    Case '<='   
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setbe al 
       ProcedureReturn 
    Case '>'  
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !seta al 
      ProcedureReturn
    Case '>='  
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setae al 
       ProcedureReturn 
     Case '=' 
      !mov rax, [p.v_arg1]
      !cmp rax, [p.v_arg2] 
      !sete al 
      ProcedureReturn
    Case '<>' 
      !mov rax, [p.v_arg1]
      !cmp rax, [p.v_arg2] 
      !setne al 
      ProcedureReturn
  EndSelect     
EndProcedure     
  

x.l=$FFFFFFFF
y.l=$FFFFFFFE

If Unsigned(x,'>=',y) ; unsigned comparison.
  Debug "OK"
EndIf

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 9:54 pm
by User_Russian
Thank you, it works.
But I hope that the Unsigned() function will be added to PB, because the expression may be more complex than a simple comparison, and the necessary functionality like Bool().

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 10:25 pm
by Thunder93
Nice work idle. I see that you've already made revisions.. :shock:

@User_Russian; I guess persistence pays off? :)

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 10:46 pm
by idle
of course it would be better to have unsigned types and operators, but it should handle expressions

Code: Select all

CompilerIf SizeOf(Integer) = 4 
  Macro rdx : edx : EndMacro 
CompilerEndIf  
Procedure Unsigned(arg1.i,op1.l,arg2.i) 
  Select op1 
    Case '<'
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setb al 
      ProcedureReturn 
    Case '<='   
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setbe al 
       ProcedureReturn 
    Case '>'  
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !seta al 
      ProcedureReturn
    Case '>='  
      !mov rdx, [p.v_arg1]
      !cmp rdx, [p.v_arg2] 
      !setae al 
       ProcedureReturn 
     Case '=' 
      !mov rax, [p.v_arg1]
      !cmp rax, [p.v_arg2] 
      !sete al 
      ProcedureReturn
    Case '<>' 
      !mov rax, [p.v_arg1]
      !cmp rax, [p.v_arg2] 
      !setne al 
      ProcedureReturn
  EndSelect     
EndProcedure     
  

x.l=$FFFFFFFF
y.l=$FFFFFFFE

If Unsigned(x,'>=',y/2) ; unsigned comparison.
  Debug "OK"
EndIf

I think the only issues are with SAR SAL IDIV and conditional tests from CMP
It's possible to make a solution for windows and linux with fasm macros to patch sar sal and idiv
but the user would have to invoke EnableUnsigned() / DisableUnsigned()
Nice work idle. I see that you've already made revisions.. :shock:
I didn't have time to test it earlier and it was wrong with <= >=

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 10:50 pm
by jack
you made rax macro but then you use rdx ;)

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 10:56 pm
by idle
jack wrote:you made rax macro but then you use rdx ;)
:oops: thanks I'm multi tasking with a parrot chewing my ear, think it's hungry!

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:01 pm
by Thunder93
I'm lost.. :shock:
Which one do I save? :twisted:

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:19 pm
by idle
thunder this one

Code: Select all

CompilerIf SizeOf(Integer) = 8 
  Macro edx : rdx : EndMacro 
CompilerEndIf 
Procedure Unsigned(arg1.i,op1.l,arg2.i) 
   
  Select op1 
    Case '<'
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setb al 
      ProcedureReturn 
    Case '<='   
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setbe al 
       ProcedureReturn 
    Case '>'  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !seta al 
      ProcedureReturn
    Case '>='  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setae al 
       ProcedureReturn 
     Case '=' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !sete al 
      ProcedureReturn
    Case '<>' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setne al 
      ProcedureReturn
  EndSelect     
EndProcedure     
 


And for linux x64 and maybe windows try this: (x86 output may be different)

Code: Select all

CompilerIf SizeOf(Integer) = 8 
  Macro edx : rdx : EndMacro 
CompilerEndIf 

Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !xor edx,edx 
     !div var
  !} 
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
  
EndMacro

Macro DisableUnsigned() 
  !purge IDIV
  !purge SAR
  !purge SAL 
  UndefineMacro EnableUnsigned 
EndMacro   

Procedure Unsigned(arg1.i,op1.l,arg2.i) 
   
  Select op1 
    Case '<'
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setb al 
      ProcedureReturn 
    Case '<='   
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setbe al 
       ProcedureReturn 
    Case '>'  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !seta al 
      ProcedureReturn
    Case '>='  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setae al 
       ProcedureReturn 
     Case '=' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !sete al 
      ProcedureReturn
    Case '<>' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setne al 
      ProcedureReturn
  EndSelect     
EndProcedure     
  

x.l=$FFFFFFFF
y.l=$FFFFFFFE

If Unsigned(x,'>=',y/2) ; unsigned comparison.
  Debug "OK"
  EnableUnsigned() 
  Debug y / 2
  y<<1
  DisableUnsigned()
  Debug y / 2
  
EndIf

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:29 pm
by Thunder93
The second one, runs on x64 of Windows. However x86 it brings up asm error.


Under x86

Code: Select all

PureBasic - Assembler error

PureBasic.asm [211]:
mov rdx, [p.v_arg1]
error: illegal instruction.
Under x64 - Debug output

Code: Select all

OK
9223372036854775807
-2

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:36 pm
by Thunder93
First one in the previous post runs on x64 of Windows with PBx64. However with you revision and testing under Windows x64 and PBx86

Code: Select all

PureBasic - Assembler error

PureBasic.asm [182]:
mov rdx, [p.v_arg1]
error: illegal instruction.

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:36 pm
by Thunder93
hold on.. i'll try it

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:37 pm
by Thunder93
Your latest example. Under x64 Windows, with PBx86

Code: Select all

PureBasic - Assembler error

PureBasic.asm [212]:
mov rdx, [p.v_arg1]
error: illegal instruction.

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:40 pm
by Thunder93
restart the compiler and test... It's showing

PureBasic.asm [211]
however run it again. Now back to 212

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:45 pm
by idle
I'm spamming the thread now might have to moderate myself;
I don't have an x86 vm setup at the moment or windows either

so this should hopefully work now and I'll go back and edit my spam !

Code: Select all

CompilerIf SizeOf(Integer) = 8 
  Macro edx : rdx : EndMacro 
CompilerEndIf 

Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !xor edx,edx 
     !div var
  !} 
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
  
EndMacro

Macro DisableUnsigned() 
  !purge IDIV
  !purge SAR
  !purge SAL 
  UndefineMacro EnableUnsigned 
EndMacro   

Procedure Unsigned(arg1.i,op1.l,arg2.i) 
   
  Select op1 
    Case '<'
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setb al 
      ProcedureReturn 
    Case '<='   
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setbe al 
       ProcedureReturn 
    Case '>'  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !seta al 
      ProcedureReturn
    Case '>='  
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setae al 
       ProcedureReturn 
     Case '=' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !sete al 
      ProcedureReturn
    Case '<>' 
      !mov edx, [p.v_arg1]
      !cmp edx, [p.v_arg2] 
      !setne al 
      ProcedureReturn
  EndSelect     
EndProcedure     
  

x.l=$FFFFFFFF
y.l=$FFFFFFFE

If Unsigned(x,'>=',y/2) ; unsigned comparison.
  Debug "OK"
  EnableUnsigned() 
  Debug y / 2
  y<<1
  DisableUnsigned()
  Debug y / 2
  
EndIf

Re: Unsigned dword/qword

Posted: Wed Mar 23, 2016 11:53 pm
by Thunder93
PBx86 - Under Win x64
OK
2147483647
-2


---
PBx64 - Under Win x64
OK
9223372036854775807
-2


... Looks good. :)