last one I hope, please try to break it. (probably won't have to try to hard)
for x86 it should handle unsigned arithmetic for longs, integers (quads aren't possible)
Code: Select all
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 {}
EndMacro
Macro DisableUnsigned()
!purge IDIV
!purge IMUL
!purge SAR
!purge SAL
!purge CDQ
EndMacro
Procedure Unsigned(arg1.i,op1.l,arg2.i)
EnableASM
Select op1
Case '<'
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!setb al
ProcedureReturn
Case '<='
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!setbe al
ProcedureReturn
Case '>'
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!seta al
ProcedureReturn
Case '>='
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!setae al
ProcedureReturn
Case '='
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!sete al
ProcedureReturn
Case '<>'
!xor eax , eax
!mov edx, [p.v_arg1]
!cmp edx, [p.v_arg2]
!setne al
ProcedureReturn
EndSelect
EndProcedure
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 {}
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
EndMacro
Procedure Unsigned(arg1.i,op1.l,arg2.i)
EnableASM
Select op1
Case '<'
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!setb al
ProcedureReturn
Case '<='
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!setbe al
ProcedureReturn
Case '>'
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!seta al
ProcedureReturn
Case '>='
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!setae al
ProcedureReturn
Case '='
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!sete al
ProcedureReturn
Case '<>'
!xor rax,rax
!mov rdx, [p.v_arg1]
!cmp rdx, [p.v_arg2]
!setne al
ProcedureReturn
EndSelect
EndProcedure
CompilerEndIf
Global x.l,y.l
x=2
y=$FFFFFFFE
Debug y
y / 2
Debug y
EnableUnsigned()
y=$FFFFFFFE
If Unsigned(x,'<=',y) ; unsigned comparison.
Debug "OK"
y / 2
Debug Hex(y,#PB_Long) + " " + StrU(y) ;7FFFFFFF
y * x
Debug Hex(y,#PB_Long) + " " + StrU(y) ;FFFFFFFE
y >> 1
Debug Hex(y,#PB_Long) + " " + StrU(y) ;7FFFFFFF
y << 1
Debug Hex(y,#PB_Long) + " " + StrU(y) ;FFFFFFFE
y - x
Debug Hex(y,#PB_Long) + " " + StrU(y) ;FFFFFFFC
y + x
Debug Hex(y,#PB_Long) + " " + StrU(y) ;FFFFFFFE
DisableUnsigned()
y / 2
Debug Hex(y,#PB_Long) + " " + StrU(y) + " should be 7FFFFFFF if unsigned was used "
y * x
Debug Hex(y,#PB_Long) + " " + StrU(y) ;FFFFFFFE -
EndIf
CompilerIf SizeOf(Integer) = 8;
;
Global xx.q,yy.q
xx=2
yy=$FFFFFFFFFFFFFFFE
Debug yy
yy / 2
Debug yy
EnableUnsigned()
xx=2
y=$FFFFFFFFFFFFFFFE
If Unsigned(xx,'<=',yy) ; unsigned comparison.
Debug "OK"
yy / 2
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;7FFFFFFFFFFFFFFF
yy * xx
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;FFFFFFFFFFFFFFFE
yy >> 1
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;7FFFFFFFFFFFFFFF
yy << 1
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;FFFFFFFFFFFFFFFE
yy - xx
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;FFFFFFFFFFFFFFFC
yy + xx
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;FFFFFFFFFFFFFFFE
DisableUnsigned()
yy / 2
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) + " should be 7FFFFFFFFFFFFFFF if unsigned was used "
yy * xx
Debug Hex(yy,#PB_Quad) + " " + StrU(yy) ;FFFFFFFE -
EndIf
CompilerEndIf