FPPS4/spirv/emit_sop1.pas

299 lines
6.5 KiB
Plaintext
Raw Normal View History

2022-05-31 07:17:14 +00:00
unit emit_SOP1;
{$mode objfpc}{$H+}
interface
uses
sysutils,
ps4_pssl,
2022-12-23 11:22:08 +00:00
spirv,
2022-09-05 13:30:24 +00:00
srCFGLabel,
srFlow,
srType,
2022-05-31 07:17:14 +00:00
srConst,
srReg,
srLayout,
2022-09-05 13:30:24 +00:00
srOpUtils,
emit_fetch;
2022-05-31 07:17:14 +00:00
type
2022-09-05 13:30:24 +00:00
TEmit_SOP1=class(TEmitFetch)
procedure emit_SOP1;
Function GetFuncPtr(src:PPsrRegNode):Pointer;
procedure emit_S_MOV_B32;
procedure emit_S_MOV_B64;
2022-12-05 15:03:14 +00:00
procedure OpISccNotZero(src:PsrRegNode);
procedure emit_S_NOT_B32;
procedure emit_S_NOT_B64;
2022-10-06 09:36:58 +00:00
procedure emit_S_GETPC_B64;
2022-09-05 13:30:24 +00:00
procedure emit_S_SETPC_B64;
2022-10-06 09:36:58 +00:00
procedure emit_S_SWAPPC_B64;
2022-09-05 13:30:24 +00:00
procedure emit_S_AND_SAVEEXEC_B64;
2022-12-23 11:22:08 +00:00
procedure emit_S_WQM_B32;
2022-09-05 13:30:24 +00:00
procedure emit_S_WQM_B64;
2022-12-23 11:22:08 +00:00
procedure emit_S_BREV_B32;
procedure emit_S_BREV_B64;
2022-05-31 07:17:14 +00:00
end;
implementation
2022-09-05 13:30:24 +00:00
Function TEmit_SOP1.GetFuncPtr(src:PPsrRegNode):Pointer;
2022-05-31 07:17:14 +00:00
var
chain:TsrChains;
2022-09-05 13:30:24 +00:00
pConst:array[0..1] of PsrConst;
2022-05-31 07:17:14 +00:00
pLayout:PsrDataLayout;
begin
Result:=nil;
2022-09-05 13:30:24 +00:00
src[0]:=RegDown(src[0]);
src[1]:=RegDown(src[1]);
Assert(src[0]<>nil);
Assert(src[1]<>nil);
if (src[0]^.is_const) and (src[1]^.is_const) then
begin
pConst[0]:=src[0]^.AsConst;
pConst[1]:=src[1]^.AsConst;
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
QWORD(Result):=QWORD(pConst[0]^.AsUint32) or (QWORD(pConst[1]^.AsUint32) shl 32);
end else
begin
chain:=Default(TsrChains);
chain[0]:=GetChainRegNode(src[0]);
chain[1]:=GetChainRegNode(src[1]);
pLayout:=DataLayoutList.Grouping(chain,rtFunPtr2);
Result:=pLayout^.pData;
end;
2022-05-31 07:17:14 +00:00
Assert(Result<>nil);
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_S_MOV_B32;
2022-05-31 07:17:14 +00:00
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
2022-09-05 13:30:24 +00:00
dst:=get_sdst7(FSPI.SOP1.SDST);
2022-05-31 07:17:14 +00:00
src:=fetch_ssrc9(FSPI.SOP1.SSRC,dtUnknow);
2022-12-23 11:22:08 +00:00
2022-09-05 13:30:24 +00:00
MakeCopy(dst,src);
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_S_MOV_B64;
2022-05-31 07:17:14 +00:00
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
2022-12-23 11:22:08 +00:00
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
2022-05-31 07:17:14 +00:00
2022-12-23 11:22:08 +00:00
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
MakeCopy(dst[0],src[0]);
MakeCopy(dst[1],src[1]);
2022-05-31 07:17:14 +00:00
end;
2022-12-05 15:03:14 +00:00
procedure TEmit_SOP1.OpISccNotZero(src:PsrRegNode); //SCC = (sdst.u != 0)
begin
MakeCopy(get_scc,src);
get_scc^.current^.dtype:=dtBool; //implict cast (int != 0)
end;
procedure TEmit_SOP1.emit_S_NOT_B32; //sdst = ~ssrc; SCC = (sdst != 0)
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=get_sdst7(FSPI.SOP1.SDST);
src:=fetch_ssrc9(FSPI.SOP1.SSRC,dtUnknow);
OpNot(dst,src);
src:=MakeRead(dst,dtUnknow);
OpISccNotZero(src);
end;
procedure TEmit_SOP1.emit_S_NOT_B64; //sdst[2] = ~ssrc0[2]; SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
2022-12-23 11:22:08 +00:00
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
2022-12-05 15:03:14 +00:00
2022-12-23 11:22:08 +00:00
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
2022-12-05 15:03:14 +00:00
OpNot(dst[0],src[0]);
OpNot(dst[1],src[1]);
src[0]:=MakeRead(dst[0],dtUnknow);
src[1]:=MakeRead(dst[1],dtUnknow);
OpLogicalOr(get_scc,src[0],src[1]); //implict cast (int != 0)
end;
2022-10-06 09:36:58 +00:00
procedure TEmit_SOP1.emit_S_GETPC_B64;
2022-05-31 07:17:14 +00:00
Var
dst:array[0..1] of PsrRegSlot;
2022-10-06 09:36:58 +00:00
oldptr:Pointer;
2022-05-31 07:17:14 +00:00
begin
2022-09-05 13:30:24 +00:00
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
oldptr:=GetPtr;
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
SetConst_q(dst[0],dtUint32,QWORD(oldptr));
SetConst_q(dst[1],dtUint32,QWORD(oldptr) shr 32);
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_S_SETPC_B64;
2022-05-31 07:17:14 +00:00
Var
2022-09-05 13:30:24 +00:00
src:array[0..1] of PsrRegNode;
2022-05-31 07:17:14 +00:00
newptr:Pointer;
begin
2022-09-05 13:30:24 +00:00
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
newptr:=GetFuncPtr(@src);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
SetPtr(newptr,btMain);
2022-05-31 07:17:14 +00:00
end;
2022-10-06 09:36:58 +00:00
procedure TEmit_SOP1.emit_S_SWAPPC_B64;
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
oldptr,newptr:Pointer;
begin
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
newptr:=GetFuncPtr(@src);
oldptr:=GetPtr;
SetConst_q(dst[0],dtUint32,QWORD(oldptr));
SetConst_q(dst[1],dtUint32,QWORD(oldptr) shr 32);
SetPtr(newptr,btSetpc);
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_S_AND_SAVEEXEC_B64; //sdst.du = EXEC;| EXEC = (ssrc.du & EXEC);| SCC = (sdst != 0)
2022-05-31 07:17:14 +00:00
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc:array[0..1] of PsrRegNode;
begin
2022-09-05 13:30:24 +00:00
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(False);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(False); //ssrc8
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
exc[0]:=MakeRead(get_exec0,dtUnknow);
exc[1]:=MakeRead(get_exec1,dtUnknow);
2022-05-31 07:17:14 +00:00
MakeCopy(dst[0],exc[0]);
MakeCopy(dst[1],exc[1]);
2022-09-05 13:30:24 +00:00
OpBitwiseAnd(get_exec0,src[0],exc[0]);
OpBitwiseAnd(get_exec1,src[1],exc[1]);
2022-05-31 07:17:14 +00:00
//SCC = ((exc[0] != 0) or ((exc[1] != 0))
2022-09-05 13:30:24 +00:00
OpLogicalOr(get_scc,exc[0],exc[1]); //implict cast (int != 0)
2022-05-31 07:17:14 +00:00
//SCC = (sdst != 0) SCC = ((exc[0] != 0) or ((exc[1] != 0))
end;
2022-12-23 11:22:08 +00:00
procedure TEmit_SOP1.emit_S_WQM_B32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=get_sdst7(FSPI.SOP1.SDST);
src:=fetch_ssrc9(FSPI.SOP1.SSRC,dtUnknow);
OpWQM32(dst,src);
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_S_WQM_B64;
2022-05-31 07:17:14 +00:00
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
//S_WQM_B64 EXEC_LO, EXEC_LO //sdst.du = wholeQuadMode(ssrc.du); SCC = (sdst.du != 0)
//dst[q*4+3:q*4].du = (ssrc[4*q+3:4*q].du != 0) ? 0xF : 0
//dst[3:0].du = (ssrc[3:0].du != 0) ? 0xF : 0
//dst[63:60].du = (ssrc[63:60].du != 0) ? 0xF : 0
//if (ssrc[3:0].du != 0) then dst[63:60].du=0xF else dst[63:60].du=0
2022-09-05 13:30:24 +00:00
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(False);
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(False); //ssrc8
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
OpWQM32(dst[0],src[0]);
OpWQM32(dst[1],src[1]);
2022-05-31 07:17:14 +00:00
end;
2022-12-23 11:22:08 +00:00
procedure TEmit_SOP1.emit_S_BREV_B32; //sdst[31:0] = ssrc[0:31]
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=get_sdst7(FSPI.SOP1.SDST);
src:=fetch_ssrc9(FSPI.SOP1.SSRC,dtUInt32);
Op1(Op.OpBitReverse,dtUInt32,dst,src);
end;
procedure TEmit_SOP1.emit_S_BREV_B64; //sdst[63:0] = ssrc[0:63]
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
Op1(Op.OpBitReverse,dtUInt32,dst[0],src[1]); //0 -> 1
Op1(Op.OpBitReverse,dtUInt32,dst[1],src[0]); //1 -> 0
end;
2022-09-05 13:30:24 +00:00
procedure TEmit_SOP1.emit_SOP1;
2022-05-31 07:17:14 +00:00
begin
Case FSPI.SOP1.OP of
2022-09-05 13:30:24 +00:00
S_MOV_B32 : emit_S_MOV_B32;
S_MOV_B64 : emit_S_MOV_B64;
2022-12-05 15:03:14 +00:00
S_NOT_B32 : emit_S_NOT_B32;
S_NOT_B64 : emit_S_NOT_B64;
2022-12-23 11:22:08 +00:00
S_WQM_B32 : emit_S_WQM_B32;
2022-09-05 13:30:24 +00:00
S_WQM_B64 : emit_S_WQM_B64;
2022-12-05 15:03:14 +00:00
2022-12-23 11:22:08 +00:00
S_BREV_B32 : emit_S_BREV_B32;
S_BREV_B64 : emit_S_BREV_B64;
2022-10-06 09:36:58 +00:00
S_GETPC_B64 : emit_S_GETPC_B64;
2022-09-05 13:30:24 +00:00
S_SETPC_B64 : emit_S_SETPC_B64;
2022-10-06 09:36:58 +00:00
S_SWAPPC_B64 : emit_S_SWAPPC_B64;
2022-09-05 13:30:24 +00:00
S_AND_SAVEEXEC_B64: emit_S_AND_SAVEEXEC_B64;
2022-05-31 07:17:14 +00:00
else
Assert(false,'SOP1?'+IntToStr(FSPI.SOP1.OP));
end;
end;
end.