Code: Select all
EnableExplicit
; works at x32 and x64
; min of 4 Long
; SSE PackedMin support only up to 32 Bit
Procedure Min4l(a.l, b.l, c.l=2147483647, d.l=2147483647)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerIf #PB_Compiler_64Bit
!XOR RAX, RAX
CompilerEndIf
!MOVD XMM0, [p.v_a] ; XMM0-LoWord = a
!MOVD XMM1, [p.v_b] ; XMM1-LoWord = b
!MOVD XMM2, [p.v_c] ; XMM2-LoWord = c
!MOVD XMM3, [p.v_d] ; XMM3-LoWord = d
!PMINSD XMM0, XMM1 ; Min(a,b)
!PMINSD XMM2, XMM3 ; Min(c,d)
!PMINSD XMM0, XMM2 ; MinOfAll -> XMM0
!MOVD EAX, XMM0 ; EAX = min
ProcedureReturn ; Return EAX/RAX
CompilerElse
If a > b : a = b : EndIf
If a > c : a = c : EndIf
If a > d : a = d : EndIf
ProcedureReturn a
CompilerEndIf
EndProcedure
Procedure Max4l(a.l, b.l, c.l=-2147483648, d.l=-2147483648 )
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerIf #PB_Compiler_64Bit
!XOR RAX, RAX
CompilerEndIf
!MOVD XMM0, [p.v_a] ; XMM0-LoWord = a
!MOVD XMM1, [p.v_b] ; XMM1-LoWord = b
!MOVD XMM2, [p.v_c] ; XMM2-LoWord = c
!MOVD XMM3, [p.v_d] ; XMM3-LoWord = d
!PMAXSD XMM0, XMM1 ; Max(a,b)
!PMAXSD XMM2, XMM3 ; Max(c,d)
!PMAXSD XMM0, XMM2 ; MaxOfAll -> XMM0
!MOVD EAX, XMM0 ; EAX = Max
ProcedureReturn ; Return EAX/RAX
CompilerElse
If a < b : a = b : EndIf
If a < c : a = c : EndIf
If a < d : a = d : EndIf
ProcedureReturn a
CompilerEndIf
EndProcedure
CompilerIf #PB_Compiler_64Bit
#MaxInt = 9223372036854775807
#MinInt = -9223372036854775808
CompilerElse
#MaxInt = 2147483647
#MinInt = -2147483648
CompilerEndIf
Procedure Min4i(a, b, c=#MaxInt, d=#MaxInt)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerIf #PB_Compiler_64Bit
!MOV RAX, [p.v_a] ; RAX = a
!CMP RAX, [p.v_b] ; compare with b
!CMOVG RAX, [p.v_b] ; If greater Then Load RAX with b
!CMP RAX, [p.v_c] ; compare with c
!CMOVG RAX, [p.v_c] ; If greater Then Load RAX with c
!CMP RAX, [p.v_d] ; compare with d
!CMOVG RAX, [p.v_d] ; If greater Then Load RAX with d
CompilerElse
!MOV EAX, [p.v_a] ; EAX = a
!CMP EAX, [p.v_b] ; compare with b
!CMOVG EAX, [p.v_b] ; If greater Then Load EAX with b
!CMP EAX, [p.v_c] ; compare with c
!CMOVG EAX, [p.v_c] ; If greater Then Load EAX with c
!CMP EAX, [p.v_d] ; compare with d
!CMOVG EAX, [p.v_d] ; If greater Then Load EAX with d
CompilerEndIf
CompilerElse
If a > b : a = b : EndIf
If a > c : a = c : EndIf
If a > d : a = d : EndIf
ProcedureReturn a
CompilerEndIf
ProcedureReturn ; Return EAX/RAX
EndProcedure
Procedure Max4i(a, b, c=#MinInt, d=#MinInt)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerIf #PB_Compiler_64Bit
!MOV RAX, [p.v_a] ; RAX = a
!CMP RAX, [p.v_b] ; compare with b
!CMOVL RAX, [p.v_b] ; If less Then Load RAX with b
!CMP RAX, [p.v_c] ; compare with c
!CMOVL RAX, [p.v_c] ; If less Then Load RAX with c
!CMP RAX, [p.v_d] ; compare with d
!CMOVL RAX, [p.v_d] ; If less Then Load RAX with d
CompilerElse
!MOV EAX, [p.v_a] ; EAX = a
!CMP EAX, [p.v_b] ; compare with b
!CMOVL EAX, [p.v_b] ; If less Then Load EAX with b
!CMP EAX, [p.v_c] ; compare with c
!CMOVL EAX, [p.v_c] ; If less Then Load EAX with c
!CMP EAX, [p.v_d] ; compare with d
!CMOVL EAX, [p.v_d] ; If less Then Load EAX with d
CompilerEndIf
ProcedureReturn ; Return EAX/RAX
CompilerElse
If a < b : a = b : EndIf
If a < c : a = c : EndIf
If a < d : a = d : EndIf
ProcedureReturn a
CompilerEndIf
EndProcedure
Define a=3
Define b=5
Define c=2
Define d=10
Debug Str(a) + ", " + Str(b) + ", " + Str(c) + ", " + Str(d)
Debug ""
Debug "Min of 2 Long = " + Str(Min4l(a,b))
Debug "Max of 2 Long = " + Str(Max4l(a,b))
Debug ""
Debug "Min of 3 Long = " + Str(Min4l(a,b,c))
Debug "Max of 3 Long = " + Str(Max4l(a,b,c))
Debug ""
Debug "Min of 4 Long = " + Str(Min4l(a,b,c,d))
Debug "Max of 4 Long = " + Str(Max4l(a,b,c,d))
Debug ""
Debug "------------------------------"
Debug ""
Debug "Min of 2 Int = " + Str(Min4i(a,b))
Debug "Max of 2 Int = " + Str(Max4i(a,b))
Debug ""
Debug "Min of 3 Int = " + Str(Min4i(a,b,c))
Debug "Max of 3 Int = " + Str(Max4i(a,b,c))
Debug ""
Debug "Min of 4 Int = " + Str(Min4i(a,b,c,d))
Debug "Max of 4 Int = " + Str(Max4i(a,b,c,d))