This commit is contained in:
Pavel 2025-05-26 14:43:31 +03:00
parent f205dd419f
commit b75f4ed26a
3 changed files with 189 additions and 8 deletions

View File

@ -55,6 +55,7 @@ type
function fetch_vdst8_64(VDST:Word;rtype:TsrDataType):TsrRegNode;
//
procedure OpCmpV(OpId:DWORD;dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpCmpClass(dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpConvFloatToHalf2(dst:PsrRegSlot;src0,src1:TsrRegNode);
//
@ -550,6 +551,135 @@ begin
SetThreadBit(dst0,dst1,exc);
end;
const
fcSignalingNan = 1 shl 0;
fcQuietNan = 1 shl 1;
fcNegativeInfinity = 1 shl 2;
fcNegativeNormal = 1 shl 3;
fcNegativeDenorm = 1 shl 4;
fcNegativeZero = 1 shl 5;
fcPositiveZero = 1 shl 6;
fcPositiveDenorm = 1 shl 7;
fcPositiveNormal = 1 shl 8;
fcPositiveInfinity = 1 shl 9;
fcAny = (1 shl 10)-1;
fcNaN = fcSignalingNan or fcQuietNan;
fcInfinity = fcPositiveInfinity or fcNegativeInfinity;
fcNegative = fcNegativeInfinity or fcNegativeNormal or fcNegativeDenorm or fcNegativeZero;
fcPositive = fcPositiveZero or fcPositiveDenorm or fcPositiveNormal or fcPositiveInfinity;
procedure TEmitFetch.OpCmpClass(dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
var
rsl:TsrRegNode;
ror:TsrRegNode;
exc:TsrRegNode;
msk:TsrConst;
val:DWORD;
function _test_group(val,mask:DWORD):Boolean; inline;
var
i:DWORD;
begin
i:=(val and mask);
Result:=(i=0) or (i=mask);
end;
begin
msk:=src1.AsConst;
if (msk<>nil) then
begin
val:=msk.AsUint32;
if (val and fcAny)=fcAny then
begin
ror:=NewImm_b(True);
end else
if _test_group(val,fcNaN ) or
_test_group(val,fcInfinity) or
_test_group(val,fcNegative) or
_test_group(val,fcPositive) then
begin
ror:=nil;
if (val and fcNaN)=fcNaN then
begin
rsl:=NewReg(dtBool);
_Op1(line,Op.OpIsNan,rsl,src0);
ror:=rsl;
end;
if (val and fcInfinity)=fcInfinity then
begin
rsl:=NewReg(dtBool);
_Op1(line,Op.OpIsInf,rsl,src0);
//
if (ror=nil) then
begin
ror:=rsl;
end else
begin
ror:=OpLogicalOrTo(ror,rsl);
end;
//
end;
if (val and fcNegative)=fcNegative then
begin
rsl:=NewReg(dtBool);
_Op2(line,Op.OpFOrdLessThanEqual,rsl,src0,NewImm_s(dtFloat32,-0.0));
//
if (ror=nil) then
begin
ror:=rsl;
end else
begin
ror:=OpLogicalOrTo(ror,rsl);
end;
//
end;
if (val and fcPositive)=fcPositive then
begin
rsl:=NewReg(dtBool);
_Op2(line,Op.OpFOrdGreaterThanEqual,rsl,src0,NewImm_s(dtFloat32,+0.0));
//
if (ror=nil) then
begin
ror:=rsl;
end else
begin
ror:=OpLogicalOrTo(ror,rsl);
end;
//
end;
if (ror=nil) then
begin
ror:=NewImm_b(False);
end;
end else
begin
Assert(false,'TODO: Unhandled mask V_CMP_CLASS_32:0x'+HexStr(val,2));
end;
end else
begin
Assert(false,'TODO: Non const V_CMP_CLASS_32');
end;
exc:=GetThreadBit(get_exec0,get_exec1,dtBool);
exc:=OpLogicalAndTo(ror,exc);
SetThreadBit(dst0,dst1,exc);
end;
procedure TEmitFetch.OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
begin
Op2(OpId,dtBool,dst,src0,src1);

View File

@ -20,6 +20,7 @@ type
procedure emit_VOP3a;
procedure emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
procedure emit_V_CMP_C (r,x:Boolean);
procedure emit_V_CMP_CLASS_32(x:Boolean);
procedure emit_src_neg_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType);
procedure emit_src_abs_bit(src:PPsrRegNode;count:Byte;rtype:TsrDataType);
@ -111,13 +112,37 @@ begin
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
SetConst_b(dst[0],r);
SetConst_q(dst[1],dtUnknow,0); //set zero
SetThreadBit(dst[0],dst[1],NewImm_b(r));
if x then
begin
MakeCopy (get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;
procedure TEmit_VOP3.emit_V_CMP_CLASS_32(x:Boolean);
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of TsrRegNode;
begin
if not get_sdst7_pair(FSPI.VOP3a.VDST,@dst) then Exit;
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32);
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32);
emit_src_abs_bit(@src,1,dtFloat32);
emit_src_neg_bit(@src,1,dtFloat32);
OpCmpClass(dst[0],dst[1],src[0],src[1]);
if x then
begin
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;
@ -1253,6 +1278,9 @@ begin
V_CMPX_LG_U32 :emit_V_CMP_32(Op.OpINotEqual ,dtUint32,true);
V_CMPX_GE_U32 :emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,true);
V_CMP_CLASS_F32 :emit_V_CMP_CLASS_32(false);
V_CMPX_CLASS_F32:emit_V_CMP_CLASS_32(true );
else
Assert(false,'VOP3c?'+IntToStr(FSPI.VOP3a.OP)+' '+get_str_spi(FSPI));
end;

View File

@ -17,6 +17,7 @@ type
procedure emit_VOPC;
procedure emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
procedure emit_V_CMP_C (r,x:Boolean);
procedure emit_V_CMP_CLASS_32(x:Boolean);
end;
implementation
@ -48,13 +49,32 @@ begin
dst[0]:=get_vcc0;
dst[1]:=get_vcc1;
SetConst_b(dst[0],r);
SetConst_q(dst[1],dtUnknow,0); //set zero
SetThreadBit(dst[0],dst[1],NewImm_b(r));
if x then
begin
MakeCopy (get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;
procedure TEmit_VOPC.emit_V_CMP_CLASS_32(x:Boolean);
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of TsrRegNode;
begin
dst[0]:=get_vcc0;
dst[1]:=get_vcc1;
src[0]:=fetch_ssrc9(FSPI.VOPC.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOPC.VSRC1,dtUInt32);
OpCmpClass(dst[0],dst[1],src[0],src[1]);
if x then
begin
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;
@ -193,6 +213,9 @@ begin
V_CMPX_LG_U32 :emit_V_CMP_32(Op.OpINotEqual ,dtUint32,true);
V_CMPX_GE_U32 :emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,true);
V_CMP_CLASS_F32 :emit_V_CMP_CLASS_32(false);
V_CMPX_CLASS_F32:emit_V_CMP_CLASS_32(true );
else
Assert(false,'VOPC?'+IntToStr(FSPI.VOPC.OP)+' '+get_str_spi(FSPI));
end;