fpPS4/spirv/srBitcast.pas

199 lines
3.8 KiB
ObjectPascal
Raw Permalink Normal View History

2022-05-31 07:17:14 +00:00
unit srBitcast;
{$mode ObjFPC}{$H+}
interface
uses
2022-09-05 13:30:24 +00:00
ginodes,
srNode,
srType,
srConst,
srReg;
2022-05-31 07:17:14 +00:00
type
PsrBitcast=^TsrBitcast;
TsrBitcast=object
pLeft,pRight:PsrBitcast;
//----
key:packed record
dtype:TsrDataType;
src:PsrRegNode;
end;
dst:PsrRegNode;
function c(n1,n2:PsrBitcast):Integer; static;
end;
2022-09-05 13:30:24 +00:00
PsrBitcastList=^TsrBitcastList;
2022-05-31 07:17:14 +00:00
TsrBitcastList=object
type
TNodeFetch=specialize TNodeFetch<PsrBitcast,TsrBitcast>;
var
FNTree:TNodeFetch;
2022-09-05 13:30:24 +00:00
rSlot:TsrRegSlot;
procedure Init(Emit:TCustomEmit); inline;
2023-01-09 12:16:08 +00:00
function _Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
function Find(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
Procedure Save(dtype:TsrDataType;src,dst:PsrRegNode);
2022-09-05 13:30:24 +00:00
function FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
2022-05-31 07:17:14 +00:00
end;
implementation
function TsrBitcast.c(n1,n2:PsrBitcast):Integer;
begin
2022-09-05 13:30:24 +00:00
//first dtype
Result:=Integer(n1^.key.dtype>n2^.key.dtype)-Integer(n1^.key.dtype<n2^.key.dtype);
if (Result<>0) then Exit;
//second src
Result:=Integer(n1^.key.src>n2^.key.src)-Integer(n1^.key.src<n2^.key.src);
end;
procedure TsrBitcastList.Init(Emit:TCustomEmit); inline;
begin
rSlot.Init(Emit,'BCAST');
2022-05-31 07:17:14 +00:00
end;
2023-01-09 12:16:08 +00:00
function TsrBitcastList._Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
2022-05-31 07:17:14 +00:00
var
node:TsrBitcast;
begin
node:=Default(TsrBitcast);
node.key.dtype:=dtype;
node.key.src:=src;
Result:=FNTree.Find(@node);
end;
2023-01-09 12:16:08 +00:00
function TsrBitcastList.Find(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
node:PsrBitcast;
begin
Result:=nil;
node:=_Find(dtype,src);
if (node<>nil) then
begin
Result:=node^.dst;
end;
end;
Procedure TsrBitcastList.Save(dtype:TsrDataType;src,dst:PsrRegNode);
var
node:PsrBitcast;
begin
node:=rSlot.Emit.Alloc(SizeOf(TsrBitcast));
node^:=Default(TsrBitcast);
node^.key.dtype:=dtype;
node^.key.src:=src;
node^.dst:=dst;
FNTree.Insert(node);
end;
2022-05-31 07:17:14 +00:00
function TsrBitcastList.FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
2023-01-09 12:16:08 +00:00
pConstList:PsrConstList;
2022-05-31 07:17:14 +00:00
dst:PsrRegNode;
2023-01-09 12:16:08 +00:00
pConst:PsrConst;
2022-05-31 07:17:14 +00:00
begin
Result:=src;
if (src=nil) then Exit;
2022-09-05 13:30:24 +00:00
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
2022-05-31 07:17:14 +00:00
2023-11-09 18:39:56 +00:00
Assert(TryBitcastType(src^.dtype,dtype));
2023-01-09 12:16:08 +00:00
if src^.is_const then
begin
//only from consts, first
dst:=Find(dtype,src);
if (dst<>nil) then Exit(dst);
pConst:=src^.AsConst;
pConstList:=rSlot.Emit.GetConstList;
pConst:=pConstList^.Bitcast(dtype,pConst);
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=pConst;
//
Save(dtype,src,dst);
end else
begin
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=src;
end;
2022-05-31 07:17:14 +00:00
Result:=dst;
end;
2022-09-05 13:30:24 +00:00
function TsrBitcastList.FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
dst:PsrRegNode;
2022-05-31 07:17:14 +00:00
begin
Result:=src;
if (src=nil) then Exit;
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
2023-11-09 18:39:56 +00:00
Assert(TryBitcastType(src^.dtype,dtype));
2022-09-05 13:30:24 +00:00
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=src^.pWriter;
src^.pWriter:=dst;
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
Result:=dst;
2022-05-31 07:17:14 +00:00
end;
function TsrBitcastList.FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
2022-09-05 13:30:24 +00:00
pConstList:PsrConstList;
2022-05-31 07:17:14 +00:00
dst:PsrRegNode;
2022-07-15 10:12:45 +00:00
pConst:PsrConst;
2022-05-31 07:17:14 +00:00
begin
Result:=src;
if (src=nil) then Exit;
2022-09-05 13:30:24 +00:00
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
2022-05-31 07:17:14 +00:00
dst:=nil;
2023-11-09 18:39:56 +00:00
Assert(TryBitcastType(src^.dtype,dtype));
2023-01-09 12:16:08 +00:00
//
dst:=Find(dtype,src);
if (dst<>nil) then Exit(dst);
2022-05-31 07:17:14 +00:00
if src^.is_const then
begin
2022-07-15 10:12:45 +00:00
pConst:=src^.AsConst;
2022-09-05 13:30:24 +00:00
2022-11-05 14:48:13 +00:00
pConstList:=rSlot.Emit.GetConstList;
2022-09-05 13:30:24 +00:00
pConst:=pConstList^.Bitcast(dtype,pConst);
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=pConst;
2022-05-31 07:17:14 +00:00
end else
begin
if TryBitcastType(src^.dtype,dtype) then
begin
2022-09-05 13:30:24 +00:00
dst:=rSlot.New(src^.pLine,dtype);
2022-11-05 14:48:13 +00:00
rSlot.Emit.OpCast(src^.pLine,dst,src)
2022-05-31 07:17:14 +00:00
end else
begin
2023-11-09 18:39:56 +00:00
Writeln('bitcast:',src^.dtype,'<>',dtype);
2022-05-31 07:17:14 +00:00
Assert(false,'bitcast');
end;
end;
2023-01-09 12:16:08 +00:00
//
Save(dtype,src,dst);
2022-05-31 07:17:14 +00:00
Result:=dst;
end;
end.