unit emit_print; {$mode objfpc}{$H+} interface uses sysutils, spirv, srNode, srType, srTypes, srConst, srVariable, srOp, srOpUtils, srCapability, emit_fetch; type TSprvEmit_print=class(TEmitFetch) procedure Print; procedure PrintCaps; procedure PrintOpBlock(pBlock:PsrOpBlock); procedure PrintHeaderInfo; procedure PrintTypes; procedure PrintConst; procedure PrintVariable; procedure PrintFunc; procedure PrintOp(node:PSpirvOp;print_offset:Boolean); end; implementation procedure TSprvEmit_print.Print; begin PrintCaps; Writeln; PrintHeaderInfo; PrintTypes; Writeln; PrintConst; PrintVariable; PrintFunc; end; procedure PrintNode(Node:PsrNode); var name:RawByteString; begin Assert(Node<>nil,'PrintNode$1'); name:=node^.GetPrintName; if (name<>'') then begin Write('%',name); end else begin name:=node^.GetPrintData; Assert(name<>'','PrintNode$2'); Write(name); end; end; procedure TSprvEmit_print.PrintCaps; var node:PsrCapability; 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:PsrOpBlock); var node:PSpirvOp; 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,false); 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:PsrType; i:Word; begin node:=TypeList.First; While (node<>nil) do begin PrintNode(node); Write(' = ',Op.GetStr(node^.OpId)); if (node^.ItemCount<>0) then begin For i:=0 to node^.ItemCount-1 do begin Write(' '); PrintNode(node^.GetItem(i)); end; end; Writeln; node:=node^.Next; end; end; procedure TSprvEmit_print.PrintConst; var node:PsrConst; 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 PrintNode(node); Write(' = ',Op.GetStr(node^.OpId),' '); PrintNode(node^.pType); if (node^.dtype<>dtBool) then begin For i:=0 to node^.ItemCount-1 do begin Write(' '); PrintNode(node^.GetItem(i)); end; end; Writeln; end; node:=node^.Next; end; if (ConstList.First<>nil) then Writeln; end; procedure TSprvEmit_print.PrintVariable; var node:PsrVariable; begin node:=VariableList.First; While (node<>nil) do begin if (node^.pType<>nil) then begin PrintNode(node); Write(' = ',Op.GetStr(Op.OpVariable),' '); PrintNode(node^.pType); Writeln(' ',StorageClass.GetStr(node^.GetStorageClass)); end; node:=node^.Next; end; end; procedure TSprvEmit_print.PrintFunc; var pFunc:PSpirvFunc; begin pFunc:=FuncList.First; While (pFunc<>nil) do begin Writeln; PrintOpBlock(pFunc^.pTop); pFunc:=pFunc^.Next; end; end; procedure TSprvEmit_print.PrintOp(node:PSpirvOp;print_offset:Boolean); 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'); if (node^.pDst<>nil) then begin PrintNode(node^.pDst); end; Write(' = '); Write(Op.GetStr(node^.OpId)); end else begin //no dst Write(Op.GetStr(node^.OpId)); if (node^.pDst<>nil) then begin Write(' '); PrintNode(node^.pDst); end; end; if Info.rstype then //dst type begin Assert(node^.pType<>nil,'PrintOp$2'); Write(' '); if (node^.pType<>nil) then begin PrintNode(node^.pType); end; end; Param:=node^.ParamFirst; While (Param<>nil) do begin Write(' '); PrintNode(Param^.Value); 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)); False:Writeln; end; end; end.