blob: fdc8704f14063f8cbe385f73fb467acd48d7d4a0 [file] [log] [blame]
// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "SpirvShader.hpp"
#include "spirv-tools/libspirv.h"
#include <spirv/unified1/spirv.hpp>
namespace sw {
const char *Spirv::OpcodeName(spv::Op opcode)
{
return spvOpcodeString(opcode);
}
// This function is used by the shader debugger to determine whether an instruction is steppable.
bool Spirv::IsStatement(spv::Op opcode)
{
switch(opcode)
{
default:
// Most statement-like instructions produce a result which has a type.
// Note OpType* instructions have a result but it is a type itself.
{
bool hasResult = false;
bool hasResultType = false;
spv::HasResultAndType(opcode, &hasResult, &hasResultType);
return hasResult && hasResultType;
}
break;
// Instructions without a result but potential side-effects.
case spv::OpNop:
case spv::OpStore:
case spv::OpCopyMemory:
case spv::OpCopyMemorySized:
case spv::OpImageWrite:
case spv::OpEmitVertex:
case spv::OpEndPrimitive:
case spv::OpEmitStreamVertex:
case spv::OpEndStreamPrimitive:
case spv::OpControlBarrier:
case spv::OpMemoryBarrier:
case spv::OpAtomicStore:
case spv::OpBranch:
case spv::OpBranchConditional:
case spv::OpSwitch:
case spv::OpKill:
case spv::OpReturn:
case spv::OpReturnValue:
case spv::OpLifetimeStart:
case spv::OpLifetimeStop:
case spv::OpGroupWaitEvents:
case spv::OpCommitReadPipe:
case spv::OpCommitWritePipe:
case spv::OpGroupCommitReadPipe:
case spv::OpGroupCommitWritePipe:
case spv::OpRetainEvent:
case spv::OpReleaseEvent:
case spv::OpSetUserEventStatus:
case spv::OpCaptureEventProfilingInfo:
case spv::OpAtomicFlagClear:
case spv::OpMemoryNamedBarrier:
case spv::OpTerminateInvocation:
case spv::OpTraceRayKHR:
case spv::OpExecuteCallableKHR:
case spv::OpIgnoreIntersectionKHR:
case spv::OpTerminateRayKHR:
case spv::OpRayQueryInitializeKHR:
case spv::OpRayQueryTerminateKHR:
case spv::OpRayQueryGenerateIntersectionKHR:
case spv::OpRayQueryConfirmIntersectionKHR:
case spv::OpBeginInvocationInterlockEXT:
case spv::OpEndInvocationInterlockEXT:
case spv::OpDemoteToHelperInvocationEXT:
case spv::OpAssumeTrueKHR:
return true;
}
}
bool Spirv::IsTerminator(spv::Op opcode)
{
switch(opcode)
{
// Branch instructions
case spv::OpBranch:
case spv::OpBranchConditional:
case spv::OpSwitch:
// Function termination instructions
case spv::OpReturn:
case spv::OpReturnValue:
case spv::OpKill:
case spv::OpUnreachable:
case spv::OpTerminateInvocation:
return true;
default:
return false;
}
}
} // namespace sw