// Copyright 2019 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/unified1/spirv.hpp>

namespace sw {

struct SpirvShader::GroupOps {

	// Template function to perform a binary operation.
	// |TYPE| should be the type of the identity value (as an SIMD::<Type>).
	// |APPLY| should be a callable object that takes two RValue<TYPE> parameters
	// and returns a new RValue<TYPE> corresponding to the operation's result.
	template <typename TYPE, typename APPLY>
	static void BinaryOperation(
		const SpirvShader*               shader,
		const SpirvShader::InsnIterator& insn,
		const SpirvShader::EmitState*    state,
		Intermediate&                    dst,
		const TYPE&                      identity,
		APPLY&&                          apply)
	{
		SpirvShader::GenericValue value(shader, state, insn.word(5));
		auto &type = shader->getType(SpirvShader::Type::ID(insn.word(1)));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			auto mask = As<SIMD::UInt>(state->activeLaneMask());
			SIMD::UInt v_uint = (value.UInt(i) & mask) | (As<SIMD::UInt>(identity) & ~mask);
			TYPE v = As<TYPE>(v_uint);
			switch (spv::GroupOperation(insn.word(4)))
			{
			case spv::GroupOperationReduce:
			{
				// NOTE: floating-point add and multiply are not really commutative so
				//       ensure that all values in the final lanes are identical
				TYPE v2 = apply(v.xxzz,  v.yyww);   // [xy]   [xy]   [zw]   [zw]
				TYPE v3 = apply(v2.xxxx, v2.zzzz);  // [xyzw] [xyzw] [xyzw] [xyzw]
				dst.move(i, v3);
				break;
			}
			case spv::GroupOperationInclusiveScan:
			{
				TYPE v2 = apply(v,  Shuffle(v, identity, 0x4012) /* [id, v.y, v.z, v.w] */);    // [x] [xy] [yz]  [zw]
				TYPE v3 = apply(v2, Shuffle(v2, identity, 0x4401) /* [id,  id, v2.x, v2.y] */); // [x] [xy] [xyz] [xyzw]
				dst.move(i, v3);
				break;
			}
			case spv::GroupOperationExclusiveScan:
			{
				TYPE v2 = apply(v,  Shuffle(v, identity, 0x4012) /* [id, v.y, v.z, v.w] */);    // [x] [xy] [yz]  [zw]
				TYPE v3 = apply(v2, Shuffle(v2, identity, 0x4401) /* [id,  id, v2.x, v2.y] */); // [x] [xy] [xyz] [xyzw]
				auto v4 = Shuffle(v3, identity, 0x4012 /* [id, v3.x, v3.y, v3.z] */);           // [i] [x]  [xy]  [xyz]
				dst.move(i, v4);
				break;
			}
			default:
				UNIMPLEMENTED("EmitGroupNonUniform op: %s Group operation: %d",
								SpirvShader::OpcodeName(type.opcode()).c_str(), insn.word(4));
			}
		}
	}

};


SpirvShader::EmitResult SpirvShader::EmitGroupNonUniform(InsnIterator insn, EmitState *state) const
{
	static_assert(SIMD::Width == 4, "EmitGroupNonUniform makes many assumptions that the SIMD vector width is 4");

	auto &type = getType(Type::ID(insn.word(1)));
	Object::ID resultId = insn.word(2);
	auto scope = spv::Scope(GetConstScalarInt(insn.word(3)));
	ASSERT_MSG(scope == spv::ScopeSubgroup, "Scope for Non Uniform Group Operations must be Subgroup for Vulkan 1.1");

	auto &dst = state->createIntermediate(resultId, type.sizeInComponents);

	switch (insn.opcode())
	{
	case spv::OpGroupNonUniformElect:
	{
		// Result is true only in the active invocation with the lowest id
		// in the group, otherwise result is false.
		SIMD::Int active = state->activeLaneMask();
		// TODO: Would be nice if we could write this as:
		//   elect = active & ~(active.Oxyz | active.OOxy | active.OOOx)
		auto v0111 = SIMD::Int(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
		auto elect = active & ~(v0111 & (active.xxyz | active.xxxy | active.xxxx));
		dst.move(0, elect);
		break;
	}

	case spv::OpGroupNonUniformAll:
	{
		GenericValue predicate(this, state, insn.word(4));
		dst.move(0, AndAll(predicate.UInt(0) | ~As<SIMD::UInt>(state->activeLaneMask())));
		break;
	}

	case spv::OpGroupNonUniformAny:
	{
		GenericValue predicate(this, state, insn.word(4));
		dst.move(0, OrAll(predicate.UInt(0) & As<SIMD::UInt>(state->activeLaneMask())));
		break;
	}

	case spv::OpGroupNonUniformAllEqual:
	{
		GenericValue value(this, state, insn.word(4));
		auto res = SIMD::UInt(0xffffffff);
		SIMD::UInt active = As<SIMD::UInt>(state->activeLaneMask());
		SIMD::UInt inactive = ~active;
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			SIMD::UInt v = value.UInt(i) & active;
			SIMD::UInt filled = v;
			for (int j = 0; j < SIMD::Width - 1; j++)
			{
				filled |= filled.yzwx & inactive; // Populate inactive 'holes' with a live value
			}
			res &= AndAll(CmpEQ(filled.xyzw, filled.yzwx));
		}
		dst.move(0, res);
		break;
	}

	case spv::OpGroupNonUniformBroadcast:
	{
		auto valueId = Object::ID(insn.word(4));
		auto id = SIMD::Int(GetConstScalarInt(insn.word(5)));
		GenericValue value(this, state, valueId);
		auto mask = CmpEQ(id, SIMD::Int(0, 1, 2, 3));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			dst.move(i, OrAll(value.Int(i) & mask));
		}
		break;
	}

	case spv::OpGroupNonUniformBroadcastFirst:
	{
		auto valueId = Object::ID(insn.word(4));
		GenericValue value(this, state, valueId);
		// Result is true only in the active invocation with the lowest id
		// in the group, otherwise result is false.
		SIMD::Int active = state->activeLaneMask();
		// TODO: Would be nice if we could write this as:
		//   elect = active & ~(active.Oxyz | active.OOxy | active.OOOx)
		auto v0111 = SIMD::Int(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
		auto elect = active & ~(v0111 & (active.xxyz | active.xxxy | active.xxxx));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			dst.move(i, OrAll(value.Int(i) & elect));
		}
		break;
	}

	case spv::OpGroupNonUniformBallot:
	{
		ASSERT(type.sizeInComponents == 4);
		GenericValue predicate(this, state, insn.word(4));
		dst.move(0, SIMD::Int(SignMask(state->activeLaneMask() & predicate.Int(0))));
		dst.move(1, SIMD::Int(0));
		dst.move(2, SIMD::Int(0));
		dst.move(3, SIMD::Int(0));
		break;
	}

	case spv::OpGroupNonUniformInverseBallot:
	{
		auto valueId = Object::ID(insn.word(4));
		ASSERT(type.sizeInComponents == 1);
		ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
		GenericValue value(this, state, valueId);
		auto bit = (value.Int(0) >> SIMD::Int(0, 1, 2, 3)) & SIMD::Int(1);
		dst.move(0, -bit);
		break;
	}

	case spv::OpGroupNonUniformBallotBitExtract:
	{
		auto valueId = Object::ID(insn.word(4));
		auto indexId = Object::ID(insn.word(5));
		ASSERT(type.sizeInComponents == 1);
		ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
		ASSERT(getType(getObject(indexId).type).sizeInComponents == 1);
		GenericValue value(this, state, valueId);
		GenericValue index(this, state, indexId);
		auto vecIdx = index.Int(0) / SIMD::Int(32);
		auto bitIdx = index.Int(0) & SIMD::Int(31);
		auto bits =	(value.Int(0) & CmpEQ(vecIdx, SIMD::Int(0))) |
					(value.Int(1) & CmpEQ(vecIdx, SIMD::Int(1))) |
					(value.Int(2) & CmpEQ(vecIdx, SIMD::Int(2))) |
					(value.Int(3) & CmpEQ(vecIdx, SIMD::Int(3)));
		dst.move(0, -((bits >> bitIdx) & SIMD::Int(1)));
		break;
	}

	case spv::OpGroupNonUniformBallotBitCount:
	{
		auto operation = spv::GroupOperation(insn.word(4));
		auto valueId = Object::ID(insn.word(5));
		ASSERT(type.sizeInComponents == 1);
		ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
		GenericValue value(this, state, valueId);
		switch (operation)
		{
		case spv::GroupOperationReduce:
			dst.move(0, CountBits(value.UInt(0) & SIMD::UInt(15)));
			break;
		case spv::GroupOperationInclusiveScan:
			dst.move(0, CountBits(value.UInt(0) & SIMD::UInt(1, 3, 7, 15)));
			break;
		case spv::GroupOperationExclusiveScan:
			dst.move(0, CountBits(value.UInt(0) & SIMD::UInt(0, 1, 3, 7)));
			break;
		default:
			UNSUPPORTED("GroupOperation %d", int(operation));
		}
		break;
	}

	case spv::OpGroupNonUniformBallotFindLSB:
	{
		auto valueId = Object::ID(insn.word(4));
		ASSERT(type.sizeInComponents == 1);
		ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
		GenericValue value(this, state, valueId);
		dst.move(0, Cttz(value.UInt(0) & SIMD::UInt(15), true));
		break;
	}

	case spv::OpGroupNonUniformBallotFindMSB:
	{
		auto valueId = Object::ID(insn.word(4));
		ASSERT(type.sizeInComponents == 1);
		ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
		GenericValue value(this, state, valueId);
		dst.move(0, SIMD::UInt(31) - Ctlz(value.UInt(0) & SIMD::UInt(15), false));
		break;
	}

	case spv::OpGroupNonUniformShuffle:
	{
		GenericValue value(this, state, insn.word(4));
		GenericValue id(this, state, insn.word(5));
		auto x = CmpEQ(SIMD::Int(0), id.Int(0));
		auto y = CmpEQ(SIMD::Int(1), id.Int(0));
		auto z = CmpEQ(SIMD::Int(2), id.Int(0));
		auto w = CmpEQ(SIMD::Int(3), id.Int(0));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			SIMD::Int v = value.Int(i);
			dst.move(i, (x & v.xxxx) | (y & v.yyyy) | (z & v.zzzz) | (w & v.wwww));
		}
		break;
	}

	case spv::OpGroupNonUniformShuffleXor:
	{
		GenericValue value(this, state, insn.word(4));
		GenericValue mask(this, state, insn.word(5));
		auto x = CmpEQ(SIMD::Int(0), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
		auto y = CmpEQ(SIMD::Int(1), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
		auto z = CmpEQ(SIMD::Int(2), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
		auto w = CmpEQ(SIMD::Int(3), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			SIMD::Int v = value.Int(i);
			dst.move(i, (x & v.xxxx) | (y & v.yyyy) | (z & v.zzzz) | (w & v.wwww));
		}
		break;
	}

	case spv::OpGroupNonUniformShuffleUp:
	{
		GenericValue value(this, state, insn.word(4));
		GenericValue delta(this, state, insn.word(5));
		auto d0 = CmpEQ(SIMD::Int(0), delta.Int(0));
		auto d1 = CmpEQ(SIMD::Int(1), delta.Int(0));
		auto d2 = CmpEQ(SIMD::Int(2), delta.Int(0));
		auto d3 = CmpEQ(SIMD::Int(3), delta.Int(0));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			SIMD::Int v = value.Int(i);
			dst.move(i, (d0 & v.xyzw) | (d1 & v.xxyz) | (d2 & v.xxxy) | (d3 & v.xxxx));
		}
		break;
	}

	case spv::OpGroupNonUniformShuffleDown:
	{
		GenericValue value(this, state, insn.word(4));
		GenericValue delta(this, state, insn.word(5));
		auto d0 = CmpEQ(SIMD::Int(0), delta.Int(0));
		auto d1 = CmpEQ(SIMD::Int(1), delta.Int(0));
		auto d2 = CmpEQ(SIMD::Int(2), delta.Int(0));
		auto d3 = CmpEQ(SIMD::Int(3), delta.Int(0));
		for (auto i = 0u; i < type.sizeInComponents; i++)
		{
			SIMD::Int v = value.Int(i);
			dst.move(i, (d0 & v.xyzw) | (d1 & v.yzww) | (d2 & v.zwww) | (d3 & v.wwww));
		}
		break;
	}

	case spv::OpGroupNonUniformIAdd:
	{
		using Type = SIMD::Int;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){ return a + b; }
		);
		break;
	}

	case spv::OpGroupNonUniformFAdd:
	{
		using Type = SIMD::Float;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0.),
				[](RValue<Type>a, RValue<Type>b){ return a + b; }
		);
		break;
	}

	case spv::OpGroupNonUniformIMul:
	{
		using Type = SIMD::Int;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(1),
				[](RValue<Type>a, RValue<Type>b){ return a * b; }
		);
		break;
	}

	case spv::OpGroupNonUniformFMul:
	{
		using Type = SIMD::Float;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(1.),
				[](RValue<Type>a, RValue<Type>b){ return a * b; }
		);
		break;
	}

	case spv::OpGroupNonUniformBitwiseAnd:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(~0u),
				[](RValue<Type>a, RValue<Type>b){ return a & b; }
		);
		break;
	}

	case spv::OpGroupNonUniformBitwiseOr:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){ return a | b; }
		);
		break;
	}

	case spv::OpGroupNonUniformBitwiseXor:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){ return a ^ b; }
		);
		break;
	}

	case spv::OpGroupNonUniformSMin:
	{
		using Type = SIMD::Int;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(INT32_MAX),
				[](RValue<Type>a, RValue<Type>b){ return Min(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformUMin:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(~0u),
				[](RValue<Type>a, RValue<Type>b){ return Min(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformFMin:
	{
		using Type = SIMD::Float;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type::positive_inf(),
				[](RValue<Type>a, RValue<Type>b){ return NMin(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformSMax:
	{
		using Type = SIMD::Int;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(INT32_MIN),
				[](RValue<Type>a, RValue<Type>b){ return Max(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformUMax:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){ return Max(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformFMax:
	{
		using Type = SIMD::Float;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type::negative_inf(),
				[](RValue<Type>a, RValue<Type>b){ return NMax(a, b); }
		);
		break;
	}

	case spv::OpGroupNonUniformLogicalAnd:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(~0u),
				[](RValue<Type>a, RValue<Type>b){
					SIMD::UInt zero = SIMD::UInt(0);
					return CmpNEQ(a, zero) & CmpNEQ(b, zero);
				}
		);
		break;
	}

	case spv::OpGroupNonUniformLogicalOr:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){
					SIMD::UInt zero = SIMD::UInt(0);
					return CmpNEQ(a, zero) | CmpNEQ(b, zero);
				}
		);
		break;
	}

	case spv::OpGroupNonUniformLogicalXor:
	{
		using Type = SIMD::UInt;
		SpirvShader::GroupOps::BinaryOperation(
				this, insn, state, dst,
				Type(0),
				[](RValue<Type>a, RValue<Type>b){
					SIMD::UInt zero = SIMD::UInt(0);
					return CmpNEQ(a, zero) ^ CmpNEQ(b, zero);
				}
		);
		break;
	}

	default:
		UNIMPLEMENTED("EmitGroupNonUniform op: %s", OpcodeName(type.opcode()).c_str());
	}
	return EmitResult::Continue;
}

}  // namespace sw
