mirror of https://github.com/red-prig/fpPS4.git
Big refraction of structuring CFG and many minor fixes
This commit is contained in:
parent
8e2961f5f6
commit
5b701a35d1
|
@ -1244,8 +1244,7 @@ type
|
|||
ENCODING:bit6;
|
||||
|
||||
ADDR:Byte; //(vbindex)
|
||||
DATA0:Byte; //(vsrc0)
|
||||
DATA1:Byte; //(vsrc1)
|
||||
DATA:array[0..1] of Byte; //(vsrc0),(vsrc1)
|
||||
VDST:Byte;
|
||||
end;
|
||||
|
||||
|
@ -3869,7 +3868,7 @@ begin
|
|||
TBUFFER_LOAD_FORMAT_X :str:='TBUFFER_LOAD_FORMAT_X';
|
||||
TBUFFER_LOAD_FORMAT_XY :str:='TBUFFER_LOAD_FORMAT_XY';
|
||||
TBUFFER_LOAD_FORMAT_XYZ :str:='TBUFFER_LOAD_FORMAT_XYZ';
|
||||
TBUFFER_LOAD_FORMAT_XYZW :str:='TBUFFER_LOAD_FORMAT_XYZ';
|
||||
TBUFFER_LOAD_FORMAT_XYZW :str:='TBUFFER_LOAD_FORMAT_XYZW';
|
||||
|
||||
TBUFFER_STORE_FORMAT_X :str:='TBUFFER_STORE_FORMAT_X';
|
||||
TBUFFER_STORE_FORMAT_XY :str:='TBUFFER_STORE_FORMAT_XY';
|
||||
|
@ -4056,22 +4055,22 @@ begin
|
|||
2,3,4:
|
||||
begin
|
||||
str:=str+'v['+IntToStr(SPI.MIMG.VDATA)+':'+IntToStr(SPI.MIMG.VDATA+t-1)+']';
|
||||
str:=str+', ';
|
||||
str:=str+'v['+IntToStr(SPI.MIMG.VADDR)+':'+IntToStr(SPI.MIMG.VADDR+t-1)+']';
|
||||
end;
|
||||
else
|
||||
begin
|
||||
str:=str+_get_vdst8(SPI.MIMG.VDATA);
|
||||
str:=str+', ';
|
||||
str:=str+_get_vdst8(SPI.MIMG.VADDR);
|
||||
end;
|
||||
end;
|
||||
str:=str+', ';
|
||||
|
||||
//operand #2
|
||||
str:=str+'s['+IntToStr(SPI.MIMG.SRSRC*4)+':'+IntToStr(SPI.MIMG.SRSRC*4+7)+']';
|
||||
str:=str+'v['+IntToStr(SPI.MIMG.VADDR)+':'+IntToStr(SPI.MIMG.VADDR+2)+']';
|
||||
str:=str+', ';
|
||||
|
||||
//operand #3
|
||||
str:=str+'s['+IntToStr(SPI.MIMG.SRSRC*4)+':'+IntToStr(SPI.MIMG.SRSRC*4+7)+']';
|
||||
|
||||
//operand #4
|
||||
Case SPI.MIMG.OP of
|
||||
IMAGE_SAMPLE..IMAGE_SAMPLE_C_CD_CL_O:
|
||||
begin
|
||||
|
@ -4376,19 +4375,50 @@ begin
|
|||
|
||||
//VDST vbindex vsrc0 vsrc1 OFFSET0 OFFSET1 GDS
|
||||
|
||||
str:=str+_get_vdst8(SPI.DS.VDST);
|
||||
str:=str+', ';
|
||||
//vdst
|
||||
Case SPI.DS.OP of
|
||||
DS_ADD_RTN_U32..DS_WRXCHG_RTN_B32,
|
||||
DS_CMPST_RTN_B32..DS_READ_B32,
|
||||
DS_READ_I8..DS_ORDERED_COUNT:
|
||||
begin
|
||||
str:=str+_get_vdst8(SPI.DS.VDST);
|
||||
str:=str+', ';
|
||||
end;
|
||||
|
||||
DS_WRXCHG2_RTN_B32 ,
|
||||
DS_WRXCHG2ST64_RTN_B32,
|
||||
DS_READ2_B32 ,
|
||||
DS_READ2ST64_B32 ,
|
||||
DS_ADD_RTN_U64..DS_WRXCHG_RTN_B64,
|
||||
DS_CMPST_RTN_B64..DS_READ_B64,
|
||||
DS_CONDXCHG32_RTN_B64:
|
||||
begin
|
||||
str:=str+_get_vdst8_cnt(SPI.DS.VDST,2);
|
||||
str:=str+', ';
|
||||
end;
|
||||
|
||||
DS_WRXCHG2_RTN_B64 ,
|
||||
DS_WRXCHG2ST64_RTN_B64,
|
||||
DS_READ2_B64 ,
|
||||
DS_READ2ST64_B64 :
|
||||
begin
|
||||
str:=str+_get_vdst8_cnt(SPI.DS.VDST,4);
|
||||
str:=str+', ';
|
||||
end;
|
||||
|
||||
else;
|
||||
end;
|
||||
|
||||
//vbindex
|
||||
str:=str+_get_vdst8(SPI.DS.ADDR);
|
||||
str:=str+', ';
|
||||
|
||||
//vsrc0
|
||||
str:=str+_get_vdst8(SPI.DS.DATA0);
|
||||
str:=str+_get_vdst8(SPI.DS.DATA[0]);
|
||||
str:=str+', ';
|
||||
|
||||
//vsrc1
|
||||
str:=str+_get_vdst8(SPI.DS.DATA1);
|
||||
str:=str+_get_vdst8(SPI.DS.DATA[1]);
|
||||
|
||||
str:=str+' OFFSET:0x'+HexStr(WORD(SPI.DS.OFFSET),4);
|
||||
|
||||
|
|
|
@ -1252,10 +1252,6 @@
|
|||
<Filename Value="spirv\srCapability.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="spirv\srCFGLabel.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="spirv\srConfig.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
|
|
@ -59,6 +59,8 @@ type
|
|||
Procedure InitCs(RSRC1:TCOMPUTE_PGM_RSRC1;
|
||||
RSRC2:TCOMPUTE_PGM_RSRC2);
|
||||
|
||||
Procedure cs_set_initial_exec;
|
||||
|
||||
Procedure SET_NUM_THREADS(NTX:TCOMPUTE_NUM_THREAD_X;
|
||||
NTY:TCOMPUTE_NUM_THREAD_Y;
|
||||
NTZ:TCOMPUTE_NUM_THREAD_Z);
|
||||
|
@ -706,6 +708,53 @@ begin
|
|||
AddCapability(Capability.Shader);
|
||||
end;
|
||||
|
||||
Procedure TSprvEmit.cs_set_initial_exec;
|
||||
var
|
||||
total:PtrUint;
|
||||
val:PtrUint;
|
||||
|
||||
vec:TsrRegNode;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
begin
|
||||
if not Config.UseExtendedEXECMask then Exit;
|
||||
|
||||
total:=FLocalSize.x*FLocalSize.y*FLocalSize.z;
|
||||
val:=not PtrUint(0);
|
||||
|
||||
if (total<64) then
|
||||
begin
|
||||
val:=(PtrUint(1) shl total)-1;
|
||||
end else
|
||||
if ((total mod 64)=0) then
|
||||
begin
|
||||
val:=not PtrUint(0);
|
||||
end else
|
||||
if (total>64) then
|
||||
begin
|
||||
Assert(false,'TODO: big unaligned total LocalSize');
|
||||
end;
|
||||
|
||||
SetConst_q(get_exec0,dtUnknow,val and (not DWORD(0)));
|
||||
SetConst_q(get_exec1,dtUnknow,val shr 32);
|
||||
|
||||
vec:=AddInput(@RegsStory.FUnattach,dtVec3u,itThreadId,0);
|
||||
|
||||
src[0]:=RegsStory.FUnattach.New(dtUint32);
|
||||
src[1]:=RegsStory.FUnattach.New(dtUint32);
|
||||
src[2]:=RegsStory.FUnattach.New(dtUint32);
|
||||
|
||||
OpExtract(init_line,src[0],vec,0);
|
||||
OpExtract(init_line,src[1],vec,1);
|
||||
OpExtract(init_line,src[2],vec,2);
|
||||
|
||||
FThread_id:=OpIMulTo(OpIMulTo(src[0],src[1]),src[2]);
|
||||
|
||||
if (total>64) then
|
||||
begin
|
||||
FThread_id:=OpAndTo(FThread_id,63);
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure TSprvEmit.SET_NUM_THREADS(NTX:TCOMPUTE_NUM_THREAD_X;
|
||||
NTY:TCOMPUTE_NUM_THREAD_Y;
|
||||
NTZ:TCOMPUTE_NUM_THREAD_Z);
|
||||
|
@ -721,6 +770,8 @@ begin
|
|||
if (FLocalSize.x=0) then FLocalSize.x:=1;
|
||||
if (FLocalSize.y=0) then FLocalSize.y:=1;
|
||||
if (FLocalSize.z=0) then FLocalSize.z:=1;
|
||||
//
|
||||
cs_set_initial_exec;
|
||||
end;
|
||||
|
||||
Procedure TSprvEmit.InitCustomGs();
|
||||
|
|
|
@ -193,25 +193,19 @@ begin
|
|||
lvl_0.size :=stride;
|
||||
lvl_0.offset:=offset;
|
||||
|
||||
//region_addr = (OFFSET + vbindex) & alignment
|
||||
if vbindex.is_const then
|
||||
begin
|
||||
//#static
|
||||
//i = #(OFFSET + vbindex) & alignment
|
||||
|
||||
lvl_0.offset:=lvl_0.offset + vbindex.AsConst.GetData;
|
||||
|
||||
lvl_0.offset:=lvl_0.offset and (not (stride-1));
|
||||
lvl_0.offset:=lvl_0.offset and (not (stride-1)); //4,8
|
||||
|
||||
Result:=pLayout.Fetch(@lvl_0,nil,cflags(atomic));
|
||||
end else
|
||||
if ((lvl_0.offset mod stride)=0) then
|
||||
begin
|
||||
//i = OFFSET + (vbindex / stride)
|
||||
|
||||
lvl_1.pIndex:=OpIDivTo(vbindex,stride);
|
||||
lvl_1.stride:=stride;
|
||||
|
||||
Result:=pLayout.Fetch(@lvl_0,@lvl_1,cflags(atomic));
|
||||
end else
|
||||
begin
|
||||
//#dynamic
|
||||
//i = (vbindex + OFFSET) / stride
|
||||
|
||||
lvl_1.pIndex:=OpIAddTo(vbindex,lvl_0.offset);
|
||||
|
@ -236,14 +230,14 @@ begin
|
|||
|
||||
if (rtype.BitSize=64) then
|
||||
begin
|
||||
vsrc:=fetch_vdst8_64(FSPI.DS.DATA0,dtUint64);
|
||||
vsrc:=fetch_vdst8_64(FSPI.DS.DATA[0],dtUint64);
|
||||
end else
|
||||
if (rtype.BitSize=32) then
|
||||
begin
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA0,rtype);
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],rtype);
|
||||
end else
|
||||
begin
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA0,dtUnknow);
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],dtUnknow);
|
||||
end;
|
||||
|
||||
case rtype of
|
||||
|
@ -260,10 +254,10 @@ end;
|
|||
//vbindex, vsrc0[], vsrc1[] [OFFSET0:<0..255>] [OFFSET1:<0..255>] [GDS:< 0|1>]
|
||||
procedure TEmit_DS.emit_DS_WRITE2(rtype:TsrDataType;extra_stride:Word);
|
||||
var
|
||||
pChain:array[0..1] of TsrChain;
|
||||
pChain:array[0..3] of TsrChain;
|
||||
|
||||
vbindex:TsrRegNode;
|
||||
vsrc:array[0..1] of TsrRegNode;
|
||||
vsrc:array[0..3] of TsrRegNode;
|
||||
|
||||
i,hi:Byte;
|
||||
begin
|
||||
|
@ -273,15 +267,41 @@ begin
|
|||
|
||||
if (rtype.BitSize=64) then
|
||||
begin
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
vsrc[i]:=fetch_vdst8_64(PBYTE(@FSPI.DS.DATA0)[i],dtUint64);
|
||||
vsrc[i*2+0]:=fetch_vdst8(FSPI.DS.DATA[i]+0,dtUint32);
|
||||
vsrc[i*2+1]:=fetch_vdst8(FSPI.DS.DATA[i]+1,dtUint32);
|
||||
end;
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
pChain[i*2+0]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+0);
|
||||
pChain[i*2+1]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+4);
|
||||
end;
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
FetchStore(pChain[i*2+0],vsrc[i*2+0]);
|
||||
FetchStore(pChain[i*2+1],vsrc[i*2+1]);
|
||||
end;
|
||||
|
||||
exit;
|
||||
|
||||
{
|
||||
Assert(false,'DS_WRITE2 64');
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
vsrc[i]:=fetch_vdst8_64(FSPI.DS.DATA[i],dtUint64);
|
||||
end;
|
||||
}
|
||||
|
||||
end else
|
||||
begin
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
vsrc[i]:=fetch_vdst8(PBYTE(@FSPI.DS.DATA0)[i],rtype);
|
||||
vsrc[i]:=fetch_vdst8(FSPI.DS.DATA[i],rtype);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -338,10 +358,10 @@ end;
|
|||
|
||||
procedure TEmit_DS.emit_DS_READ2(rtype:TsrDataType;extra_stride:Word);
|
||||
var
|
||||
pChain:array[0..1] of TsrChain;
|
||||
pChain:array[0..3] of TsrChain;
|
||||
|
||||
vbindex:TsrRegNode;
|
||||
vdst:array[0..1] of TsrRegNode;
|
||||
vdst:array[0..3] of TsrRegNode;
|
||||
|
||||
dst:array[0..3] of PsrRegSlot;
|
||||
|
||||
|
@ -351,6 +371,33 @@ begin
|
|||
|
||||
hi:=ord(FSPI.DS.OFFSET[0]<>FSPI.DS.OFFSET[1]);
|
||||
|
||||
if (rtype.BitSize=64) then
|
||||
begin
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
pChain[i*2+0]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+0);
|
||||
pChain[i*2+1]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+4);
|
||||
end;
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
vdst[i*2+0]:=FetchLoad(pChain[i*2+0],dtUint32);
|
||||
vdst[i*2+1]:=FetchLoad(pChain[i*2+1],dtUint32);
|
||||
end;
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
dst[i*2+0]:=get_vdst8(FSPI.DS.VDST+i*2+0);
|
||||
dst[i*2+1]:=get_vdst8(FSPI.DS.VDST+i*2+1);
|
||||
|
||||
MakeCopy(dst[i*2+0],vdst[i*2+0]);
|
||||
MakeCopy(dst[i*2+1],vdst[i*2+1]);
|
||||
end;
|
||||
|
||||
exit;
|
||||
end;
|
||||
|
||||
for i:=0 to hi do
|
||||
begin
|
||||
pChain[i]:=fetch_ds_chain(vbindex,rtype,dtUnknow,FSPI.DS.OFFSET[i]*(rtype.BitSize div 8)*extra_stride);
|
||||
|
@ -398,14 +445,14 @@ begin
|
|||
|
||||
if (rtype.BitSize=64) then
|
||||
begin
|
||||
vsrc:=fetch_vdst8_64(FSPI.DS.DATA0,dtUint64);
|
||||
vsrc:=fetch_vdst8_64(FSPI.DS.DATA[0],dtUint64);
|
||||
end else
|
||||
if (rtype.BitSize=32) then
|
||||
begin
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA0,rtype);
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],rtype);
|
||||
end else
|
||||
begin
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA0,dtUnknow);
|
||||
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],dtUnknow);
|
||||
end;
|
||||
|
||||
case rtype of
|
||||
|
|
|
@ -8,7 +8,8 @@ uses
|
|||
sysutils,
|
||||
ps4_pssl,
|
||||
si_ci_vi_merged_enum,
|
||||
srCFGLabel,
|
||||
srCFGCursor,
|
||||
srCFGParser,
|
||||
srConfig,
|
||||
srFlow,
|
||||
srType,
|
||||
|
@ -220,12 +221,12 @@ begin
|
|||
if (FSPI.EXP.VM<>0) and (FSPI.EXP.DONE<>0) then
|
||||
begin
|
||||
parent:=AllocBlockOp;
|
||||
parent.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
|
||||
parent.SetInfo(btOther);
|
||||
|
||||
PushBlockOp(line,parent);
|
||||
PushBlockOp(line,parent,Default(TsrCursor));
|
||||
Inc(push_count);
|
||||
|
||||
exc:=MakeRead(get_exec0,dtBool); //It means that lane_id=0
|
||||
exc:=GetThreadBit(get_exec0,get_exec1,dtBool);
|
||||
node:=AddSpirvOp(srOpInternal.OpMakeExp);
|
||||
node.AddParam(exc); //<-fetch read
|
||||
end;
|
||||
|
@ -246,9 +247,9 @@ begin
|
|||
end;
|
||||
|
||||
pOpBlock:=AllocBlockOp; //down
|
||||
pOpBlock.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
|
||||
pOpBlock.SetInfo(btOther);
|
||||
|
||||
PushBlockOp(line,pOpBlock);
|
||||
PushBlockOp(line,pOpBlock,Default(TsrCursor));
|
||||
Inc(push_count);
|
||||
|
||||
if (parent<>nil) then
|
||||
|
|
|
@ -54,9 +54,7 @@ type
|
|||
function fetch_vdst8(VDST:Word;rtype:TsrDataType):TsrRegNode;
|
||||
function fetch_vdst8_64(VDST:Word;rtype:TsrDataType):TsrRegNode;
|
||||
//
|
||||
procedure MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
|
||||
//
|
||||
procedure OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
procedure OpCmpV(OpId:DWORD;dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
procedure OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
procedure OpConvFloatToHalf2(dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
//
|
||||
|
@ -260,7 +258,7 @@ begin
|
|||
if (pImm=nil) then Exit;
|
||||
if (pImm.AsUint32<>8) then Exit;
|
||||
|
||||
reg:=RegDown(pSelect.ParamNode(2).AsReg);
|
||||
reg:=RegDown(pSelect.ParamNode(1).AsReg);
|
||||
if (reg=nil) then Exit;
|
||||
|
||||
pBitwiseAnd:=reg.pWriter.specialize AsType<ntOp>;
|
||||
|
@ -281,7 +279,7 @@ begin
|
|||
end;
|
||||
|
||||
//final
|
||||
reg:=RegDown(pSelect.ParamNode(1).AsReg);
|
||||
reg:=RegDown(pSelect.ParamNode(2).AsReg);
|
||||
if (reg=nil) then Exit;
|
||||
|
||||
regs[0]:=reg;
|
||||
|
@ -513,7 +511,6 @@ end;
|
|||
function TEmitFetch.fetch_vdst8_64(VDST:Word;rtype:TsrDataType):TsrRegNode;
|
||||
var
|
||||
src:array[0..1] of TsrRegNode;
|
||||
dst:TsrRegNode;
|
||||
begin
|
||||
src[0]:=fetch_vdst8(VDST+0,dtUint32);
|
||||
src[1]:=fetch_vdst8(VDST+1,dtUint32);
|
||||
|
@ -523,31 +520,12 @@ begin
|
|||
Assert(False);
|
||||
end;
|
||||
|
||||
dst:=NewReg(dtVec2u);
|
||||
OpMakeCon(line,dst,@src);
|
||||
|
||||
Result:=BitcastList.FetchRead(rtype,dst);
|
||||
Result:=fetch64(@src,rtype);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure TEmitFetch.MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
|
||||
var
|
||||
dst:TsrRegNode;
|
||||
node:array[0..1] of TsrRegNode;
|
||||
begin
|
||||
dst:=BitcastList.FetchRead(dtVec2u,src);
|
||||
|
||||
node[0]:=dst0^.New(dtUint32,line);
|
||||
node[1]:=dst1^.New(dtUint32,line);
|
||||
|
||||
OpExtract(line,node[0],dst,0);
|
||||
OpExtract(line,node[1],dst,1);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
Var
|
||||
tmp:TsrRegNode;
|
||||
exc:TsrRegNode;
|
||||
|
@ -565,8 +543,11 @@ begin
|
|||
|
||||
_Op2(line,OpId,tmp,src0,src1);
|
||||
|
||||
exc:=MakeRead(get_exec0,dtBool);
|
||||
OpLogicalAnd(dst,tmp,exc);
|
||||
exc:=GetThreadBit(get_exec0,get_exec1,dtBool);
|
||||
|
||||
exc:=OpLogicalAndTo(tmp,exc);
|
||||
|
||||
SetThreadBit(dst0,dst1,exc);
|
||||
end;
|
||||
|
||||
procedure TEmitFetch.OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
|
|
|
@ -12,7 +12,7 @@ uses
|
|||
srConst,
|
||||
srReg,
|
||||
srOp,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
srOpInternal,
|
||||
srOpUtils,
|
||||
srCacheOp,
|
||||
|
@ -20,6 +20,15 @@ uses
|
|||
|
||||
type
|
||||
TEmitOp=class(TEmitInterface)
|
||||
//
|
||||
procedure MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
|
||||
function GetThreadBit(exe0,exe1:PsrRegSlot;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
procedure SetThreadBit(exe0,exe1:PsrRegSlot;val:TsrRegNode);
|
||||
//
|
||||
function fetch_vccnz (ppLine:PPspirvOp):TsrRegNode;
|
||||
function fetch_execnz(ppLine:PPspirvOp):TsrRegNode;
|
||||
function fetch_execnz_tid(ppLine:PPspirvOp):TsrRegNode;
|
||||
function fetch_scc :TsrRegNode;
|
||||
//
|
||||
function _Op1(pLine:TspirvOp;OpId:DWORD;dst,src:TsrRegNode):TspirvOp;
|
||||
function _Op2(pLine:TspirvOp;OpId:DWORD;dst,src0,src1:TsrRegNode):TspirvOp;
|
||||
|
@ -73,8 +82,8 @@ type
|
|||
procedure OpFmaI32(dst:PsrRegSlot;src0,src1,src2:TsrRegNode);
|
||||
procedure OpFmaU32(dst:PsrRegSlot;src0,src1,src2:TsrRegNode);
|
||||
//
|
||||
procedure OpSelect(dst:PsrRegSlot;src_false,src_true,cond:TsrRegNode);
|
||||
function OpSelectTo(src_false,src_true,cond:TsrRegNode):TsrRegNode;
|
||||
procedure OpSelect(dst:PsrRegSlot;cond,src_true,src_false:TsrRegNode);
|
||||
function OpSelectTo(cond,src_true,src_false:TsrRegNode):TsrRegNode;
|
||||
//
|
||||
procedure OpIAddCar(pLine:TspirvOp;dst,car,src0,src1:TsrRegNode);
|
||||
procedure OpIAddExt(dst,car:PsrRegSlot;src0,src1:TsrRegNode;rtype:TsrDataType);
|
||||
|
@ -91,6 +100,7 @@ type
|
|||
//
|
||||
function OpBFITo (src0,src1,src2,src3:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpBFUETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpBFSETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
//
|
||||
procedure OpPackAnc(dst:PsrRegSlot;prim,smid,rtid:TsrRegNode);
|
||||
//
|
||||
|
@ -111,6 +121,8 @@ type
|
|||
function OpMakeCon(pLine:TspirvOp;dst:TsrRegNode;src:PPsrRegNode):TspirvOp;
|
||||
function OpMakeVec(pLine:TspirvOp;rtype:TsrDataType;src:PPsrRegNode):TsrRegNode;
|
||||
function OpMakeCub(pLine:TspirvOp;rtype:TsrDataType;src:PPsrRegNode):TsrRegNode;
|
||||
function fetch64 (src:PPsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function fetch64 (src0,src1:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegSampledImage;
|
||||
//
|
||||
procedure OpIAdd(dst:PsrRegSlot;src0,src1:TsrRegNode);
|
||||
|
@ -163,6 +175,8 @@ type
|
|||
function OpOrTo (src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpAndTo(src0:TsrRegNode;src1:QWORD;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpLogicalOrTo (src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpLogicalAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
//
|
||||
function OpIsSSignTo(src:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
function OpIEqualTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
|
@ -209,6 +223,123 @@ end;
|
|||
|
||||
//
|
||||
|
||||
procedure TEmitOp.MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
|
||||
var
|
||||
dst:TsrRegNode;
|
||||
node:array[0..1] of TsrRegNode;
|
||||
begin
|
||||
dst:=BitcastList.FetchRead(dtVec2u,src);
|
||||
|
||||
node[0]:=dst0^.New(dtUint32,line);
|
||||
node[1]:=dst1^.New(dtUint32,line);
|
||||
|
||||
OpExtract(line,node[0],dst,0);
|
||||
OpExtract(line,node[1],dst,1);
|
||||
end;
|
||||
|
||||
function TEmitOp.GetThreadBit(exe0,exe1:PsrRegSlot;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
var
|
||||
mask:TsrRegNode;
|
||||
begin
|
||||
if Config.UseExtendedEXECMask and (FExecutionModel=ExecutionModel.GLCompute) then
|
||||
begin
|
||||
mask:=fetch64(MakeRead(exe0,dtUint32),MakeRead(exe1,dtUint32),dtUint64,ppLine);
|
||||
|
||||
Result:=OpShrTo(mask,FThread_id,ppLine);
|
||||
Result:=OpUToU (Result,dtUint32,ppLine);
|
||||
Result:=OpAndTo(Result,1,ppLine);
|
||||
Result.PrepType(ord(dtUint32));
|
||||
Result:=BitcastList.FetchRead(rtype,Result);
|
||||
|
||||
//Result:=OpBFUETo(mask,FThread_id,NewImm_i(dtUint32,1));
|
||||
//Result:=OpUToU(Result,dtUint32);
|
||||
//Result:=BitcastList.FetchRead(rtype,Result);
|
||||
end else
|
||||
begin
|
||||
//It means that lane_id=0
|
||||
Result:=MakeRead(exe0,rtype);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TEmitOp.SetThreadBit(exe0,exe1:PsrRegSlot;val:TsrRegNode);
|
||||
var
|
||||
mask,mask2:TsrRegNode;
|
||||
begin
|
||||
if Config.UseExtendedEXECMask and (FExecutionModel=ExecutionModel.GLCompute) then
|
||||
begin
|
||||
|
||||
val:=BitcastList.FetchRead(dtUint32,val);
|
||||
val:=OpUToU (val,dtUint64);
|
||||
val:=OpShlTo(val,FThread_id);
|
||||
|
||||
mask:=fetch64(MakeRead(exe0,dtUint32),MakeRead(exe1,dtUint32),dtUint64);
|
||||
|
||||
mask2:=OpShlTo(NewImm_i(dtUint64,1),FThread_id);
|
||||
mask2:=OpNotTo(mask2);
|
||||
mask2.PrepType(ord(dtUint64));
|
||||
|
||||
mask:=OpAndTo(mask,mask2);
|
||||
mask.PrepType(ord(dtUint64));
|
||||
|
||||
mask:=OpOrTo(mask,val);
|
||||
mask.PrepType(ord(dtUint64));
|
||||
|
||||
MakeCopy64(exe0,exe1,mask);
|
||||
|
||||
//val:=BitcastList.FetchRead(dtUint32,val);
|
||||
//val:=OpUToU(val,dtUint64);
|
||||
//mask:=fetch64(exe0^.current,exe1^.current,dtUint64);
|
||||
//mask:=OpBFITo(mask,val,FThread_id,NewImm_i(dtUint32,1));
|
||||
//MakeCopy64(exe0,exe1,mask);
|
||||
//
|
||||
end else
|
||||
begin
|
||||
//It means that lane_id=0
|
||||
MakeCopy (exe0,val);
|
||||
SetConst_q(exe1,dtUnknow,0); //set zero
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function TEmitOp.fetch_vccnz(ppLine:PPspirvOp):TsrRegNode;
|
||||
var
|
||||
src:array[0..1] of TsrRegNode;
|
||||
begin
|
||||
//It means that (vcc0 != 0) || (vcc1 != 0)
|
||||
|
||||
src[0]:=MakeRead(get_vcc0,dtBool); //implict cast (int != 0)
|
||||
src[1]:=MakeRead(get_vcc1,dtBool); //implict cast (int != 0)
|
||||
|
||||
Result:=OpLogicalOrTo(src[0],src[1],ppLine);
|
||||
end;
|
||||
|
||||
function TEmitOp.fetch_execnz(ppLine:PPspirvOp):TsrRegNode;
|
||||
var
|
||||
src:array[0..1] of TsrRegNode;
|
||||
begin
|
||||
//It means that (exec0 != 0) || (exec1 != 0)
|
||||
|
||||
src[0]:=MakeRead(get_exec0,dtBool); //implict cast (int != 0)
|
||||
src[1]:=MakeRead(get_exec1,dtBool); //implict cast (int != 0)
|
||||
|
||||
Result:=OpLogicalOrTo(src[0],src[1],ppLine);
|
||||
end;
|
||||
|
||||
function TEmitOp.fetch_execnz_tid(ppLine:PPspirvOp):TsrRegNode;
|
||||
begin
|
||||
//It means that (exec[thread_id:] == 0)
|
||||
|
||||
Result:=GetThreadBit(get_exec0,get_exec1,dtBool,ppLine);
|
||||
end;
|
||||
|
||||
function TEmitOp.fetch_scc:TsrRegNode;
|
||||
begin
|
||||
Result:=MakeRead(get_scc,dtBool);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function TEmitOp._Op1(pLine:TspirvOp;OpId:DWORD;dst,src:TsrRegNode):TspirvOp;
|
||||
Var
|
||||
node:TspirvOp;
|
||||
|
@ -640,14 +771,14 @@ end;
|
|||
|
||||
//
|
||||
|
||||
procedure TEmitOp.OpSelect(dst:PsrRegSlot;src_false,src_true,cond:TsrRegNode);
|
||||
procedure TEmitOp.OpSelect(dst:PsrRegSlot;cond,src_true,src_false:TsrRegNode);
|
||||
begin
|
||||
Op3(Op.OpSelect,LazyType2(src_false.dtype,src_true.dtype),dst,cond,src_true,src_false);
|
||||
Op3(Op.OpSelect,LazyType2(src_true.dtype,src_false.dtype),dst,cond,src_true,src_false);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpSelectTo(src_false,src_true,cond:TsrRegNode):TsrRegNode;
|
||||
function TEmitOp.OpSelectTo(cond,src_true,src_false:TsrRegNode):TsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(LazyType2(src_false.dtype,src_true.dtype));
|
||||
Result:=NewReg(LazyType2(src_true.dtype,src_false.dtype));
|
||||
//
|
||||
_Op3(line,Op.OpSelect,Result,cond,src_true,src_false);
|
||||
end;
|
||||
|
@ -795,6 +926,12 @@ begin
|
|||
_set_line(ppLine,_Op3(_get_line(ppLine),Op.OpBitFieldUExtract,Result,src0,src1,src2));
|
||||
end;
|
||||
|
||||
function TEmitOp.OpBFSETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(src0.dtype);
|
||||
_set_line(ppLine,_Op3(_get_line(ppLine),Op.OpBitFieldSExtract,Result,src0,src1,src2));
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure TEmitOp.OpPackAnc(dst:PsrRegSlot;prim,smid,rtid:TsrRegNode);
|
||||
|
@ -1022,6 +1159,65 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
t_bridge_info=record
|
||||
val:TsrRegNode;
|
||||
pos:PtrUint;
|
||||
end;
|
||||
|
||||
function get_bridge(src:TsrRegNode):t_bridge_info;
|
||||
var
|
||||
pLine:TSpirvOp;
|
||||
begin
|
||||
Result:=Default(t_bridge_info);
|
||||
|
||||
pLine:=src.pWriter.specialize AsType<ntOp>;
|
||||
if (pLine=nil) then Exit;
|
||||
if (pLine.OpId<>Op.OpCompositeExtract) then Exit;
|
||||
|
||||
if not pLine.ParamNode(1).TryGetValue(Result.pos) then Exit;
|
||||
|
||||
Result.val:=pLine.ParamNode(0).AsReg;
|
||||
end;
|
||||
|
||||
function TEmitOp.fetch64(src:PPsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
var
|
||||
bri:array[0..1] of t_bridge_info;
|
||||
dst:TsrRegNode;
|
||||
begin
|
||||
bri[0]:=get_bridge(src[0]);
|
||||
bri[1]:=get_bridge(src[1]);
|
||||
|
||||
dst:=nil;
|
||||
|
||||
if (bri[0].val<>nil) and
|
||||
(bri[0].val=bri[1].val) and
|
||||
(bri[0].pos=0) and
|
||||
(bri[1].pos=1) then
|
||||
if (bri[0].val.dtype.Count=2) then
|
||||
begin
|
||||
dst:=bri[0].val;
|
||||
end;
|
||||
|
||||
if (dst=nil) then
|
||||
begin
|
||||
dst:=NewReg(dtVec2u);
|
||||
_set_line(ppLine,OpMakeCon(_get_line(ppLine),dst,src));
|
||||
end;
|
||||
|
||||
Result:=BitcastList.FetchRead(rtype,dst);
|
||||
end;
|
||||
|
||||
function TEmitOp.fetch64(src0,src1:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
var
|
||||
src:array[0..1] of TsrRegNode;
|
||||
begin
|
||||
src[0]:=src0;
|
||||
src[1]:=src1;
|
||||
|
||||
Result:=fetch64(@src,rtype,ppLine);
|
||||
end;
|
||||
|
||||
Function FindByHalfSpace(node:TspirvOp;pDst:TsrNode):Boolean;
|
||||
begin
|
||||
Result:=False;
|
||||
|
@ -1030,7 +1226,7 @@ begin
|
|||
if (node.pDst=pDst) then Exit(True);
|
||||
//
|
||||
if node.IsType(ntOpBlock) then
|
||||
if IsReal(TsrOpBlock(node).Block.bType) then
|
||||
if IsReal(TsrOpBlock(node).bType) then
|
||||
begin
|
||||
Exit(False);
|
||||
end;
|
||||
|
@ -1439,6 +1635,20 @@ end;
|
|||
|
||||
//
|
||||
|
||||
function TEmitOp.OpLogicalOrTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(dtBool);
|
||||
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpLogicalOr,Result,src0,src1)); //post type
|
||||
end;
|
||||
|
||||
function TEmitOp.OpLogicalAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(dtBool);
|
||||
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpLogicalAnd,Result,src0,src1)); //post type
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function TEmitOp.OpIsSSignTo(src:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
|
||||
var
|
||||
zero:TsrRegNode;
|
||||
|
|
|
@ -247,6 +247,32 @@ begin
|
|||
until false;
|
||||
end;
|
||||
|
||||
function CompareTypeOp(OpId:DWORD;rtype1,rtype2:TsrDataType):Boolean;
|
||||
var
|
||||
relax:Boolean;
|
||||
begin
|
||||
Case OpId of
|
||||
Op.OpLoad ,
|
||||
Op.OpImageRead ,
|
||||
Op.OpImageWrite ,
|
||||
Op.OpBitFieldSExtract ,
|
||||
Op.OpBitFieldUExtract ,
|
||||
Op.OpSelect ,
|
||||
Op.OpIAddCarry ,
|
||||
Op.OpISubBorrow ,
|
||||
Op.OpUMulExtended ,
|
||||
Op.OpSMulExtended ,
|
||||
Op.OpCompositeConstruct:relax:=False;
|
||||
else
|
||||
relax:=True;
|
||||
end;
|
||||
|
||||
Case relax of
|
||||
True :Result:=CompareType(rtype1,rtype2);
|
||||
False:Result:=(rtype1=rtype2);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSprvEmit_post.RegCollapse(pLine:TspirvOp;var node:TsrRegNode):Integer;
|
||||
var
|
||||
rold,rnew:TsrRegNode;
|
||||
|
@ -260,7 +286,7 @@ begin
|
|||
|
||||
if (rold<>rnew) then //is change?
|
||||
begin
|
||||
if (rnew.dtype=dtUnknow) or CompareType(rnew.dtype,rold.dtype) then
|
||||
if (rnew.dtype=dtUnknow) or CompareTypeOp(pLine.OpId,rnew.dtype,rold.dtype) then
|
||||
begin
|
||||
rnew.PrepType(ord(rold.dtype));
|
||||
if (rnew.dtype<>dtUnknow) then
|
||||
|
@ -291,6 +317,8 @@ begin
|
|||
Result:=0;
|
||||
if (node=nil) then Exit;
|
||||
|
||||
//if not (node.IsUsed) then Exit;
|
||||
|
||||
old:=node;
|
||||
|
||||
node:=RegDown(old);
|
||||
|
@ -609,6 +637,15 @@ function TSprvEmit_post.OnOpStep4(node:TspirvOp):Integer; //forward
|
|||
begin
|
||||
Result:=0;
|
||||
|
||||
{
|
||||
//prior
|
||||
if node.is_post then
|
||||
begin
|
||||
Result:=Result+EnumLineRegs(@RegVResolve,node);
|
||||
Exit;
|
||||
end;
|
||||
}
|
||||
|
||||
if node.is_cleared then Exit;
|
||||
|
||||
if node.can_clear then
|
||||
|
@ -972,6 +1009,11 @@ begin
|
|||
rtGDS:max:=64*1024;
|
||||
end;
|
||||
|
||||
if (max=0) then
|
||||
begin
|
||||
Assert(false,'Access to LDS/GDS and the maximum is 0?');
|
||||
end;
|
||||
|
||||
if (Align(_offset,pChain.stride)>max) then
|
||||
begin
|
||||
Assert(false,'LDS/GDS big addresing?');
|
||||
|
@ -1006,7 +1048,10 @@ begin
|
|||
//patch dtype
|
||||
dtype:=F.pField.Fdtype.Child;
|
||||
end;
|
||||
frValueInArray :ShiftIndex(pChain,F,_offset);
|
||||
frValueInArray :
|
||||
begin
|
||||
ShiftIndex(pChain,F,_offset);
|
||||
end;
|
||||
end;
|
||||
|
||||
until false;
|
||||
|
|
|
@ -9,7 +9,7 @@ uses
|
|||
bittype,
|
||||
Half16,
|
||||
spirv,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
srNode,
|
||||
srType,
|
||||
srTypes,
|
||||
|
@ -181,6 +181,8 @@ begin
|
|||
dtBool :Result:=dtBool;
|
||||
dtInt32,
|
||||
dtUint32:Result:=dtUint32;
|
||||
dtInt64,
|
||||
dtUint64:Result:=dtUint64;
|
||||
else
|
||||
Result:=dtUnknow;
|
||||
end;
|
||||
|
@ -196,7 +198,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -204,7 +206,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -346,7 +348,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -354,7 +356,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -482,7 +484,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -490,7 +492,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -646,7 +648,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -654,7 +656,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -710,7 +712,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -800,7 +802,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -850,7 +852,7 @@ begin
|
|||
Op.OpLabel,
|
||||
Op.OpSelectionMerge,
|
||||
Op.OpBranch,
|
||||
Op.OpBranchConditional:node.mark_not_used(True);
|
||||
Op.OpBranchConditional:node.mark([soNotUsed,soForce]);
|
||||
else;
|
||||
end;
|
||||
//
|
||||
|
@ -904,6 +906,9 @@ var
|
|||
cst :TsrConst;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
//exit;
|
||||
|
||||
src:=RegDown(node.ParamNode(0).AsReg);
|
||||
|
||||
if (src=nil) then Exit;
|
||||
|
@ -927,10 +932,10 @@ begin
|
|||
|
||||
//Get merge block
|
||||
pMerg:=pCond.Parent;
|
||||
Assert(pMerg.Block.bType=btMerg);
|
||||
Assert(pMerg.bType=btMerg);
|
||||
|
||||
//set type
|
||||
pMerg.Block.bType:=btOther;
|
||||
pMerg.bType:=btOther;
|
||||
|
||||
_restore(pCond.vctx);
|
||||
|
||||
|
@ -938,7 +943,7 @@ begin
|
|||
//PrivateList.build_volatile_ctrue(pCond.pAfter,pCond.Regs.orig,pCond.Regs.prev,pCond.Regs.next);
|
||||
|
||||
//set type
|
||||
pCond.Block.bType:=btOther;
|
||||
pCond.bType:=btOther;
|
||||
|
||||
//clear instructions
|
||||
mark_not_used_branch_op(pMerg);
|
||||
|
@ -991,7 +996,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1038,7 +1043,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1075,7 +1080,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1084,7 +1089,7 @@ var
|
|||
begin
|
||||
Assert(dtype=dtFloat32);
|
||||
dst.pWriter:=NewImm_s(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1092,7 +1097,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1240,7 +1245,7 @@ begin
|
|||
|
||||
dst.pWriter:=pc;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1294,7 +1299,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1302,7 +1307,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1381,7 +1386,7 @@ var
|
|||
begin
|
||||
Assert(dtype=dtFloat32);
|
||||
dst.pWriter:=NewImm_s(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1422,7 +1427,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1430,7 +1435,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1476,7 +1481,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1510,7 +1515,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1600,7 +1605,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1735,7 +1740,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1800,7 +1805,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1808,7 +1813,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1856,7 +1861,7 @@ begin
|
|||
|
||||
//else
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
rmax:=OpUMaxTo(src[0],src[1],@node); //update line
|
||||
|
@ -1889,7 +1894,7 @@ var
|
|||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst.pWriter:=NewImm_q(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -1897,7 +1902,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -2005,12 +2010,14 @@ begin
|
|||
|
||||
dst.pWriter:=cret;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
Inc(Result);
|
||||
end else
|
||||
begin
|
||||
src:=node.ParamNode(1).AsReg;
|
||||
|
||||
pLine:=src.pLine;
|
||||
|
||||
vint6:=NewImm_i(dtInt32,6);
|
||||
|
@ -2018,32 +2025,21 @@ begin
|
|||
Case count of
|
||||
1:
|
||||
begin
|
||||
rvec[0]:=NewReg(dtInt32);
|
||||
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
|
||||
|
||||
src:=rvec[0];
|
||||
src:=OpBFSETo(src,NewImm_i(dtInt32,0),vint6,@pLine);
|
||||
end;
|
||||
2:
|
||||
begin
|
||||
rvec[0]:=NewReg(dtInt32);
|
||||
rvec[1]:=NewReg(dtInt32);
|
||||
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[1],src,NewImm_i(dtInt32, 8),vint6);
|
||||
rvec[0]:=OpBFSETo(src,NewImm_i(dtInt32,0),vint6,@pLine);
|
||||
rvec[1]:=OpBFSETo(src,NewImm_i(dtInt32,8),vint6,@pLine);
|
||||
|
||||
src:=NewReg(dtVec2i);
|
||||
pLine:=OpMakeCon(pLine,src,@rvec);
|
||||
end;
|
||||
3:
|
||||
begin
|
||||
rvec[0]:=NewReg(dtInt32);
|
||||
rvec[1]:=NewReg(dtInt32);
|
||||
rvec[2]:=NewReg(dtInt32);
|
||||
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[1],src,NewImm_i(dtInt32, 8),vint6);
|
||||
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[2],src,NewImm_i(dtInt32,16),vint6);
|
||||
rvec[0]:=OpBFSETo(src,NewImm_i(dtInt32, 0),vint6,@pLine);
|
||||
rvec[1]:=OpBFSETo(src,NewImm_i(dtInt32, 8),vint6,@pLine);
|
||||
rvec[2]:=OpBFSETo(src,NewImm_i(dtInt32,16),vint6,@pLine);
|
||||
|
||||
src:=NewReg(dtVec3i);
|
||||
pLine:=OpMakeCon(pLine,src,@rvec);
|
||||
|
@ -2055,7 +2051,7 @@ begin
|
|||
dst.dtype :=src.dtype;
|
||||
dst.pWriter:=src;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
Inc(Result);
|
||||
|
@ -2331,7 +2327,7 @@ begin
|
|||
|
||||
dst.pWriter:=rsl;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
Exit;
|
||||
|
@ -2402,7 +2398,7 @@ begin
|
|||
Assert(False);
|
||||
end;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
end;
|
||||
|
||||
|
@ -2445,7 +2441,7 @@ begin
|
|||
|
||||
_Op4(pLine,Op.OpBitFieldInsert,dst,src[1],src[0],rIndex,rCount);
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
Exit;
|
||||
|
@ -2466,7 +2462,7 @@ begin
|
|||
|
||||
_Op2(pLine,Op.OpBitwiseOr,dst,src[0],src[1]);
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
end;
|
||||
|
||||
|
@ -2761,7 +2757,7 @@ begin
|
|||
|
||||
MakeVecComp(node,dtVec3f,dst,@src);
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Result:=1;
|
||||
end;
|
||||
|
@ -2774,7 +2770,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -2797,7 +2793,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -2820,7 +2816,7 @@ var
|
|||
procedure _SetReg(src:TsrRegNode);
|
||||
begin
|
||||
dst.pWriter:=src;
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -2843,7 +2839,7 @@ var
|
|||
begin
|
||||
Assert(dtype=dtFloat32);
|
||||
dst.pWriter:=NewImm_s(dtype,value,node);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
@ -2940,7 +2936,7 @@ begin
|
|||
|
||||
MakeVecComp(node,rtype,dst,@src);
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
end;
|
||||
|
||||
|
@ -2950,7 +2946,7 @@ begin
|
|||
|
||||
if is_term_op(flow_down_prev_up(node)) then
|
||||
begin
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
|
@ -2963,7 +2959,6 @@ var
|
|||
pChild:TsrOpBlock;
|
||||
pBegOp,pEndOp,pMrgOp:TspirvOp;
|
||||
exc:TsrRegNode;
|
||||
b_adr:TSrcAdr;
|
||||
begin
|
||||
Result:=1;
|
||||
|
||||
|
@ -2974,7 +2969,7 @@ begin
|
|||
|
||||
if exc.is_const then
|
||||
begin
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
|
||||
Case exc.AsConst.AsBool of
|
||||
True : //is always store
|
||||
|
@ -3011,7 +3006,7 @@ begin
|
|||
Op.OpNop:;
|
||||
Op.OpKill:;
|
||||
else
|
||||
node.mark_not_used(True);
|
||||
node.mark([soNotUsed,soForce]);
|
||||
end;
|
||||
end;
|
||||
node:=node.Next;
|
||||
|
@ -3024,9 +3019,7 @@ begin
|
|||
//reread
|
||||
exc:=node.ParamNode(0).AsReg;
|
||||
|
||||
node.mark_not_used;
|
||||
|
||||
b_adr:=pOpBlock.Block.b_adr;
|
||||
node.mark([soNotUsed]);
|
||||
|
||||
pLine:=node.Next;
|
||||
if (pLine=nil) then //kill or nop
|
||||
|
@ -3036,11 +3029,8 @@ begin
|
|||
pEndOp:=NewLabelOp(False); //end
|
||||
pMrgOp:=pEndOp; //merge
|
||||
|
||||
pBegOp.Adr:=b_adr;
|
||||
pEndOp.Adr:=b_adr;
|
||||
|
||||
pOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp);
|
||||
pOpBlock.Block.bType:=btCond;
|
||||
pOpBlock.bType:=btCond;
|
||||
pOpBlock.SetCond(exc,false); //reverse
|
||||
|
||||
pLine:=node;
|
||||
|
@ -3049,7 +3039,7 @@ begin
|
|||
pLine:=AddSpirvOp (pLine,pBegOp);
|
||||
|
||||
pChild:=AllocBlockOp; //create new
|
||||
pChild.SetInfo(btOther,b_adr,b_adr);
|
||||
pChild.SetInfo(btOther);
|
||||
pChild.dummy.OpId:=Op.OpKill; //set kill to dummy
|
||||
|
||||
pOpBlock.pBody:=pChild;
|
||||
|
@ -3067,15 +3057,11 @@ begin
|
|||
pEndOp:=NewLabelOp(False); //end
|
||||
pMrgOp:=NewLabelOp(False); //merge
|
||||
|
||||
pBegOp.Adr:=b_adr;
|
||||
pEndOp.Adr:=b_adr;
|
||||
pMrgOp.Adr:=b_adr;
|
||||
|
||||
pOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp);
|
||||
pOpBlock.Block.bType:=btCond;
|
||||
pOpBlock.bType:=btCond;
|
||||
pOpBlock.SetCond(exc,false); //reverse
|
||||
|
||||
pOpBlock.pElse.Block.bType:=btElse;
|
||||
pOpBlock.pElse.bType:=btElse;
|
||||
|
||||
pLine:=node;
|
||||
pLine:=OpCondMerge (pLine,pMrgOp);
|
||||
|
@ -3083,7 +3069,7 @@ begin
|
|||
pLine:=AddSpirvOp (pLine,pBegOp);
|
||||
|
||||
pChild:=AllocBlockOp; //create new
|
||||
pChild.SetInfo(btOther,b_adr,b_adr);
|
||||
pChild.SetInfo(btOther);
|
||||
pChild.dummy.OpId:=Op.OpKill; //set kill to dummy
|
||||
|
||||
pOpBlock.pBody:=pChild;
|
||||
|
@ -3124,7 +3110,7 @@ begin
|
|||
|
||||
if (src[0]=nil) or (src[1]=nil) then Exit;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
if (car.IsUsed) then //carry is use
|
||||
|
@ -3155,7 +3141,7 @@ begin
|
|||
|
||||
if (src[0]=nil) or (src[1]=nil) then Exit;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
if (bor.IsUsed) then //borrow is use
|
||||
|
@ -3186,7 +3172,7 @@ begin
|
|||
|
||||
if (src[0]=nil) or (src[0]=nil) or (src[1]=nil) then Exit;
|
||||
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed]);
|
||||
node.pDst:=nil;
|
||||
|
||||
num4 :=NewImm_q(dtUint32, 4,node);
|
||||
|
|
|
@ -29,7 +29,7 @@ type
|
|||
procedure PrintConst;
|
||||
procedure PrintVariable;
|
||||
procedure PrintFunc;
|
||||
procedure PrintOp(node:TSpirvOp;print_offset:Boolean);
|
||||
procedure PrintOp(node:TSpirvOp);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
@ -91,7 +91,7 @@ begin
|
|||
begin
|
||||
pBlock:=node.Parent;
|
||||
Write(Space(pBlock.Level));
|
||||
PrintOp(node,false);
|
||||
PrintOp(node);
|
||||
end;
|
||||
node:=flow_down_next_up(node);
|
||||
end;
|
||||
|
@ -187,7 +187,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TSprvEmit_print.PrintOp(node:TSpirvOp;print_offset:Boolean);
|
||||
procedure TSprvEmit_print.PrintOp(node:TSpirvOp);
|
||||
var
|
||||
Param:POpParamNode;
|
||||
Info:Op.TOpInfo;
|
||||
|
@ -225,15 +225,7 @@ begin
|
|||
Param:=Param.Next;
|
||||
end;
|
||||
|
||||
if (node.OpId=Op.OpLabel) then
|
||||
begin
|
||||
print_offset:=true;
|
||||
end;
|
||||
|
||||
Case print_offset of
|
||||
True :Writeln(' ;0x',HexStr(Node.Adr.Offdw*4,4){,' (',node.Order,')'});
|
||||
False:Writeln;
|
||||
end;
|
||||
Writeln;
|
||||
end;
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ uses
|
|||
sysutils,
|
||||
ps4_pssl,
|
||||
spirv,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
srFlow,
|
||||
srType,
|
||||
srConst,
|
||||
|
@ -119,6 +119,10 @@ begin
|
|||
SetConst_b(get_scc,src0.AsConst.AsBool or src1.AsConst.AsBool);
|
||||
end else
|
||||
begin
|
||||
//force type
|
||||
src0:=BitcastList.FetchRead(dtBool,src0);
|
||||
src1:=BitcastList.FetchRead(dtBool,src1);
|
||||
|
||||
OpLogicalOr(get_scc,src0,src1); //implict cast (int != 0)
|
||||
end;
|
||||
end;
|
||||
|
@ -176,16 +180,12 @@ Var
|
|||
|
||||
newptr:Pointer;
|
||||
begin
|
||||
While (CheckBlockEnd) do;
|
||||
|
||||
//ret
|
||||
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
|
||||
|
||||
newptr:=GetFuncPtr(@src);
|
||||
|
||||
set_code_ptr(newptr,btMain);
|
||||
|
||||
While (CheckBlockBeg) do;
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP1.emit_S_SWAPPC_B64;
|
||||
|
|
|
@ -73,7 +73,7 @@ begin
|
|||
a:=OpEqualTo(x,y);
|
||||
b:=OpNotEqualTo(d,x);
|
||||
|
||||
OpBitwiseAnd(car,a,b);
|
||||
OpLogicalAnd(car,a,b);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_ADD_U32;
|
||||
|
@ -118,7 +118,7 @@ begin
|
|||
a:=OpNotEqualTo(x,y);
|
||||
b:=OpNotEqualTo(d,x);
|
||||
|
||||
OpBitwiseAnd(bor,a,b);
|
||||
OpLogicalAnd(bor,a,b);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_SUB_U32;
|
||||
|
@ -207,6 +207,10 @@ begin
|
|||
SetConst_b(get_scc,src0.AsConst.AsBool or src1.AsConst.AsBool);
|
||||
end else
|
||||
begin
|
||||
//force type
|
||||
src0:=BitcastList.FetchRead(dtBool,src0);
|
||||
src1:=BitcastList.FetchRead(dtBool,src1);
|
||||
|
||||
OpLogicalOr(get_scc,src0,src1); //implict cast (int != 0)
|
||||
end;
|
||||
end;
|
||||
|
@ -431,7 +435,8 @@ begin
|
|||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUnknow);
|
||||
scc:=MakeRead(get_scc,dtBool);
|
||||
|
||||
OpSelect(dst,src[0],src[1],scc);
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,scc,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_CSELECT_B64; //sdst[2] = SCC ? ssrc0[2] : ssrc1[2]
|
||||
|
@ -447,8 +452,9 @@ begin
|
|||
|
||||
scc:=MakeRead(get_scc,dtBool);
|
||||
|
||||
OpSelect(dst[0],src0[0],src1[0],scc);
|
||||
OpSelect(dst[1],src0[1],src1[1],scc);
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst[0],scc,src0[0],src1[0]);
|
||||
OpSelect(dst[1],scc,src0[1],src1[1]);
|
||||
end;
|
||||
|
||||
//offset = ssrc1[4:0].u and 31
|
||||
|
|
|
@ -73,7 +73,7 @@ begin
|
|||
a:=OpLogicalNotTo(a);
|
||||
end;
|
||||
|
||||
OpBitwiseAnd(car,a,b);
|
||||
OpLogicalAnd(car,a,b);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPK.emit_S_MULK_I32; //sdst.s = (sdst.s * signExtend(imm16.s)) & 0xFFFFFFFF
|
||||
|
|
|
@ -8,12 +8,7 @@ uses
|
|||
sysutils,
|
||||
ps4_pssl,
|
||||
srType,
|
||||
srCFGParser,
|
||||
srCFGLabel,
|
||||
srCFGCursor,
|
||||
srFlow,
|
||||
srConst,
|
||||
srReg,
|
||||
srOp,
|
||||
srOpUtils,
|
||||
spirv,
|
||||
|
@ -22,295 +17,11 @@ uses
|
|||
type
|
||||
TEmit_SOPP=class(TEmitFetch)
|
||||
procedure emit_SOPP;
|
||||
procedure emit_S_BRANCH_COND(cond:TsrCondition;invert:Boolean);
|
||||
procedure emit_S_BRANCH;
|
||||
procedure emit_loop_branch(b_adr:TSrcAdr;pCurr:TsrOpBlock);
|
||||
function FetchCond(Adr:TSrcAdr):TsrOpBlock;
|
||||
function FetchElse(Adr:TSrcAdr):Boolean;
|
||||
function IsInLoop(Adr:TSrcAdr):Boolean;
|
||||
function IsUnknow(Adr:TSrcAdr):Boolean;
|
||||
function get_inline_end_addr(adr:TSrcAdr):TSrcAdr;
|
||||
procedure emit_block_unknow(adr:TSrcAdr);
|
||||
procedure emit_S_BARRIER;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function TEmit_SOPP.get_inline_end_addr(adr:TSrcAdr):TSrcAdr;
|
||||
var
|
||||
cInline:TsrCursor;
|
||||
begin
|
||||
cInline:=fetch_cursor_ptr(adr.get_code_ptr,btInline);
|
||||
Result :=cInline.pCode.FTop.pELabel.Adr; //get end of code
|
||||
end;
|
||||
|
||||
function _up_to_real(t:TsrOpBlock):TsrOpBlock;
|
||||
begin
|
||||
repeat
|
||||
if not t.IsType(ntOpBlock) then Break;
|
||||
if IsReal(t.Block.bType) then Break;
|
||||
t:=t.Parent;
|
||||
until false;
|
||||
Result:=t;
|
||||
end;
|
||||
|
||||
function TEmit_SOPP.FetchCond(Adr:TSrcAdr):TsrOpBlock;
|
||||
var
|
||||
pOpBlock:TsrOpBlock;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
pOpBlock:=Main.pBlock.FindUpCond;
|
||||
if (pOpBlock=nil) then Exit;
|
||||
|
||||
if (pOpBlock.Block.b_adr.get_code_ptr=Adr.get_code_ptr) then
|
||||
begin
|
||||
Result:=pOpBlock;
|
||||
end else
|
||||
begin
|
||||
//special case
|
||||
if (pOpBlock.Block.b_adr.get_code_ptr=Cursor.prev_adr.get_code_ptr) then
|
||||
if (pOpBlock.Block.e_adr.get_code_ptr=Adr.get_code_ptr) then
|
||||
begin
|
||||
Result:=pOpBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TEmit_SOPP.FetchElse(Adr:TSrcAdr):Boolean;
|
||||
var
|
||||
pOpBlock:TsrOpBlock;
|
||||
pElse :TsrOpBlock;
|
||||
begin
|
||||
Result:=False;
|
||||
|
||||
pOpBlock:=Main.pBlock.FindUpCond;
|
||||
if (pOpBlock=nil) then Exit;
|
||||
|
||||
pElse:=pOpBlock.pElse;
|
||||
if (pElse<>nil) then
|
||||
begin
|
||||
if (pElse.Block.e_adr.get_code_ptr=Adr.get_code_ptr) then
|
||||
begin
|
||||
Result:=True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TEmit_SOPP.IsInLoop(Adr:TSrcAdr):Boolean;
|
||||
var
|
||||
pOpBlock:TsrOpBlock;
|
||||
begin
|
||||
Result:=false;
|
||||
|
||||
pOpBlock:=Main.pBlock.FindUpLoop;
|
||||
if (pOpBlock=nil) then Exit(False);
|
||||
|
||||
if (pOpBlock.Block.b_adr.get_code_ptr=adr.get_code_ptr) then //is continue?
|
||||
begin
|
||||
Result:=True;
|
||||
end else
|
||||
if (pOpBlock.Block.e_adr.get_code_ptr=adr.get_code_ptr) then //is break?
|
||||
begin
|
||||
Result:=True;
|
||||
end else
|
||||
begin
|
||||
Result:=False;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TEmit_SOPP.IsUnknow(Adr:TSrcAdr):Boolean;
|
||||
var
|
||||
pLabel:TsrLabel;
|
||||
begin
|
||||
pLabel:=FindLabel(Adr);
|
||||
Assert(pLabel<>nil);
|
||||
|
||||
Result:=pLabel.IsType(ltUnknow);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPP.emit_S_BRANCH_COND(cond:TsrCondition;invert:Boolean);
|
||||
var
|
||||
c_adr,b_adr:TSrcAdr;
|
||||
pLabel:TsrLabel;
|
||||
|
||||
pCond:TsrOpBlock;
|
||||
|
||||
pBegOp,pEndOp:TspirvOp;
|
||||
|
||||
src:TsrRegNode;
|
||||
begin
|
||||
if (FSPI.SOPP.SIMM=0) then
|
||||
begin
|
||||
Exit; //skip
|
||||
end;
|
||||
|
||||
pLabel:=FindLabel(Cursor.prev_adr);
|
||||
if (pLabel<>nil) then
|
||||
begin
|
||||
if (ltGoto in pLabel.lType) then Exit;
|
||||
end;
|
||||
|
||||
While (CheckBlockBeg) do;
|
||||
|
||||
c_adr:=Cursor.Adr;
|
||||
b_adr:=c_adr;
|
||||
b_adr.Offdw:=get_branch_offset(FSPI);
|
||||
|
||||
pLabel:=FindLabel(b_adr);
|
||||
Assert(pLabel<>nil);
|
||||
|
||||
pCond:=FetchCond(c_adr);
|
||||
Assert(pCond<>nil,'Goto Unknow');
|
||||
|
||||
src:=ConvertCond(cond,pCond.vctx.Befor).pNode;
|
||||
|
||||
pBegOp:=pCond.Labels.pBegOp;
|
||||
pEndOp:=pCond.Labels.pEndOp;
|
||||
|
||||
pCond.SetCond(src,invert);
|
||||
|
||||
//OpBranchConditional
|
||||
|
||||
//The instruction specifies which block to skip, so need to invert the condition!
|
||||
//Since the main condition is this condition equal to zero, then we need to invert it again!
|
||||
Case invert of
|
||||
True: //invert of invert of invert!
|
||||
begin
|
||||
pCond.Labels.pBcnOp.AddParam(src);
|
||||
pCond.Labels.pBcnOp.AddParam(pEndOp.pDst); //True
|
||||
pCond.Labels.pBcnOp.AddParam(pBegOp.pDst); //False
|
||||
end;
|
||||
False: //invert of invert!
|
||||
begin
|
||||
pCond.Labels.pBcnOp.AddParam(src);
|
||||
pCond.Labels.pBcnOp.AddParam(pBegOp.pDst); //True
|
||||
pCond.Labels.pBcnOp.AddParam(pEndOp.pDst); //False
|
||||
end;
|
||||
end;
|
||||
|
||||
if (pCond.Block.e_adr.get_code_ptr=b_adr.get_code_ptr) then
|
||||
begin
|
||||
//if (eval) {}
|
||||
end else
|
||||
begin
|
||||
emit_loop_branch(b_adr,pCond.pBody);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPP.emit_block_unknow(adr:TSrcAdr);
|
||||
var
|
||||
pOpChild:TsrOpBlock;
|
||||
Info:TsrBlockInfo;
|
||||
begin
|
||||
Info:=Default(TsrBlockInfo);
|
||||
|
||||
Info.b_adr:=adr;
|
||||
Info.e_adr:=get_inline_end_addr(adr);
|
||||
Info.bType:=btInline;
|
||||
|
||||
//down group
|
||||
pOpChild:=AllocBlockOp;
|
||||
pOpChild.SetInfo(Info);
|
||||
PushBlockOp(line,pOpChild);
|
||||
|
||||
set_code_ptr(adr.get_code_ptr,btInline);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPP.emit_loop_branch(b_adr:TSrcAdr;pCurr:TsrOpBlock);
|
||||
var
|
||||
pOpLabel:TspirvOp;
|
||||
|
||||
pLoop:TsrOpBlock;
|
||||
|
||||
FVolMark:TsrVolMark;
|
||||
|
||||
bnew:Boolean;
|
||||
begin
|
||||
pLoop:=Main.pBlock.FindUpLoop;
|
||||
Assert(pLoop<>nil,'Goto Unknow');
|
||||
//break/continue
|
||||
|
||||
pOpLabel:=nil;
|
||||
|
||||
FVolMark:=vmNone;
|
||||
if (pLoop.Block.b_adr.get_code_ptr=b_adr.get_code_ptr) then //is continue?
|
||||
begin
|
||||
pOpLabel:=pLoop.Labels.pMrgOp; //-> OpLoopMerge end -> OpLoopMerge before
|
||||
pLoop.Cond.FUseCont:=True;
|
||||
FVolMark:=vmConti;
|
||||
end else
|
||||
if (pLoop.Block.e_adr.get_code_ptr=b_adr.get_code_ptr) then //is break?
|
||||
begin
|
||||
pOpLabel:=pLoop.Labels.pEndOp;
|
||||
FVolMark:=vmBreak;
|
||||
end else
|
||||
begin
|
||||
Assert(false,'break/continue');
|
||||
end;
|
||||
|
||||
Assert(pOpLabel<>nil);
|
||||
|
||||
bnew:=true;
|
||||
if pCurr.IsEndOf(Cursor.Adr) then //is last
|
||||
begin
|
||||
Case pCurr.Block.bType of
|
||||
btSetpc:;
|
||||
else
|
||||
begin
|
||||
bnew:=false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
//calc volatile
|
||||
case FVolMark of
|
||||
vmBreak:PrivateList.build_volatile_break(pLoop.vctx,pLoop.Regs.orig,pLoop.Regs.prev,pLoop.Regs.next);
|
||||
vmConti:PrivateList.build_volatile_conti(pLoop.vctx,pLoop.Regs.orig,pLoop.Regs.prev,pLoop.Regs.next);
|
||||
end;
|
||||
|
||||
//mark hints
|
||||
mark_end_of(FVolMark);
|
||||
|
||||
OpBranch(pCurr.line,pOpLabel);
|
||||
if bnew then
|
||||
begin
|
||||
AddSpirvOp(pCurr.line,NewLabelOp(True));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPP.emit_S_BRANCH;
|
||||
var
|
||||
pLabel:TsrLabel;
|
||||
c_adr,b_adr:TSrcAdr;
|
||||
begin
|
||||
if (FSPI.SOPP.SIMM=0) then
|
||||
begin
|
||||
Exit; //skip
|
||||
end;
|
||||
|
||||
pLabel:=FindLabel(Cursor.prev_adr);
|
||||
if (pLabel<>nil) then
|
||||
begin
|
||||
if (ltGoto in pLabel.lType) then Exit;
|
||||
end;
|
||||
|
||||
While (CheckBlockBeg) do;
|
||||
|
||||
c_adr:=Cursor.Adr;
|
||||
b_adr:=c_adr;
|
||||
b_adr.Offdw:=get_branch_offset(FSPI);
|
||||
|
||||
if FetchElse(b_adr) then
|
||||
begin
|
||||
//{} else {}
|
||||
end else
|
||||
begin
|
||||
emit_loop_branch(b_adr,Main.pBlock);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPP.emit_S_BARRIER;
|
||||
Var
|
||||
node:TspirvOp;
|
||||
|
@ -351,14 +62,14 @@ begin
|
|||
mark_end_of(vmEndpg);
|
||||
end;
|
||||
|
||||
S_CBRANCH_SCC0 :emit_S_BRANCH_COND(cScc0 ,false);
|
||||
S_CBRANCH_SCC1 :emit_S_BRANCH_COND(cScc0 ,true);
|
||||
S_CBRANCH_VCCZ :emit_S_BRANCH_COND(cVccz ,false); //It means that lane_id=0
|
||||
S_CBRANCH_VCCNZ :emit_S_BRANCH_COND(cVccz ,true); //It means that lane_id=0
|
||||
S_CBRANCH_EXECZ :emit_S_BRANCH_COND(cExecz,false); //It means that lane_id=0
|
||||
S_CBRANCH_EXECNZ:emit_S_BRANCH_COND(cExecz,true); //It means that lane_id=0
|
||||
S_CBRANCH_SCC0 :; //It means that (scc == 0)
|
||||
S_CBRANCH_SCC1 :; //It means that (scc == 1)
|
||||
S_CBRANCH_VCCZ :; //It means that (vcc0 == 0) && (vcc1 == 0)
|
||||
S_CBRANCH_VCCNZ :; //It means that (vcc0 != 0) || (vcc1 != 0)
|
||||
S_CBRANCH_EXECZ :; //It means that (exec0 == 0) && (exec1 == 0)
|
||||
S_CBRANCH_EXECNZ:; //It means that (exec0 != 0) || (exec1 != 0)
|
||||
|
||||
S_BRANCH :emit_S_BRANCH;
|
||||
S_BRANCH :;
|
||||
|
||||
S_BARRIER :emit_S_BARRIER;
|
||||
|
||||
|
|
|
@ -168,11 +168,13 @@ begin
|
|||
|
||||
cond:=OpCmpTo(Op.OpSLessThan,t3,NewImm_q(dtUint32,$38800000)); //(t3 < 0x38800000)
|
||||
|
||||
t1:=OpSelectTo(t1,NewImm_q(dtUint32,0),cond); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
|
||||
//cond,src_true,src_false
|
||||
t1:=OpSelectTo(cond,NewImm_q(dtUint32,0),t1); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
|
||||
|
||||
cond:=OpCmpTo(Op.OpSGreaterThan,t3,NewImm_q(dtUint32,$47000000)); //(t3 > 0x47000000)
|
||||
|
||||
t1:=OpSelectTo(t1,NewImm_q(dtUint32,$3FF),cond); //if (t3 > 0x47000000) t1 = 0x3FF; // Clamp-to-max
|
||||
//cond,src_true,src_false
|
||||
t1:=OpSelectTo(cond,NewImm_q(dtUint32,$3FF),t1); //if (t3 > 0x47000000) t1 = 0x3FF; // Clamp-to-max
|
||||
|
||||
Result:=t1;
|
||||
end;
|
||||
|
@ -195,11 +197,13 @@ begin
|
|||
|
||||
cond:=OpCmpTo(Op.OpSLessThan,t3,NewImm_q(dtUint32,$38800000)); //(t3 < 0x38800000)
|
||||
|
||||
t1:=OpSelectTo(t1,NewImm_q(dtUint32,0),cond); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
|
||||
//cond,src_true,src_false
|
||||
t1:=OpSelectTo(cond,NewImm_q(dtUint32,0),t1); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
|
||||
|
||||
cond:=OpCmpTo(Op.OpSGreaterThan,t3,NewImm_q(dtUint32,$87000000)); //(t3 > 0x87000000)
|
||||
|
||||
t1:=OpSelectTo(t1,NewImm_q(dtUint32,$7FF),cond); //if (t3 > 0x47000000) t1 = 0x7FF; // Clamp-to-max
|
||||
//cond,src_true,src_false
|
||||
t1:=OpSelectTo(cond,NewImm_q(dtUint32,$7FF),t1); //if (t3 > 0x47000000) t1 = 0x7FF; // Clamp-to-max
|
||||
|
||||
Result:=t1;
|
||||
end;
|
||||
|
|
|
@ -363,6 +363,9 @@ Var
|
|||
pos:TsrRegNode;
|
||||
cnd:TsrRegNode;
|
||||
begin
|
||||
// Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB)
|
||||
// position
|
||||
|
||||
dst:=get_vdst8(FSPI.VOP1.VDST);
|
||||
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUint32);
|
||||
|
||||
|
@ -371,10 +374,11 @@ begin
|
|||
|
||||
pos:=OpISubTo(NewImm_i(dtUint32,31),msb);
|
||||
|
||||
cnd:=OpIEqualTo(src,NewImm_i(dtUint32,0));
|
||||
// Select 0xFFFFFFFF if src was 0
|
||||
cnd:=OpINotEqualTo(src,NewImm_i(dtUint32,0));
|
||||
|
||||
// True, False
|
||||
OpSelect(dst,NewImm_q(dtUint32,High(DWORD)),pos,cnd);
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,cnd,pos,NewImm_q(dtUint32,High(DWORD)));
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP1.emit_V_FFBL_B32;
|
||||
|
|
|
@ -67,18 +67,19 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_CNDMASK_B32;
|
||||
procedure TEmit_VOP2.emit_V_CNDMASK_B32; //vdst = smask[thread_id:] ? vsrc1 : vsrc0
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUnknow);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUnknow);
|
||||
src[2]:=MakeRead(get_vcc0,dtBool);
|
||||
src[0]:=fetch_ssrc9 (FSPI.VOP2.SRC0 ,dtUnknow);
|
||||
src[1]:=fetch_vsrc8 (FSPI.VOP2.VSRC1,dtUnknow);
|
||||
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtBool);
|
||||
|
||||
OpSelect(dst,src[0],src[1],src[2]);
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,src[2],src[1],src[0]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_AND_B32;
|
||||
|
@ -143,7 +144,7 @@ begin
|
|||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1].PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(OpId,src[0].dtype,dst,src[0],src[1]);
|
||||
Op2(OpId,rtype,dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_ADD_I32; //vdst = vsrc0.s + vsrc1.s; sdst[thread_id:] = carry_out & EXEC
|
||||
|
@ -225,7 +226,7 @@ begin
|
|||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
|
||||
src[2]:=MakeRead(get_vcc0,dtUInt32);
|
||||
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtUInt32);
|
||||
|
||||
src[2]:=OpAndTo(src[2],1);
|
||||
src[2].PrepType(ord(dtUInt32));
|
||||
|
@ -283,7 +284,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
src[2]:=MakeRead(get_vcc0,dtUInt32);
|
||||
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtUInt32);
|
||||
|
||||
src[2]:=OpAndTo(src[2],1);
|
||||
src[2].PrepType(ord(dtUInt32));
|
||||
|
@ -360,7 +361,8 @@ begin
|
|||
mul:=NewReg(dtFloat32);
|
||||
_Op2(line,Op.OpFMul,mul,src[0],src[1]);
|
||||
|
||||
OpSelect(dst,mul,zero,cmp); //false,true,cond
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,cmp,zero,mul);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_CVT_PKRTZ_F16_F32;
|
||||
|
@ -376,29 +378,23 @@ begin
|
|||
OpConvFloatToHalf2(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_MUL_I32_I24;
|
||||
procedure TEmit_VOP2.emit_V_MUL_I32_I24; //vdst = (vsrc0[23:0].s * vsrc1[23:0].s)
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of TsrRegNode;
|
||||
bit24:TsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtInt32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtInt32);
|
||||
|
||||
bit24:=NewImm_q(dtUInt32,$FFFFFF);
|
||||
|
||||
src[0]:=OpAndTo(src[0],bit24);
|
||||
src[0].PrepType(ord(dtInt32));
|
||||
|
||||
src[1]:=OpAndTo(src[1],bit24);
|
||||
src[1].PrepType(ord(dtInt32));
|
||||
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
|
||||
OpIMul(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_MUL_U32_U24;
|
||||
procedure TEmit_VOP2.emit_V_MUL_U32_U24; //vdst = (vsrc0[23:0].u * vsrc1[23:0].u)
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of TsrRegNode;
|
||||
|
@ -457,7 +453,8 @@ begin
|
|||
|
||||
mul:=MakeRead(dst,dtFloat32);
|
||||
|
||||
OpSelect(dst,mul,zero,cmp); //false,true,cond
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,cmp,zero,mul);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_MADAK_F32; //vdst = vsrc0.f * vsrc1.f + kadd.f
|
||||
|
|
|
@ -91,14 +91,12 @@ begin
|
|||
emit_src_abs_bit(@src,2,rtype);
|
||||
emit_src_neg_bit(@src,2,rtype);
|
||||
|
||||
OpCmpV(OpId,dst[0],src[0],src[1]);
|
||||
|
||||
SetConst_q(dst[1],dtUnknow,0); //set zero
|
||||
OpCmpV(OpId,dst[0],dst[1],src[0],src[1]);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -221,7 +219,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_CNDMASK_B32;
|
||||
procedure TEmit_VOP3.emit_V_CNDMASK_B32; //vdst = smask[thread_id:] ? vsrc1 : vsrc0
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
|
@ -245,12 +243,13 @@ begin
|
|||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtBool);
|
||||
src[2]:=GetThreadBit(get_ssrc9(FSPI.VOP3a.SRC2),get_ssrc9(FSPI.VOP3a.SRC2+1),dtBool);
|
||||
|
||||
emit_src_abs_bit(@src,2,rtype);
|
||||
emit_src_neg_bit(@src,2,rtype);
|
||||
|
||||
OpSelect(dst,src[0],src[1],src[2]);
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,src[2],src[1],src[0]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MUL_LEGACY_F32;
|
||||
|
@ -276,7 +275,8 @@ begin
|
|||
mul:=NewReg(dtFloat32);
|
||||
_Op2(line,Op.OpFMul,mul,src[0],src[1]);
|
||||
|
||||
OpSelect(dst,mul,zero,cmp); //false,true,cond
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,cmp,zero,mul);
|
||||
|
||||
emit_dst_omod__f(dst,dtFloat32);
|
||||
emit_dst_clamp_f(dst,dtFloat32);
|
||||
|
@ -395,7 +395,7 @@ begin
|
|||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1].PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(OpId,src[0].dtype,dst,src[0],src[1]);
|
||||
Op2(OpId,rtype,dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MUL_LO(rtype:TsrDataType);
|
||||
|
@ -416,11 +416,10 @@ begin
|
|||
OpIMul(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MUL_I32_I24;
|
||||
procedure TEmit_VOP3.emit_V_MUL_I32_I24; //vdst = (vsrc0[23:0].s * vsrc1[23:0].s)
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of TsrRegNode;
|
||||
bit24:TsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
|
@ -432,13 +431,8 @@ begin
|
|||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32);
|
||||
|
||||
bit24:=NewImm_q(dtUInt32,$FFFFFF);
|
||||
|
||||
src[0]:=OpAndTo(src[0],bit24);
|
||||
src[0].PrepType(ord(dtInt32));
|
||||
|
||||
src[1]:=OpAndTo(src[1],bit24);
|
||||
src[1].PrepType(ord(dtInt32));
|
||||
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
|
||||
OpIMul(dst,src[0],src[1]);
|
||||
end;
|
||||
|
@ -757,14 +751,14 @@ begin
|
|||
|
||||
mul:=MakeRead(dst,dtFloat32);
|
||||
|
||||
OpSelect(dst,mul,zero,cmp); //false,true,cond
|
||||
//dst,cond,src_true,src_false
|
||||
OpSelect(dst,cmp,zero,mul);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MAD_I32_I24;
|
||||
procedure TEmit_VOP3.emit_V_MAD_I32_I24; //vdst.i = vsrc0[23:0].i * vsrc1[23:0].i + vsrc2.i
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
bit24:TsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
|
@ -777,18 +771,13 @@ begin
|
|||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtInt32);
|
||||
|
||||
bit24:=NewImm_q(dtUInt32,$FFFFFF);
|
||||
|
||||
src[0]:=OpAndTo(src[0],bit24);
|
||||
src[0].PrepType(ord(dtInt32));
|
||||
|
||||
src[1]:=OpAndTo(src[1],bit24);
|
||||
src[1].PrepType(ord(dtInt32));
|
||||
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
|
||||
|
||||
OpFmaI32(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MAD_U32_U24;
|
||||
procedure TEmit_VOP3.emit_V_MAD_U32_U24; //vdst.u = vsrc0[23:0].u * vsrc1[23:0].u + vsrc2.u
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
|
@ -821,7 +810,8 @@ procedure TEmit_VOP3.emit_V_MAD_U64_U32;
|
|||
Var
|
||||
dst:array[0..1] of PsrRegSlot;
|
||||
src:array[0..2] of TsrRegNode;
|
||||
mul,sum,car,exc:TsrRegNode;
|
||||
mul,sum,car:TsrRegNode;
|
||||
//exc:TsrRegNode;
|
||||
begin
|
||||
dst[0]:=get_vdst8(FSPI.VOP3a.VDST+0);
|
||||
dst[1]:=get_vdst8(FSPI.VOP3a.VDST+1);
|
||||
|
|
|
@ -32,14 +32,12 @@ begin
|
|||
src[0]:=fetch_ssrc9(FSPI.VOPC.SRC0 ,rtype);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOPC.VSRC1,rtype);
|
||||
|
||||
OpCmpV(OpId,dst[0],src[0],src[1]);
|
||||
|
||||
SetConst_q(dst[1],dtUnknow,0); //set zero
|
||||
OpCmpV(OpId,dst[0],dst[1],src[0],src[1]);
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<Units Count="64">
|
||||
<Units Count="63">
|
||||
<Unit0>
|
||||
<Filename Value="pssl-spirv.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
@ -250,54 +250,50 @@
|
|||
<IsPartOfProject Value="True"/>
|
||||
</Unit51>
|
||||
<Unit52>
|
||||
<Filename Value="srCFGLabel.pas"/>
|
||||
<Filename Value="srCFGParser.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit52>
|
||||
<Unit53>
|
||||
<Filename Value="srCFGParser.pas"/>
|
||||
<Filename Value="srFlow.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit53>
|
||||
<Unit54>
|
||||
<Filename Value="srFlow.pas"/>
|
||||
<Filename Value="srLiteral.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit54>
|
||||
<Unit55>
|
||||
<Filename Value="srLiteral.pas"/>
|
||||
<Filename Value="srNode.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit55>
|
||||
<Unit56>
|
||||
<Filename Value="srNode.pas"/>
|
||||
<Filename Value="srPrivate.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit56>
|
||||
<Unit57>
|
||||
<Filename Value="srPrivate.pas"/>
|
||||
<Filename Value="srType.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit57>
|
||||
<Unit58>
|
||||
<Filename Value="srType.pas"/>
|
||||
<Filename Value="srUniform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit58>
|
||||
<Unit59>
|
||||
<Filename Value="srUniform.pas"/>
|
||||
<Filename Value="srVBufInfo.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit59>
|
||||
<Unit60>
|
||||
<Filename Value="srVBufInfo.pas"/>
|
||||
<Filename Value="..\chip\ps4_pssl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit60>
|
||||
<Unit61>
|
||||
<Filename Value="..\chip\ps4_pssl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit61>
|
||||
<Unit62>
|
||||
<Filename Value="emit_ds.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="emit_DS"/>
|
||||
</Unit62>
|
||||
<Unit63>
|
||||
</Unit61>
|
||||
<Unit62>
|
||||
<Filename Value="srOpInternal.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit63>
|
||||
</Unit62>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -435,9 +435,14 @@ var
|
|||
begin
|
||||
Result:=Default(TFieldFetchValue);
|
||||
|
||||
Assert(_stride<>0);
|
||||
Assert(_size <>0);
|
||||
|
||||
_count:=_size div _stride;
|
||||
_size :=_count*_stride; //align
|
||||
|
||||
Assert(_count<>0);
|
||||
|
||||
//find intersec
|
||||
node:=FindIntersect(_offset,_size);
|
||||
|
||||
|
|
|
@ -6,27 +6,31 @@ interface
|
|||
|
||||
uses
|
||||
sysutils,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
ginodes,
|
||||
srNode;
|
||||
|
||||
type
|
||||
PsrCursor=^TsrCursor;
|
||||
TsrCursor=object(TsrLCursor)
|
||||
pCode :TsrCodeBlock;
|
||||
pBlock:TsrCFGBlock;
|
||||
procedure Init(Code:TsrCodeBlock);
|
||||
TsrCursor=object
|
||||
pCode:TsrCodeRegion;
|
||||
pNode:TsrSourceNode;
|
||||
b_adr:TSrcAdr;
|
||||
e_adr:TSrcAdr;
|
||||
fnext:Boolean;
|
||||
procedure Init(Code:TsrCodeRegion;node:TsrSourceNode;base:Pointer);
|
||||
procedure UpdateAdr;
|
||||
function AsBlock:TsrSourceBlock;
|
||||
function PopBlock:Boolean;
|
||||
end;
|
||||
|
||||
TsrCodeList=specialize TNodeQueueClass<TsrCodeBlock>;
|
||||
TsrCodeList=specialize TNodeQueueClass<TsrCodeRegion>;
|
||||
|
||||
PsrCodeHeap=^TsrCodeHeap;
|
||||
TsrCodeHeap=object(TsrCodeList)
|
||||
FEmit:TCustomEmit;
|
||||
Procedure Init(Emit:TCustomEmit);
|
||||
function FindByPtr (base:Pointer):TsrCodeBlock;
|
||||
function FindByPtr (base:Pointer):TsrCodeRegion;
|
||||
function FetchByPtr(base:Pointer;bType:TsrBlockType):TsrCursor;
|
||||
end;
|
||||
|
||||
|
@ -39,15 +43,15 @@ begin
|
|||
FEmit:=Emit;
|
||||
end;
|
||||
|
||||
function TsrCodeHeap.FindByPtr(base:Pointer):TsrCodeBlock;
|
||||
function TsrCodeHeap.FindByPtr(base:Pointer):TsrCodeRegion;
|
||||
var
|
||||
node:TsrCodeBlock;
|
||||
node:TsrCodeRegion;
|
||||
begin
|
||||
Result:=nil;
|
||||
node:=pHead;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
if node.IsContain(base) then
|
||||
if (PtrUint(node.Body)<=PtrUint(base)) and ((PtrUint(node.Body)+node.Size)>PtrUint(base)) then
|
||||
begin
|
||||
Exit(node);
|
||||
end;
|
||||
|
@ -57,53 +61,78 @@ end;
|
|||
|
||||
function TsrCodeHeap.FetchByPtr(base:Pointer;bType:TsrBlockType):TsrCursor;
|
||||
var
|
||||
pCode:TsrCodeBlock;
|
||||
adr:TSrcAdr;
|
||||
pCode:TsrCodeRegion;
|
||||
pNode:TsrSourceNode;
|
||||
p_err:Integer;
|
||||
begin
|
||||
pCode:=FindByPtr(base);
|
||||
if (pCode=nil) then
|
||||
begin
|
||||
pCode:=FEmit.specialize New<TsrCodeBlock>;
|
||||
pCode.FTop:=FEmit.specialize New<TsrCFGBlock>;
|
||||
pCode.FEmit:=FEmit;
|
||||
pCode.Body :=base;
|
||||
pCode.DMem :=FEmit.GetDmem(base);
|
||||
|
||||
//
|
||||
p_err:=parse_code_cfg(bType,pCode);
|
||||
if (pCode<>nil) then
|
||||
begin
|
||||
pNode:=pCode.FindByPtr(base);
|
||||
end else
|
||||
begin
|
||||
pNode:=nil;
|
||||
end;
|
||||
|
||||
if (pNode=nil) then
|
||||
begin
|
||||
p_err:=parse_code_cfg2(pCode,bType,base,FEmit.GetDmem(base),FEmit);
|
||||
if (p_err>1) then
|
||||
begin
|
||||
Assert(False,'parse_code_cfg:'+IntToStr(p_err));
|
||||
end;
|
||||
//
|
||||
Push_tail(pCode);
|
||||
//
|
||||
pNode:=pCode.FindByPtr(base);
|
||||
end;
|
||||
|
||||
Result:=Default(TsrCursor);
|
||||
Result.Init(pCode);
|
||||
|
||||
adr:=Default(TSrcAdr);
|
||||
adr.pCode:=TsrLabelBlock(pCode);
|
||||
adr.Offdw:=(Pointer(base)-Pointer(pCode.Body)) div 4;
|
||||
|
||||
Result.Adr:=adr;
|
||||
Result.pBlock:=Result.pBlock.WorkBlock(adr);
|
||||
Result.Init(pCode,pNode,base);
|
||||
end;
|
||||
|
||||
procedure TsrCursor.Init(Code:TsrCodeBlock);
|
||||
procedure TsrCursor.Init(Code:TsrCodeRegion;node:TsrSourceNode;base:Pointer);
|
||||
begin
|
||||
inherited Init(TsrLabelBlock(Code));
|
||||
pCode :=Code;
|
||||
pBlock:=Code.FTop;
|
||||
pCode:=Code;
|
||||
pNode:=node;
|
||||
//
|
||||
b_adr.pCode :=Code;
|
||||
b_adr.Offset:=0;
|
||||
e_adr:=b_adr;
|
||||
//
|
||||
UpdateAdr;
|
||||
//
|
||||
fnext:=(e_adr.get_code_ptr=base);
|
||||
end;
|
||||
|
||||
procedure TsrCursor.UpdateAdr;
|
||||
begin
|
||||
if (pNode<>nil) then
|
||||
begin
|
||||
if pNode.InheritsFrom(TsrSourceAdr) then
|
||||
begin
|
||||
b_adr:=TsrSourceAdr(pNode).b_adr;
|
||||
e_adr:=TsrSourceAdr(pNode).e_adr;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsrCursor.AsBlock:TsrSourceBlock;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pNode<>nil) then
|
||||
if (pNode.ntype=TsrSourceBlock) then
|
||||
begin
|
||||
Exit(TsrSourceBlock(pNode));
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsrCursor.PopBlock:Boolean;
|
||||
begin
|
||||
Result:=False;
|
||||
if (pBlock=nil) then Exit;
|
||||
if (pBlock.pParent=nil) then Exit;
|
||||
pBlock:=pBlock.pParent;
|
||||
if (pNode=nil) then Exit;
|
||||
if (pNode.pParent=nil) then Exit;
|
||||
pNode:=pNode.pParent;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
|
|
|
@ -1,358 +0,0 @@
|
|||
unit srCFGLabel;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ps4_pssl,
|
||||
ginodes,
|
||||
srNode;
|
||||
|
||||
type
|
||||
TsrLabelBlock=class;
|
||||
|
||||
PSrcAdr=^TSrcAdr;
|
||||
TSrcAdr=object
|
||||
pCode:TsrLabelBlock;
|
||||
Offdw:PtrUInt;
|
||||
function get_code_ptr:PDWORD;
|
||||
function get_dmem_ptr:PDWORD;
|
||||
end;
|
||||
|
||||
TsrLCursor=object(TShaderParser)
|
||||
private
|
||||
pCode:TsrLabelBlock;
|
||||
function get_src_adr:TSrcAdr;
|
||||
Procedure set_src_adr(src:TSrcAdr);
|
||||
public
|
||||
prev_adr:TSrcAdr;
|
||||
procedure Init(Code:TsrLabelBlock);
|
||||
property Adr:TSrcAdr read get_src_adr write set_src_adr;
|
||||
Function Next(Var SPI:TSPI):Integer;
|
||||
end;
|
||||
|
||||
TsrLabelType=(ltUnknow,
|
||||
ltGoto,
|
||||
ltContinue,
|
||||
ltBreak);
|
||||
|
||||
TsrSetLabelType=Set of TsrLabelType;
|
||||
|
||||
TsrBlockType=(btMain,btSetpc,btCond,btElse,btLoop,btMerg,btExec,btInline,btOther);
|
||||
|
||||
TsrCondition=(
|
||||
cNone,
|
||||
cFalse,
|
||||
cTrue,
|
||||
cScc0,
|
||||
cScc1,
|
||||
cVccz,
|
||||
cVccnz,
|
||||
cExecz,
|
||||
cExecnz
|
||||
);
|
||||
|
||||
const
|
||||
InvertCond:array[TsrCondition] of TsrCondition=(
|
||||
cNone, //cNone,
|
||||
cTrue, //cFalse,
|
||||
cFalse, //cTrue,
|
||||
cScc1, //cScc0,
|
||||
cScc0, //cScc1,
|
||||
cVccnz, //cVccz,
|
||||
cVccz, //cVccnz,
|
||||
cExecnz, //cExecz,
|
||||
cExecz //cExecnz
|
||||
);
|
||||
|
||||
type
|
||||
TsrLabel=class
|
||||
public
|
||||
pLeft,pRight:TsrLabel;
|
||||
private
|
||||
key:TSrcAdr;
|
||||
public
|
||||
lType:TsrSetLabelType;
|
||||
class function c(n1,n2:PSrcAdr):Integer; static;
|
||||
property Adr:TSrcAdr read key;
|
||||
Procedure AddType(t:TsrLabelType);
|
||||
Procedure RemType(t:TsrLabelType);
|
||||
function IsType (t:TsrLabelType):Boolean;
|
||||
end;
|
||||
|
||||
TsrStatementType=(
|
||||
sCond,
|
||||
sGoto,
|
||||
sVar,
|
||||
sStore,
|
||||
sLoad,
|
||||
sBreak,
|
||||
sNot,
|
||||
sOr,
|
||||
sAnd
|
||||
);
|
||||
|
||||
//sCond TsrCondition
|
||||
//sGoto [sLabel]:TsrLabel [sNext]:TsrLabel [cond]:sCond/sLoad/sNot/sOr/sAnd
|
||||
|
||||
//sVar id
|
||||
|
||||
//sStore [var]:sVar [false]:sCond/sLoad/sNot/sOr/sAnd
|
||||
//sLoad [var]:sVar
|
||||
|
||||
//sBreak
|
||||
|
||||
//sNot [cond]:sCond/sLoad/sNot/sOr
|
||||
|
||||
//sOr [cond]:sCond/sLoad/sNot/sOr/sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd
|
||||
//sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd
|
||||
|
||||
TsrStatement=class
|
||||
pPrev :TsrStatement;
|
||||
pNext :TsrStatement;
|
||||
//
|
||||
sType :TsrStatementType;
|
||||
sLabel:TsrLabel;
|
||||
sNext :TsrLabel;
|
||||
pSrc :TsrStatement;
|
||||
pDst :TsrStatement;
|
||||
//
|
||||
pCache:TObject;
|
||||
u:record
|
||||
Case Byte of
|
||||
0:(id :PtrUint);
|
||||
1:(cond:TsrCondition);
|
||||
end;
|
||||
end;
|
||||
|
||||
TsrLabels=specialize TNodeTreeClass<TsrLabel>;
|
||||
|
||||
TsrLabelBlock=class
|
||||
FEmit:TCustomEmit;
|
||||
Body:Pointer;
|
||||
DMem:Pointer;
|
||||
Size:ptruint;
|
||||
FLabels:TsrLabels;
|
||||
FVarId:Ptruint;
|
||||
Function FindLabel (Adr:TSrcAdr):TsrLabel;
|
||||
Function FetchLabel(Adr:TSrcAdr):TsrLabel;
|
||||
Function IsContain (P:Pointer):Boolean;
|
||||
//
|
||||
Function NewCond(cond:TsrCondition):TsrStatement;
|
||||
Function NewGoto(sLabel,sNext:TsrLabel;pCond:TsrStatement):TsrStatement;
|
||||
Function NewVar:TsrStatement;
|
||||
Function NewStore(pVar,pCond:TsrStatement):TsrStatement;
|
||||
Function NewLoad (pVar:TsrStatement):TsrStatement;
|
||||
Function NewBreak(sLabel:TsrLabel):TsrStatement;
|
||||
Function NewNot (pCond:TsrStatement):TsrStatement;
|
||||
Function NewOr (pCond1,pCond2:TsrStatement):TsrStatement;
|
||||
Function NewAnd (pCond1,pCond2:TsrStatement):TsrStatement;
|
||||
end;
|
||||
|
||||
function get_branch_offset(var FSPI:TSPI):ptrint;
|
||||
|
||||
function IsReal(b:TsrBlockType):Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
function IsReal(b:TsrBlockType):Boolean;
|
||||
begin
|
||||
case b of
|
||||
btMain,
|
||||
btSetpc,
|
||||
btCond,
|
||||
btElse,
|
||||
btLoop:Result:=True;
|
||||
else
|
||||
Result:=False;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSrcAdr.get_code_ptr:PDWORD;
|
||||
begin
|
||||
if (pCode=nil) then
|
||||
begin
|
||||
Result:=nil;
|
||||
end else
|
||||
begin
|
||||
Result:=PDWORD(pCode.Body);
|
||||
end;
|
||||
//
|
||||
Result:=PDWORD(Result)+Offdw;
|
||||
end;
|
||||
|
||||
function TSrcAdr.get_dmem_ptr:PDWORD;
|
||||
begin
|
||||
if (pCode=nil) then
|
||||
begin
|
||||
Result:=nil
|
||||
end else
|
||||
begin
|
||||
Result:=PDWORD(pCode.DMem);
|
||||
end;
|
||||
//
|
||||
Result:=PDWORD(Result)+Offdw;
|
||||
end;
|
||||
|
||||
|
||||
procedure TsrLCursor.Init(Code:TsrLabelBlock);
|
||||
begin
|
||||
pCode :=Code;
|
||||
Body :=Code.DMem;
|
||||
OFFSET_DW:=0;
|
||||
prev_adr :=Adr;
|
||||
end;
|
||||
|
||||
Function TsrLCursor.Next(Var SPI:TSPI):Integer;
|
||||
begin
|
||||
prev_adr:=Adr;
|
||||
Result:=inherited Next(SPI);
|
||||
end;
|
||||
|
||||
function TsrLCursor.get_src_adr:TSrcAdr;
|
||||
begin
|
||||
Result:=Default(TSrcAdr);
|
||||
Result.pCode:=pCode;
|
||||
Result.Offdw:=OFFSET_DW;
|
||||
end;
|
||||
|
||||
Procedure TsrLCursor.set_src_adr(src:TSrcAdr);
|
||||
begin
|
||||
pCode :=src.pCode;
|
||||
Body :=pCode.DMem;
|
||||
OFFSET_DW:=src.Offdw;
|
||||
end;
|
||||
|
||||
class function TsrLabel.c(n1,n2:PSrcAdr):Integer;
|
||||
var
|
||||
p1,p2:Pointer;
|
||||
begin
|
||||
p1:=n1^.get_code_ptr;
|
||||
p2:=n2^.get_code_ptr;
|
||||
Result:=ord(p1>p2)-ord(p1<p2);
|
||||
end;
|
||||
|
||||
Procedure TsrLabel.AddType(t:TsrLabelType);
|
||||
begin
|
||||
lType:=lType+[t];
|
||||
end;
|
||||
|
||||
Procedure TsrLabel.RemType(t:TsrLabelType);
|
||||
begin
|
||||
lType:=lType-[t];
|
||||
end;
|
||||
|
||||
function TsrLabel.IsType(t:TsrLabelType):Boolean;
|
||||
begin
|
||||
Result:=t in lType;
|
||||
end;
|
||||
|
||||
function get_branch_offset(var FSPI:TSPI):ptrint;
|
||||
begin
|
||||
Result:=FSPI.OFFSET_DW+Smallint(FSPI.SOPP.SIMM)+1;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.FindLabel(Adr:TSrcAdr):TsrLabel;
|
||||
begin
|
||||
Assert(Adr.pCode=self);
|
||||
Result:=FLabels.Find(@Adr);
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.FetchLabel(Adr:TSrcAdr):TsrLabel;
|
||||
begin
|
||||
Assert(Adr.pCode=self);
|
||||
Result:=nil;
|
||||
Result:=FLabels.Find(@Adr);
|
||||
if (Result=nil) then
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrLabel>;
|
||||
Result.key:=Adr;
|
||||
FLabels.Insert(Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.IsContain(P:Pointer):Boolean;
|
||||
begin
|
||||
Result:=(Body<=P) and ((Body+Size)>P);
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewCond(cond:TsrCondition):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType :=sCond;
|
||||
Result.u.cond:=cond;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewGoto(sLabel,sNext:TsrLabel;pCond:TsrStatement):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType :=sGoto;
|
||||
Result.sLabel:=sLabel;
|
||||
Result.sNext :=sNext;
|
||||
Result.pSrc :=pCond;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewVar:TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sVar;
|
||||
Result.u.id :=FVarId;
|
||||
Inc(FVarId);
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewStore(pVar,pCond:TsrStatement):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sStore;
|
||||
Result.pDst :=pVar;
|
||||
Result.pSrc :=pCond;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewLoad(pVar:TsrStatement):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sLoad;
|
||||
Result.pSrc :=pVar;
|
||||
Result.u.id :=FVarId;
|
||||
Inc(FVarId);
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewBreak(sLabel:TsrLabel):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType :=sBreak;
|
||||
Result.sLabel:=sLabel;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewNot(pCond:TsrStatement):TsrStatement;
|
||||
begin
|
||||
case pCond.sType of
|
||||
sCond:Result:=NewCond(InvertCond[pCond.u.cond]);
|
||||
else
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sNot;
|
||||
Result.pSrc :=pCond;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewOr(pCond1,pCond2:TsrStatement):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sOr;
|
||||
Result.pSrc :=pCond1;
|
||||
Result.pDst :=pCond2;
|
||||
end;
|
||||
|
||||
Function TsrLabelBlock.NewAnd(pCond1,pCond2:TsrStatement):TsrStatement;
|
||||
begin
|
||||
Result:=FEmit.specialize New<TsrStatement>;
|
||||
Result.sType:=sAnd;
|
||||
Result.pSrc :=pCond1;
|
||||
Result.pDst :=pCond2;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@ interface
|
|||
uses
|
||||
ginodes,
|
||||
srNode,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
srType,
|
||||
srReg,
|
||||
srOp;
|
||||
|
@ -51,7 +51,7 @@ function _up_to_real(t:TsrOpBlock):TsrOpBlock;
|
|||
begin
|
||||
repeat
|
||||
if not t.IsType(ntOpBlock) then Break;
|
||||
if IsReal(t.Block.bType) then Break;
|
||||
if IsReal(t.bType) then Break;
|
||||
t:=t.Parent;
|
||||
until false;
|
||||
Result:=t;
|
||||
|
|
|
@ -9,19 +9,20 @@ type
|
|||
|
||||
PsrConfig=^TsrConfig;
|
||||
TsrConfig=packed object
|
||||
PrintAsm:Boolean;
|
||||
PrintCfg:Boolean;
|
||||
UseVertexInput:Boolean; //True
|
||||
UseTexelBuffer:Boolean;
|
||||
UseOutput16:Boolean;
|
||||
PrintAsm :Boolean;
|
||||
PrintCfg :Boolean;
|
||||
UseVertexInput :Boolean; //True
|
||||
UseTexelBuffer :Boolean;
|
||||
UseOutput16 :Boolean;
|
||||
UseOnlyUserdataPushConst:Boolean;
|
||||
UseExtendedEXECMask :Boolean;
|
||||
//
|
||||
DescriptorSet:DWORD; //0
|
||||
//
|
||||
SpvVersion:PtrUint; // $10100
|
||||
maxUniformBufferRange:PtrUint; // $FFFF
|
||||
PushConstantsOffset:PtrUint; // 0
|
||||
maxPushConstantsSize:PtrUint; // 128
|
||||
SpvVersion :PtrUint; // $10100
|
||||
maxUniformBufferRange :PtrUint; // $FFFF
|
||||
PushConstantsOffset :PtrUint; // 0
|
||||
maxPushConstantsSize :PtrUint; // 128
|
||||
minStorageBufferOffsetAlignment:PtrUint; // $10
|
||||
minUniformBufferOffsetAlignment:PtrUint; // $100
|
||||
//
|
||||
|
|
|
@ -6,6 +6,7 @@ interface
|
|||
|
||||
uses
|
||||
sysutils,
|
||||
math,
|
||||
spirv,
|
||||
ginodes,
|
||||
srNode,
|
||||
|
@ -818,6 +819,7 @@ end;
|
|||
|
||||
Function TryTruncInt64(c:Single;var i:int64):Boolean;
|
||||
begin
|
||||
if IsNan(c) or IsInfinite(c) then Exit(False);
|
||||
Result:=(c>=Low(int64)) and (c<=High(int64));
|
||||
if Result then
|
||||
begin
|
||||
|
|
767
spirv/srFlow.pas
767
spirv/srFlow.pas
File diff suppressed because it is too large
Load Diff
|
@ -205,7 +205,7 @@ var
|
|||
l:TSpirvOp;
|
||||
begin
|
||||
l:=node.pReg.pWriter.specialize AsType<ntOp>;
|
||||
l.mark_not_used;
|
||||
l.mark([soNotUsed]);
|
||||
|
||||
c:=PsrConstList(FEmit.GetConstList)^.Fetch(node.pReg.dtype,0);
|
||||
node.pReg.pWriter:=c;
|
||||
|
|
|
@ -85,6 +85,8 @@ type
|
|||
FSGPRS :WORD;
|
||||
FGeometryInfo :TGeometryInfo;
|
||||
//
|
||||
FThread_id :TsrRegNode;
|
||||
//
|
||||
Config:TsrConfig;
|
||||
//
|
||||
FSPI:TSPI;
|
||||
|
@ -208,10 +210,6 @@ type
|
|||
function get_exec0:PsrRegSlot;
|
||||
function get_exec1:PsrRegSlot;
|
||||
function get_scc :PsrRegSlot;
|
||||
//
|
||||
function fetch_vccz :TsrRegNode;
|
||||
function fetch_execz:TsrRegNode;
|
||||
function fetch_scc :TsrRegNode;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
@ -503,7 +501,7 @@ function TEmitInterface.NewSpirvOp(OpId:DWORD):TSpirvOp;
|
|||
begin
|
||||
Result:=specialize New<TSpirvOp>;
|
||||
Result.Init(OpId);
|
||||
Result.adr:=Cursor.Adr;
|
||||
//Result.adr:=Cursor.Adr;
|
||||
end;
|
||||
|
||||
function TEmitInterface.NewLabelOp(sdep:Boolean):TSpirvOp;
|
||||
|
@ -558,7 +556,7 @@ begin
|
|||
|
||||
node:=AddSpirvOp(node,Op.OpNop);
|
||||
node.AddParam(dst);
|
||||
node.mark_not_used;
|
||||
node.mark([soNotUsed,soPost]);
|
||||
Exit(node);
|
||||
end;
|
||||
|
||||
|
@ -803,26 +801,6 @@ end;
|
|||
|
||||
//
|
||||
|
||||
|
||||
function TEmitInterface.fetch_vccz:TsrRegNode;
|
||||
begin
|
||||
//It means that lane_id=0
|
||||
Result:=MakeRead(get_vcc0,dtBool); //implict cast (int != 0)
|
||||
end;
|
||||
|
||||
function TEmitInterface.fetch_execz:TsrRegNode;
|
||||
begin
|
||||
//It means that lane_id=0
|
||||
Result:=MakeRead(get_exec0,dtBool); //implict cast (int != 0)
|
||||
end;
|
||||
|
||||
function TEmitInterface.fetch_scc:TsrRegNode;
|
||||
begin
|
||||
Result:=MakeRead(get_scc,dtBool);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
@ -926,7 +926,7 @@ var
|
|||
Writer:TseWriter;
|
||||
pHeap :PsrCodeHeap;
|
||||
desc :TsrDescriptor;
|
||||
block :TsrCodeBlock;
|
||||
pCode :TsrCodeRegion;
|
||||
imm :TsrDataImm;
|
||||
PV :PVSharpResource4;
|
||||
PS :PTSharpResource4;
|
||||
|
@ -1020,11 +1020,11 @@ begin
|
|||
rtFunPtr2:
|
||||
begin
|
||||
//func
|
||||
block:=pHeap^.FindByPtr(Writer.node.GetData);
|
||||
Assert(block<>nil);
|
||||
pCode:=pHeap^.FindByPtr(Writer.node.GetData);
|
||||
Assert(pCode<>nil);
|
||||
//
|
||||
Writer.HexOpt('LEN',block.Size);
|
||||
Writer.ImmOpt('IMM',block.DMem,block.Size);
|
||||
Writer.HexOpt('LEN',pCode.Size);
|
||||
Writer.ImmOpt('IMM',pCode.DMem,pCode.Size);
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
|
@ -1215,7 +1215,7 @@ begin
|
|||
if (dst<>nil) then
|
||||
begin
|
||||
old:=dst.dtype;
|
||||
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
|
||||
if (old<>dtUnknow) and (rtype<>old) then
|
||||
begin
|
||||
//OpLoad -> new -> dst
|
||||
dst:=pBitcastList^.FetchDstr(rtype,dst);
|
||||
|
|
|
@ -15,6 +15,7 @@ type
|
|||
pLeft,pRight:TDependenceNode;
|
||||
//
|
||||
key:TsrNode;
|
||||
//
|
||||
fread_count :DWORD;
|
||||
fwrite_count:DWORD;
|
||||
//
|
||||
|
|
|
@ -10,7 +10,6 @@ uses
|
|||
srOpInternal,
|
||||
ginodes,
|
||||
srNode,
|
||||
srCFGLabel,
|
||||
srCFGParser,
|
||||
srCFGCursor,
|
||||
srLiteral,
|
||||
|
@ -58,7 +57,7 @@ type
|
|||
|
||||
TsrOpList=specialize TNodeListClass<TsrOpCustom>;
|
||||
|
||||
TsoFlags=(soClear,soNotUsed,soForce);
|
||||
TsoFlags=(soClear,soNotUsed,soForce,soPost);
|
||||
TsoSetFlags=Set of TsoFlags;
|
||||
|
||||
TspirvOp=class(TsrOpCustom)
|
||||
|
@ -71,7 +70,7 @@ type
|
|||
Procedure SetDst(r:TsrNode);
|
||||
Procedure UnClear;
|
||||
public
|
||||
Adr :TSrcAdr;
|
||||
//Adr :TSrcAdr;
|
||||
OpId:DWORD;
|
||||
//
|
||||
Procedure _zero_read; override;
|
||||
|
@ -95,8 +94,9 @@ type
|
|||
procedure AddString(const name:RawByteString);
|
||||
function is_cleared:Boolean;
|
||||
function is_force:Boolean;
|
||||
function is_post:Boolean;
|
||||
function Clear:Boolean;
|
||||
procedure mark_not_used(Force:Boolean=False);
|
||||
procedure mark(f:TsoSetFlags);
|
||||
function can_clear:Boolean;
|
||||
end;
|
||||
|
||||
|
@ -104,11 +104,6 @@ type
|
|||
|
||||
TsrVolMark=(vmNone,vmEndpg,vmBreak,vmConti,vmMixed);
|
||||
|
||||
TsrBlockInfo=packed record
|
||||
b_adr,e_adr:TSrcAdr;
|
||||
bType:TsrBlockType;
|
||||
end;
|
||||
|
||||
TsrOpBlockCustom=class(TsrOpCustom)
|
||||
private
|
||||
FList :TsrOpList;
|
||||
|
@ -138,7 +133,7 @@ type
|
|||
TsrOpBlock=packed class(TsrOpBlockCustom)
|
||||
public
|
||||
|
||||
Block:TsrBlockInfo;
|
||||
bType:TsrBlockType;
|
||||
|
||||
Labels:record
|
||||
pBegOp:TspirvOp;
|
||||
|
@ -153,7 +148,6 @@ type
|
|||
|
||||
vctx :TsrVolatileContext;
|
||||
|
||||
FLBlock:TsrCFGBlock;
|
||||
FCursor:TsrCursor;
|
||||
|
||||
Regs:record
|
||||
|
@ -166,6 +160,7 @@ type
|
|||
pReg :TsrRegNode;
|
||||
FNormalOrder:Boolean;
|
||||
FUseCont :Boolean;
|
||||
FExcMerg :Boolean;
|
||||
end;
|
||||
|
||||
FVolMark:TsrVolMark;
|
||||
|
@ -173,12 +168,9 @@ type
|
|||
dummy:TspirvOp;
|
||||
|
||||
procedure Init;
|
||||
procedure SetCFGBlock(pLBlock:TsrCFGBlock);
|
||||
procedure SetInfo(const b:TsrBlockInfo);
|
||||
procedure SetInfo(bType:TsrBlockType;b_adr,e_adr:TSrcAdr);
|
||||
procedure SetInfo(_bType:TsrBlockType);
|
||||
procedure SetLabels(pBegOp,pEndOp,pMrgOp:TspirvOp);
|
||||
procedure SetCond(pReg:TsrRegNode;FNormalOrder:Boolean);
|
||||
function IsEndOf(Adr:TSrcAdr):Boolean;
|
||||
function FindUpLoop:TsrOpBlock;
|
||||
function FindUpCond:TsrOpBlock;
|
||||
function FindUpCondByReg(pReg:TsrRegNode;rDown:Boolean;var Invert:Boolean):TsrOpBlock;
|
||||
|
@ -568,12 +560,18 @@ begin
|
|||
Result:=(soForce in flags);
|
||||
end;
|
||||
|
||||
function TspirvOp.is_post:Boolean;
|
||||
begin
|
||||
Result:=(soPost in flags);
|
||||
end;
|
||||
|
||||
function TspirvOp.Clear:Boolean;
|
||||
var
|
||||
node:POpParamNode;
|
||||
b:Byte;
|
||||
begin
|
||||
Result:=False;
|
||||
|
||||
if not can_clear then Exit;
|
||||
|
||||
if (read_count<>0) then
|
||||
|
@ -650,13 +648,9 @@ begin
|
|||
flags:=flags-[soClear];
|
||||
end;
|
||||
|
||||
procedure TspirvOp.mark_not_used(Force:Boolean=False);
|
||||
procedure TspirvOp.mark(f:TsoSetFlags);
|
||||
begin
|
||||
flags:=flags+[soNotUsed];
|
||||
if Force then
|
||||
begin
|
||||
flags:=flags+[soForce];
|
||||
end;
|
||||
flags:=flags+f;
|
||||
end;
|
||||
|
||||
function TspirvOp.can_clear:Boolean;
|
||||
|
@ -680,28 +674,9 @@ begin
|
|||
vctx.block:=Self;
|
||||
end;
|
||||
|
||||
procedure TsrOpBlock.SetCFGBlock(pLBlock:TsrCFGBlock);
|
||||
procedure TsrOpBlock.SetInfo(_bType:TsrBlockType);
|
||||
begin
|
||||
dummy.Adr :=pLBlock.pBLabel.Adr;
|
||||
Block.b_adr:=pLBlock.pBLabel.Adr;
|
||||
Block.e_adr:=pLBlock.pELabel.Adr;
|
||||
Block.bType:=pLBlock.bType;
|
||||
end;
|
||||
|
||||
procedure TsrOpBlock.SetInfo(const b:TsrBlockInfo);
|
||||
begin
|
||||
dummy.Adr :=b.b_adr;
|
||||
Block.b_adr:=b.b_adr;
|
||||
Block.e_adr:=b.e_adr;
|
||||
Block.bType:=b.bType;
|
||||
end;
|
||||
|
||||
procedure TsrOpBlock.SetInfo(bType:TsrBlockType;b_adr,e_adr:TSrcAdr);
|
||||
begin
|
||||
dummy.Adr :=b_adr;
|
||||
Block.b_adr:=b_adr;
|
||||
Block.e_adr:=e_adr;
|
||||
Block.bType:=bType;
|
||||
bType:=_bType;
|
||||
end;
|
||||
|
||||
procedure TsrOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp:TspirvOp);
|
||||
|
@ -717,11 +692,6 @@ begin
|
|||
Cond.FNormalOrder:=FNormalOrder;
|
||||
end;
|
||||
|
||||
function TsrOpBlock.IsEndOf(Adr:TSrcAdr):Boolean;
|
||||
begin
|
||||
Result:=(Block.e_adr.get_code_ptr<=Adr.get_code_ptr);
|
||||
end;
|
||||
|
||||
function TsrOpBlock.FindUpLoop:TsrOpBlock;
|
||||
var
|
||||
node:TsrOpBlock;
|
||||
|
@ -730,7 +700,7 @@ begin
|
|||
node:=Self;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
if (node.Block.bType=btLoop) then Exit(node);
|
||||
if (node.bType=btLoop) then Exit(node);
|
||||
node:=node.pParent;
|
||||
end;
|
||||
end;
|
||||
|
@ -743,7 +713,7 @@ begin
|
|||
node:=Self;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
if (node.Block.bType=btCond) then Exit(node);
|
||||
if (node.bType=btCond) then Exit(node);
|
||||
node:=node.pParent;
|
||||
end;
|
||||
end;
|
||||
|
@ -763,7 +733,7 @@ begin
|
|||
node:=Self;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
if (node.Block.bType=btCond) then
|
||||
if (node.bType=btCond) then
|
||||
begin
|
||||
//
|
||||
pCond:=node.Cond.pReg;
|
||||
|
@ -777,7 +747,7 @@ begin
|
|||
Exit(node);
|
||||
end;
|
||||
end else
|
||||
if (node.Block.bType=btElse) then
|
||||
if (node.bType=btElse) then
|
||||
begin
|
||||
Assert(node.pIf<>nil);
|
||||
node:=node.pIf;
|
||||
|
|
|
@ -11,7 +11,7 @@ uses
|
|||
srReg,
|
||||
srLayout,
|
||||
srVariable,
|
||||
srCFGLabel;
|
||||
srCFGParser;
|
||||
|
||||
function InsSpirvOp(pLine,pNew:TSpirvOp):TSpirvOp;
|
||||
Function get_inverse_left_cmp_op(OpId:DWORD):DWORD;
|
||||
|
@ -79,7 +79,7 @@ function flow_prev_up(pLine:TSpirvOp):TSpirvOp;
|
|||
Result:=nil;
|
||||
if (p<>nil) then
|
||||
if p.IsType(ntOpBlock) then
|
||||
if not IsReal(TsrOpBlock(p).Block.bType) then
|
||||
if not IsReal(TsrOpBlock(p).bType) then
|
||||
begin
|
||||
Result:=p.Last;
|
||||
end;
|
||||
|
@ -114,7 +114,7 @@ begin
|
|||
tmp:=flow_down_prev_up(tmp);
|
||||
Assert(tmp<>nil);
|
||||
end;
|
||||
pNew.Adr:=tmp.Adr;
|
||||
//pNew.Adr:=tmp.Adr;
|
||||
end;
|
||||
|
||||
pLine.InsertAfter(pNew);
|
||||
|
@ -529,31 +529,101 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function GetChainRegNode(node:TsrRegNode):TsrChain;
|
||||
type
|
||||
a_volatile_node=array of TsrRegNode;
|
||||
|
||||
procedure add_node(var A:a_volatile_node;node:TsrRegNode);
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
//check exist
|
||||
if Length(A)<>0 then
|
||||
For i:=0 to High(A) do
|
||||
begin
|
||||
if (A[i]=node) then Exit;
|
||||
end;
|
||||
//
|
||||
Insert([node],A,High(A));
|
||||
end;
|
||||
|
||||
procedure add_volatile(var A:a_volatile_node;V:TsrVolatile);
|
||||
var
|
||||
node:TStoreNode;
|
||||
begin
|
||||
node:=V.FList.pHead;
|
||||
while (node<>nil) do
|
||||
begin
|
||||
add_node(A,RegDown(node.src));
|
||||
//
|
||||
node:=node.pNext;
|
||||
end;
|
||||
end;
|
||||
|
||||
function next_volatile(var A:a_volatile_node;var i:Integer):TsrRegNode;
|
||||
begin
|
||||
if (i<Length(A)) then
|
||||
begin
|
||||
Result:=A[i];
|
||||
Inc(i);
|
||||
end else
|
||||
begin
|
||||
Result:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
AsrChain=array of TsrChain;
|
||||
|
||||
function GetChainRegNode2(node:TsrRegNode):AsrChain;
|
||||
var
|
||||
pOp:TSpirvOp;
|
||||
V:TsrVolatile;
|
||||
C:TsrChain;
|
||||
A:a_volatile_node;
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
Result:=[];
|
||||
A:=[];
|
||||
i:=0;
|
||||
|
||||
repeat
|
||||
while (node<>nil) do
|
||||
begin
|
||||
node:=RegDown(node);
|
||||
|
||||
if node.pWriter.IsType(TsrVolatile) then
|
||||
begin
|
||||
V:=node.pWriter.specialize AsType<TsrVolatile>;
|
||||
node:=V.FList.pTail.src;
|
||||
end else
|
||||
begin
|
||||
Break;
|
||||
add_volatile(A,V);
|
||||
node:=next_volatile(A,i);
|
||||
end;
|
||||
until false;
|
||||
|
||||
pOp:=node.pWriter.specialize AsType<ntOp>;
|
||||
if (pOp=nil) then Exit;
|
||||
pOp:=node.pWriter.specialize AsType<ntOp>;
|
||||
if (pOp<>nil) then
|
||||
if (pOp.OpId=Op.OpLoad) then
|
||||
begin
|
||||
C:=pOp.ParamNode(0).Value.specialize AsType<ntChain>;
|
||||
|
||||
if (pOp.OpId<>Op.OpLoad) then Exit;
|
||||
Result:=pOp.ParamNode(0).Value.specialize AsType<ntChain>;
|
||||
if (C<>nil) then
|
||||
begin
|
||||
Insert([C],Result,High(Result));
|
||||
end;
|
||||
end;
|
||||
|
||||
node:=next_volatile(A,i);
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetChainRegNode(node:TsrRegNode):TsrChain;
|
||||
Var
|
||||
A:AsrChain;
|
||||
begin
|
||||
A:=GetChainRegNode2(node);
|
||||
if (Length(A)=0) then Exit(nil);
|
||||
if (Length(A)>1) then
|
||||
begin
|
||||
Assert(false,'Multiple reachable chains are not supported!');
|
||||
end;
|
||||
Result:=A[0];
|
||||
end;
|
||||
|
||||
function GetSourceRegNode(node:TsrRegNode):TsrNode;
|
||||
|
|
|
@ -18,7 +18,7 @@ uses
|
|||
srVariable,
|
||||
srConst,
|
||||
srBitcast,
|
||||
srCFGLabel;
|
||||
srCFGParser;
|
||||
|
||||
type
|
||||
TsrPrivate=class;
|
||||
|
@ -27,7 +27,7 @@ type
|
|||
pPrev,pNext:TStoreNode;
|
||||
//
|
||||
src :TsrRegNode;
|
||||
line:TspirvOp;
|
||||
//line:TspirvOp;
|
||||
//
|
||||
end;
|
||||
TStoreNodeList=specialize TNodeListClass<TStoreNode>;
|
||||
|
@ -40,11 +40,13 @@ type
|
|||
FList :TStoreNodeList;
|
||||
FBase :TsrRegNode;
|
||||
FZeroRead:Boolean;
|
||||
ForceBool:Boolean;
|
||||
//
|
||||
Procedure _zero_read; override;
|
||||
Procedure _zero_unread; override;
|
||||
Procedure _PrepType(node:PPrepTypeNode); override;
|
||||
//
|
||||
function ListCount:Integer;
|
||||
Procedure AddStore(src:TsrRegNode);
|
||||
Procedure PushStore(node:TStoreNode);
|
||||
Function PopStore:TStoreNode;
|
||||
|
@ -176,11 +178,29 @@ begin
|
|||
node:=FList.pHead;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
|
||||
if node.src.pWriter.IsType(TsrVolatile) then Break;
|
||||
|
||||
node.src.PrepType(ord(new));
|
||||
node:=node.pNext;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsrVolatile.ListCount:Integer;
|
||||
var
|
||||
node:TStoreNode;
|
||||
begin
|
||||
Result:=0;
|
||||
//
|
||||
node:=FList.pHead;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
Inc(Result);
|
||||
//
|
||||
node:=node.pNext;
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure TsrVolatile.AddStore(src:TsrRegNode);
|
||||
var
|
||||
node:TStoreNode;
|
||||
|
@ -198,7 +218,7 @@ begin
|
|||
Assert(pLine<>nil);
|
||||
node:=Emit.specialize New<TStoreNode>; //cache in free list?
|
||||
node.src :=src;
|
||||
node.line:=pLine;
|
||||
//node.line:=pLine;
|
||||
if FZeroRead then
|
||||
begin
|
||||
src.mark_read(Self);
|
||||
|
@ -209,8 +229,8 @@ end;
|
|||
Procedure TsrVolatile.PushStore(node:TStoreNode);
|
||||
begin
|
||||
if (node=nil) then Exit;
|
||||
Assert(node.src.pLine<>nil);
|
||||
Assert(node.line<>nil);
|
||||
//Assert(node.src.pLine<>nil);
|
||||
//Assert(node.line<>nil);
|
||||
if FZeroRead then
|
||||
begin
|
||||
node.src.mark_read(Self);
|
||||
|
@ -343,7 +363,7 @@ begin
|
|||
if (dst<>nil) then
|
||||
begin
|
||||
old:=dst.dtype;
|
||||
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
|
||||
if (old<>dtUnknow) and (rtype<>old) then
|
||||
begin
|
||||
//OpLoad -> new -> dst
|
||||
dst:=pBitcastList^.FetchDstr(rtype,dst);
|
||||
|
@ -406,6 +426,8 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
|
||||
{
|
||||
procedure _update_store_line(pLine:TspirvOp);
|
||||
var
|
||||
pReg:TsrRegNode;
|
||||
|
@ -422,13 +444,22 @@ begin
|
|||
pCur.InsertAfter(pLine);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
|
||||
Procedure TsrPrivate.SortLines;
|
||||
var
|
||||
dnode,dnext:TDependenceNode;
|
||||
pLine:array[0..1] of TspirvOp;
|
||||
//pLine:array[0..1] of TspirvOp;
|
||||
nswp:Boolean;
|
||||
begin
|
||||
//indexing
|
||||
dnode:=FLineList.pHead;
|
||||
While (dnode<>nil) do
|
||||
begin
|
||||
dnode.fread_count:=GetGlobalIndex(dnode.pNode);
|
||||
dnode:=dnode.pNext;
|
||||
end;
|
||||
//bubble sort
|
||||
repeat
|
||||
nswp:=True;
|
||||
dnode:=FLineList.pHead;
|
||||
|
@ -437,13 +468,14 @@ begin
|
|||
dnext:=dnode.pNext;
|
||||
if (dnext=nil) then Break;
|
||||
|
||||
pLine[0]:=dnode.pNode;
|
||||
pLine[1]:=dnext.pNode;
|
||||
//pLine[0]:=dnode.pNode;
|
||||
//pLine[1]:=dnext.pNode;
|
||||
|
||||
_update_store_line(pLine[0]);
|
||||
_update_store_line(pLine[1]);
|
||||
//_update_store_line(pLine[0]);
|
||||
//_update_store_line(pLine[1]);
|
||||
|
||||
if (MaxLine(pLine[0],pLine[1])=pLine[0]) then //dnode>dnext
|
||||
//if (MaxLine(pLine[0],pLine[1])=pLine[0]) then //dnode>dnext
|
||||
if (dnode.fread_count>dnext.fread_count) then
|
||||
begin
|
||||
//swap
|
||||
nswp:=False;
|
||||
|
@ -466,7 +498,7 @@ begin
|
|||
if (node=prev) then Exit(True);
|
||||
//
|
||||
if node.IsType(ntOpBlock) then
|
||||
if IsReal(TsrOpBlock(node).Block.bType) then
|
||||
if IsReal(TsrOpBlock(node).bType) then
|
||||
begin
|
||||
Exit(False);
|
||||
end;
|
||||
|
@ -501,7 +533,7 @@ begin
|
|||
begin
|
||||
//Remove dprev
|
||||
FLineList.Remove(dprev);
|
||||
pLine[1].mark_not_used;
|
||||
pLine[1].mark([soNotUsed]);
|
||||
Continue;
|
||||
end else
|
||||
if (pLine[0].OpId=Op.OpStore) and (pLine[1].OpId=Op.OpLoad) then
|
||||
|
@ -516,7 +548,7 @@ begin
|
|||
begin
|
||||
//Remove dnode
|
||||
FLineList.Remove(dnode);
|
||||
pLine[0].mark_not_used;
|
||||
pLine[0].mark([soNotUsed]);
|
||||
|
||||
dnode:=dprev;
|
||||
if (dnode.pNext<>nil) then
|
||||
|
@ -745,7 +777,7 @@ begin
|
|||
pLine:=ctx.after;
|
||||
|
||||
//replace next
|
||||
_next:=pSlot^.New(rtype,pLine);
|
||||
_next:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
|
||||
_next.pWriter:=pVolatile;
|
||||
|
||||
ctx.AddVolatile(pVolatile,_next);
|
||||
|
@ -827,7 +859,7 @@ begin
|
|||
pLine:=ctx.after;
|
||||
|
||||
//replace next
|
||||
_next:=pSlot^.New(rtype,pLine);
|
||||
_next:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
|
||||
_next.pWriter:=pVolatile;
|
||||
|
||||
ctx.AddVolatile(pVolatile,_next);
|
||||
|
@ -916,6 +948,24 @@ begin
|
|||
|
||||
rtype:=dtUnknow;
|
||||
|
||||
|
||||
if (prv<>nil) then
|
||||
begin
|
||||
if new_vol then
|
||||
begin
|
||||
|
||||
Assert(prv.pWriter=orig,'123');
|
||||
|
||||
//need to use orig to create a loopback dependency
|
||||
prv:=orig;
|
||||
|
||||
//save if new created
|
||||
pVolatile.AddStore(prv);
|
||||
end;
|
||||
rtype:=LazyType2(rtype,prv.dtype);
|
||||
end;
|
||||
|
||||
{
|
||||
if new_vol then
|
||||
begin
|
||||
//use orig
|
||||
|
@ -933,6 +983,7 @@ begin
|
|||
rtype:=LazyType2(rtype,prv.dtype);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
//
|
||||
if (cur<>nil) then
|
||||
begin
|
||||
|
@ -949,7 +1000,7 @@ begin
|
|||
if (prev=nil) then
|
||||
begin
|
||||
//The input register is not defined, should it be initialized to make_copy_slot?
|
||||
prev:=pSlot^.New(rtype,pLine);
|
||||
prev:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
|
||||
end;
|
||||
|
||||
//set backedge dependence
|
||||
|
@ -1075,6 +1126,56 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function calc_most_used_type(V:TsrVolatile):TsrDataType;
|
||||
type
|
||||
t_table=array[TsrDataType] of Integer;
|
||||
var
|
||||
node :TStoreNode;
|
||||
Table:t_table;
|
||||
Count:Integer;
|
||||
i,max:TsrDataType;
|
||||
begin
|
||||
if V.ForceBool then
|
||||
begin
|
||||
Exit(dtBool);
|
||||
end;
|
||||
//
|
||||
Table:=Default(t_table);
|
||||
Count:=0;
|
||||
//
|
||||
node:=V.FList.pHead;
|
||||
While (node<>nil) do
|
||||
begin
|
||||
Inc(Table[RegDown(node.src).dtype]);
|
||||
Inc(Count);
|
||||
//
|
||||
node:=node.pNext;
|
||||
end;
|
||||
//
|
||||
if (Count=0) then
|
||||
begin
|
||||
Result:=dtUnknow;
|
||||
end else
|
||||
if (Count=Table[dtBool]) then
|
||||
begin
|
||||
//Result:=dtBool;
|
||||
Result:=dtUint32;
|
||||
end else
|
||||
begin
|
||||
max:=dtUnknow;
|
||||
For i:=Low(TsrDataType) to High(TsrDataType) do
|
||||
if (i<>dtBool) then
|
||||
begin
|
||||
if ((max=dtUnknow) and (Table[i]<>0)) or
|
||||
(Table[i]>Table[max]) then
|
||||
begin
|
||||
max:=i;
|
||||
end;
|
||||
end;
|
||||
Result:=max;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsrPrivateList.PrepVolatile(dst:TspirvOp;src:TsrRegNode):TsrRegNode; //use forward only
|
||||
var
|
||||
tmp:TsrRegNode;
|
||||
|
@ -1084,6 +1185,7 @@ var
|
|||
pLine:TspirvOp;
|
||||
//pTmp:TspirvOp;
|
||||
//vtmp:TsrVolatile;
|
||||
dtype:TsrDataType;
|
||||
begin
|
||||
Result:=src;
|
||||
if (src=nil) then Exit;
|
||||
|
@ -1098,18 +1200,42 @@ begin
|
|||
|
||||
pVolatile:=src.pWriter.specialize AsType<ntVolatile>;
|
||||
|
||||
pPrivate:=pVolatile.FPrivate;
|
||||
if pVolatile.FSlot^.iUnattach then
|
||||
begin
|
||||
pPrivate:=pVolatile.FPrivate;
|
||||
end else
|
||||
begin
|
||||
pPrivate:=TsrPrivate(pVolatile.FSlot^.FPrivate);
|
||||
end;
|
||||
|
||||
if (pPrivate=nil) then
|
||||
begin
|
||||
pPrivate:=Fetch(pVolatile.FSlot);
|
||||
pVolatile.FPrivate:=pPrivate;
|
||||
|
||||
if pVolatile.FSlot^.iUnattach then
|
||||
begin
|
||||
pVolatile.FPrivate:=pPrivate;
|
||||
end else
|
||||
begin
|
||||
pVolatile.FSlot^.FPrivate:=pPrivate;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
dtype:=calc_most_used_type(pVolatile);
|
||||
dtype:=lazyType2(dtype,StoreType(src.dtype));
|
||||
dtype:=lazyType2(dtype,dtFloat32);
|
||||
|
||||
if (dtype=dtBool) and (pVolatile.FSlot^.Name='S0') then
|
||||
begin
|
||||
calc_most_used_type(pVolatile);
|
||||
end;
|
||||
|
||||
pPrivate.InitVar();
|
||||
|
||||
pPrivate .PrepType(src.dtype);
|
||||
pVolatile.PrepType(pPrivate.GetRegType);
|
||||
pPrivate .PrepType(dtype);
|
||||
|
||||
pVolatile.PrepType(dtype);
|
||||
|
||||
if (pPrivate.GetRegType=dtUnknow) then
|
||||
begin
|
||||
|
@ -1126,7 +1252,8 @@ begin
|
|||
begin
|
||||
|
||||
//pLine:=TsrRegNode(node.pNode).pLine;
|
||||
pLine:=node.line;
|
||||
//pLine:=node.line;
|
||||
pLine:=node.src.pLine;
|
||||
Assert(pLine<>nil);
|
||||
|
||||
up_merge_line(pLine);
|
||||
|
@ -1156,7 +1283,7 @@ begin
|
|||
//ntVolatile -> src -> next
|
||||
//Opload -> new
|
||||
|
||||
Result:=src.pSlot^.New(src.dtype,dst);
|
||||
Result:=src.pSlot^._New(src.dtype,dst); //<-The slot value will not be updated
|
||||
|
||||
pPrivate.FetchLoad(dst,Result); //before reg
|
||||
end;
|
||||
|
|
|
@ -124,6 +124,7 @@ type
|
|||
FBits :TsrBitKey;
|
||||
procedure set_current(c:TsrRegNode);
|
||||
public
|
||||
FPrivate:TsrNode;
|
||||
property Emit :TCustomEmit read FEmit;
|
||||
property current :TsrRegNode read FCurrent write set_current;
|
||||
property Name :TString7 read FName;
|
||||
|
@ -137,6 +138,7 @@ type
|
|||
function isBoolOnly:Boolean;
|
||||
function isScalar:Boolean;
|
||||
function iUnattach:Boolean;
|
||||
function _New(rtype:TsrDataType;pLine:TsrRegNode):TsrRegNode;
|
||||
function New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
|
||||
end;
|
||||
|
||||
|
@ -1046,7 +1048,7 @@ begin
|
|||
Result:=(FBits.Category=cUnattach);
|
||||
end;
|
||||
|
||||
function TsrRegSlot.New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
|
||||
function TsrRegSlot._New(rtype:TsrDataType;pLine:TsrRegNode):TsrRegNode;
|
||||
var
|
||||
node:TsrRegNode;
|
||||
begin
|
||||
|
@ -1059,8 +1061,13 @@ begin
|
|||
node.dtype:=rtype;
|
||||
node.CustomLine:=pLine;
|
||||
Result:=node;
|
||||
end;
|
||||
|
||||
function TsrRegSlot.New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
|
||||
begin
|
||||
Result:=_New(rtype,pLine);
|
||||
//update
|
||||
current:=node;
|
||||
current:=Result;
|
||||
end;
|
||||
|
||||
//
|
||||
|
|
|
@ -166,16 +166,17 @@ begin
|
|||
yxEqual:=SprvEmit.OpAndTo(CoordEqualY[i], CoordEqualX[(i + 2) mod 3]);
|
||||
//
|
||||
EdgeVertex[i]:=SprvEmit.OpOrTo(xyEqual,yxEqual);
|
||||
//
|
||||
barycentric[i]:=SprvEmit.OpSelectTo(pOneId,pMinusOne,EdgeVertex[i]);
|
||||
//cond,src_true,src_false
|
||||
barycentric[i]:=SprvEmit.OpSelectTo(EdgeVertex[i],pMinusOne,pOneId);
|
||||
end;
|
||||
|
||||
//calc last pos
|
||||
Positions[3]:=interpolate(SprvEmit,dtVec4f,@barycentric,@Positions);
|
||||
|
||||
//select first index
|
||||
pIndex:=SprvEmit.OpSelectTo(UintId[0], UintId[1], EdgeVertex[1]);
|
||||
pIndex:=SprvEmit.OpSelectTo(pIndex , UintId[2], EdgeVertex[2]);
|
||||
//cond,src_true,src_false
|
||||
pIndex:=SprvEmit.OpSelectTo(EdgeVertex[1], UintId[1], UintId[0]);
|
||||
pIndex:=SprvEmit.OpSelectTo(EdgeVertex[2], UintId[2], pIndex );
|
||||
|
||||
//Send vertex by index
|
||||
For i:=0 to 2 do
|
||||
|
|
Loading…
Reference in New Issue