mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
f205dd419f
commit
b75f4ed26a
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue