unit emit_print; {$mode objfpc}{$H+} interface uses sysutils, spirv, srNode, srType, srTypes, srConst, srVariable, srOp, srOpInternal, srOpUtils, strutils, srCapability, emit_fetch; type TSprvEmit_print=class(TEmitFetch) procedure Print; procedure PrintCaps; procedure PrintOpBlock(pBlock:TsrOpBlock); procedure PrintHeaderInfo; procedure PrintTypes; procedure PrintConst; procedure PrintVariable; procedure PrintFunc; procedure PrintOp(node:TSpirvOp); end; implementation const PadAssign=0; //5 procedure TSprvEmit_print.Print; begin PrintCaps; Writeln; PrintHeaderInfo; PrintTypes; Writeln; PrintConst; PrintVariable; PrintFunc; end; function GetNodeStr(Node:TsrNode):RawByteString; var name:RawByteString; begin Assert(Node<>nil,'GetNodeStr$1'); name:=node.GetPrintName; if (name<>'') then begin Result:='%'+name; end else begin name:=node.GetPrintData; Assert(name<>'','GetNodeStr$2'); Result:=name; end; end; procedure TSprvEmit_print.PrintCaps; var node:TsrCapability; begin node:=CapabilityList.First; While (node<>nil) do begin Writeln(Op.GetStr(Op.OpCapability),' ',Capability.GetStr(node.ID)); node:=CapabilityList.Next(node); end; end; procedure TSprvEmit_print.PrintOpBlock(pBlock:TsrOpBlock); var node:TSpirvOp; begin if (pBlock=nil) then Exit; node:=pBlock.First; While (node<>nil) do begin if node.IsType(ntOp) then begin pBlock:=node.Parent; Write(Space(pBlock.Level)); PrintOp(node); end; node:=flow_down_next_up(node); end; end; procedure TSprvEmit_print.PrintHeaderInfo; begin PrintOpBlock(HeaderList); if (HeaderList.First<>nil) then Writeln; PrintOpBlock(DebugInfoList); if (DebugInfoList.First<>nil) then Writeln; PrintOpBlock(DecorateList); if (DecorateList.First<>nil) then Writeln; end; procedure TSprvEmit_print.PrintTypes; var node:TsrType; i:Word; begin node:=TypeList.First; While (node<>nil) do begin Write(PadRight(GetNodeStr(node),PadAssign),' = ',Op.GetStr(node.OpId)); if (node.ItemCount<>0) then begin For i:=0 to node.ItemCount-1 do begin Write(' ',GetNodeStr(node.GetItem(i))); end; end; Writeln; node:=node.Next; end; end; procedure TSprvEmit_print.PrintConst; var node:TsrConst; i:Word; begin node:=ConstList.First; While (node<>nil) do begin if (node.dtype=dtUnknow) then begin Write('; '); Writeln(' = dtUnknow: read_count=',node.read_count,' value=',node.GetData); end else begin Write(PadRight(GetNodeStr(node),PadAssign),' = ',Op.GetStr(node.OpId),' ',GetNodeStr(node.pType)); if (node.dtype<>dtBool) then begin For i:=0 to node.ItemCount-1 do begin Write(' ',GetNodeStr(node.GetItem(i))); end; end; Writeln; end; node:=node.Next; end; if (ConstList.First<>nil) then Writeln; end; procedure TSprvEmit_print.PrintVariable; var node:TsrVariable; begin node:=VariableList.First; While (node<>nil) do begin if (node.pType<>nil) then begin Writeln(PadRight(GetNodeStr(node),PadAssign),' = ',Op.GetStr(Op.OpVariable), ' ',GetNodeStr(node.pType), ' ',StorageClass.GetStr(node.GetStorageClass)); end; node:=node.Next; end; end; procedure TSprvEmit_print.PrintFunc; var pFunc:TSpirvFunc; begin pFunc:=FuncList.First; While (pFunc<>nil) do begin Writeln; PrintOpBlock(pFunc.pTop); pFunc:=pFunc.Next; end; end; procedure TSprvEmit_print.PrintOp(node:TSpirvOp); var Param:POpParamNode; Info:Op.TOpInfo; begin if (node=nil) then Exit; Info:=Op.GetInfo(node.OpId); if Info.result then //dst begin Assert(node.pDst<>nil,'PrintOp$1'); Write(PadRight(GetNodeStr(node.pDst),PadAssign),' = ',OpGetStrInternal(node.OpId)); end else begin //no dst Write(OpGetStrInternal(node.OpId)); if (node.pDst<>nil) then begin Write(' ',GetNodeStr(node.pDst)); end; end; if Info.rstype then //dst type begin Assert(node.pType<>nil,'PrintOp$2'); if (node.pType<>nil) then begin Write(' ',GetNodeStr(node.pType)); end; end; Param:=node.ParamFirst; While (Param<>nil) do begin Write(' ',GetNodeStr(Param.Value)); Param:=Param.Next; end; Writeln; end; end.