unit emit_SOPP;

{$mode objfpc}{$H+}

interface

uses
  sysutils,
  ps4_pssl,
  srType,
  srConst,
  srOp,
  srOpUtils,
  spirv,
  emit_fetch;

type
 TEmit_SOPP=class(TEmitFetch)
  procedure emit_SOPP;
  procedure emit_S_BARRIER;
 end;

implementation

procedure TEmit_SOPP.emit_S_BARRIER;
Var
 node:TspirvOp;
 execution,memory,memory_semantics:TsrConst;
begin
 //upgrade version to 1.3
 Config.UpgradeVersion($10300);

 node:=AddSpirvOp(line,Op.OpControlBarrier); //need first

 execution       :=ConstList.Fetch(dtUint32,Scope.Workgroup);
 memory          :=ConstList.Fetch(dtUint32,Scope.Workgroup);
 memory_semantics:=ConstList.Fetch(dtUint32,MemorySemantics.AcquireRelease or MemorySemantics.WorkgroupMemory);

 node.AddParam(execution);
 node.AddParam(memory);
 node.AddParam(memory_semantics);
end;

procedure TEmit_SOPP.emit_SOPP;
begin
 Case FSPI.SOPP.OP of
  S_NOP,
  S_WAITCNT:;

  S_TTRACEDATA:; //write_thread_trace_data(M0[31:0])

  S_ENDPGM:
   begin
    if not is_term_op(line) then
    begin
     AddSpirvOp(Op.OpReturn);
    end;
    //mark hints
    mark_end_of(vmEndpg);
   end;

  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        :;

  S_BARRIER       :emit_S_BARRIER;

  else
   Assert(false,'SOPP?'+IntToStr(FSPI.SOPP.OP)+' '+get_str_spi(FSPI));
 end;
end;

end.

