Page 1 of 1

EnableUnsigned()

Posted: Sat Mar 26, 2016 1:09 am
by idle
Macro to enable unsigned arithmetic and logic for windows and linux x86 and x64 for Longs and Integers

note this patches the assembly in the assembler and could yield unexpected results, use with caution!

Code: Select all

;EnableUnsigned  v1.0a   
;Author Idle 25/3/16 
;Supports PB 5.42LTS Window, Linux  
;Unsigned arithmetic and logical comparisons for   
;x64: Long, Integer, Quads 
;x86: Long, Integer 
;Usage: 
;Scope unsigned arithmetic and logic in EnableUnsigned() DisableUnsigned() blocks
;EnableUnsigned()  
;if ux > uy  ; changes the operators to unsigned: supports < > <= >= <> =   
;    do something unsigned: supports * / + - << >>  
;  DisableUnsigned()
;   ;back to signed  
;EndIf 
;Disableunsigned() ;Note you can call Disableunsigned() where ever you need it 


CompilerIf SizeOf(integer) = 4
  
  
Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !mov edx,0 
     !div var
  !}
  
  !macro IMUL reg,var
  !{
    !mov eax,reg 
    !mul var
    !mov reg,eax 
  !}  
  
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
    
  !macro CDQ {} 
  
  !macro JG arg
  !{ 
  !JA arg 
  !}
  !macro JGE arg 
  !{ 
     !JAE arg 
  !}
  !macro JL arg 
  !{
     !JB arg 
  !}
  !macro JLE arg 
  !{ 
     !JBE arg 
  !}
  
EndMacro

Macro DisableUnsigned() 
  !purge IDIV
  !purge IMUL
  !purge SAR
  !purge SAL 
  !purge CDQ 
  !purge JG
  !purge JGE
  !purge JL
  !purge JLE
EndMacro 

CompilerElse 
   
  Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !mov rdx,0 
     !div var
  !}
  
  !macro IMUL reg,var
  !{
  !match =qword x , var 
  !\{ mov rax, reg 
     !mov r15, var 
   !\} 
    !mul reg
    !mov reg,rax 
  !}  
  
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
    
  !macro MOVSXD reg,var  
  !{ 
    !match =dword x , var 
    !\{ mov eax, var 
       !mov reg,rax \} 
    !} 
  !macro CQO {}
  !macro CDO {}
  !macro CWD {} 
  !macro CBW {}
  !macro CWDE{}
  !macro CDQE {} 
  !macro CDQ {} 
  
  !macro JG arg
  !{ 
  !JA arg 
  !}
  !macro JGE arg 
  !{ 
     !JAE arg 
  !}
  !macro JL arg 
  !{
     !JB arg 
  !}
  !macro JLE arg 
  !{ 
     !JBE arg 
  !}
  
EndMacro 

Macro DisableUnsigned() 
  !purge IDIV
  !purge IMUL
  !purge SAR
  !purge SAL 
  !purge MOVSXD
  !purge CQO 
  !purge CDO
  !purge CWD 
  !purge CBW
  !purge CWDE 
  !purge CDQE 
  !purge CDQ 
  !purge JG
  !purge JGE
  !purge JL
  !purge JLE
EndMacro   

CompilerEndIf   

OpenConsole()

CompilerIf #PB_Compiler_IsMainFile 
Global x.l,y.l 
x=2
y=$FFFFFFFC
If x > y 
  PrintN("Result not unsigned, activating EnableUnsigned()")
  EnableUnsigned()
EndIf   

If y >= x 
  PrintN("OK Unsigned Enabled ")
EndIf 

If PeekL(@y) >= PeekL(@x)
   PrintN("OK peekL Unsigned Enabled ")
EndIf 

x = -1 
If x = $ffffffff 
  PrintN("unsigned -1") 
EndIf   


y=$FFFFFFFE
x=2
If x < y 
  PrintN("OK x <= y")
  y / 2
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;7FFFFFFF
  y * x
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;FFFFFFFE 
  y >> 1 
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;7FFFFFFF 
  y << 1 
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;FFFFFFFE  
  y - x 
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;FFFFFFFC
  y + x 
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;FFFFFFFE
  DisableUnsigned()
  y / 2 
  PrintN(Hex(y,#PB_Long) + " " + StrU(y) + " should be 7FFFFFFF if unsigned was used ")  
  y * x
  PrintN(Hex(y,#PB_Long) + " " + StrU(y))  ;FFFFFFFE -
EndIf 

 x = -1 
 If x = $ffffffff 
   PrintN("signed -1") 
 EndIf 


CompilerIf SizeOf(Integer) = 8; 

Global xx.q,yy.q 
xx=2
yy=$FFFFFFFFFFFFFFFC
Debug yy 

If xx > yy 
  PrintN("Result not unsigned, activating EnableUnsigned()")
  EnableUnsigned()
EndIf   

If yy >= xx 
  PrintN("OK Unsigned Enabled ")
EndIf 

If PeekQ(@yy) >= PeekQ(@xx)
   PrintN("OK peekQ Unsigned Enabled ")
EndIf   

yy=$FFFFFFFFFFFFFFFE  

If xx <= yy 
  
  PrintN("OK xx <= yy")
  yy / 2
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;7FFFFFFFFFFFFFFF
  yy * xx
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;FFFFFFFFFFFFFFFE 
  yy >> 1 
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;7FFFFFFFFFFFFFFF 
  yy << 1 
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;FFFFFFFFFFFFFFFE  
  yy - xx 
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;FFFFFFFFFFFFFFFC
  yy + xx 
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;FFFFFFFFFFFFFFFE
  DisableUnsigned()
  yy / 2 
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy) + " should be 7FFFFFFFFFFFFFFF if unsigned was used ") 
  yy * xx
  PrintN(Hex(yy,#PB_Quad) + " " + StrU(yy))  ;FFFFFFFFFFFFFFFE-
EndIf

CompilerEndIf 

CompilerEndIf 

Input()
CloseConsole() 

Re: EnableUnsigned()

Posted: Sat Mar 26, 2016 9:10 pm
by Thunder93
Hi idle. Thanks for putting the effort into this. You seem to have a working solution for unsigned arithmetic.

Would be great if people can apply this to existing projects and see how it'll fair.

Just wanted to show my gratitude. Keep up the superb work! :mrgreen:

Re: EnableUnsigned()

Posted: Mon Mar 28, 2016 12:27 am
by Keya
This is a HUGE BREAKTHROUGH IN PUREBASIC!!!!!!! Absolutely brilliant work idle!!! Im surprised how little code was required though! Nice job sneaking it in Easter when nobodys looking too lol :) :) :) might explain no comment from PB! Hopefully YASM on OSX is as flexible as FASM on Windows/Linux!

Re: EnableUnsigned()

Posted: Mon Oct 22, 2018 11:39 am
by LiK137
Few features left to find in forum PB to be perfect.
Enormous/Tremendous respects to Idle for Unsigned feature.

Re: EnableUnsigned()

Posted: Thu Nov 19, 2020 4:06 am
by kparadine
This is awfully cool stuff. It's too bad that it requires you to use unsigned (long/int/quad) in sections and then disable it to call API functions, because it appears to change ALL (long/int/quad) in the program into unsigned integers.

It would still be nicer to have them as accessible types at all times, knowing full well that the Purebasic API requires signed ints for everything that gets fed into it.

Having this, and actual variable length parameter lists (think sprintf/sscanf), would allow the replication of just about anything in Purebasic. And those convenience features like ++ and -- wouldn't hurt either.

I know it's asking a lot, but I think some people (me included) would pay for such things.

Re: EnableUnsigned()

Posted: Thu Nov 19, 2020 9:02 am
by BarryG
Is this safe to use? I mean, if it were that simple, why hasn't Fred officially done it yet? He must be avoiding it for some internal compiler reason?

Re: EnableUnsigned()

Posted: Thu Nov 19, 2020 9:30 am
by idle
BarryG wrote:Is this safe to use? I mean, if it were that simple, why hasn't Fred officially done it yet? He must be avoiding it for some internal compiler reason?
I'm not sure if it's safe and the asm output from the compiler could have changed between versions for all I know, plus it only works for windows and linux.

Yes it is that simple, there's no reason why it couldn't be done and it would be a most welcome addition to have unsigned fully supported

Re: EnableUnsigned()

Posted: Thu Nov 19, 2020 10:03 am
by Saki
An evergreen.

Re: EnableUnsigned()

Posted: Mon Dec 21, 2020 11:47 am
by kinglestat
Thanks this is truly a nice cheat

Re: EnableUnsigned()

Posted: Wed Dec 30, 2020 4:24 pm
by Kwai chang caine
Thanks IDLE for sharing :wink: