shader: Rename, implement FADD.SAT and P2R (imm)

This commit is contained in:
ReinUsesLisp 2021-02-21 17:50:14 -03:00 committed by ameerj
parent e2bc05b17d
commit 704c6f353f
18 changed files with 213 additions and 127 deletions

View file

@ -7,10 +7,39 @@
namespace Shader::Backend::SPIRV {
Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) {
if (inst->HasAssociatedPseudoOperation()) {
throw NotImplementedException("Pseudo-operations on IAdd32");
Id result{};
if (IR::Inst* const carry{inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp)}) {
const Id carry_type{ctx.TypeStruct(ctx.U32[1], ctx.U32[1])};
const Id carry_result{ctx.OpIAddCarry(carry_type, a, b)};
result = ctx.OpCompositeExtract(ctx.U32[1], carry_result, 0U);
const Id carry_value{ctx.OpCompositeExtract(ctx.U32[1], carry_result, 1U)};
carry->SetDefinition(ctx.OpINotEqual(ctx.U1, carry_value, ctx.u32_zero_value));
carry->Invalidate();
} else {
result = ctx.OpIAdd(ctx.U32[1], a, b);
}
return ctx.OpIAdd(ctx.U32[1], a, b);
if (IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}) {
zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value));
zero->Invalidate();
}
if (IR::Inst* const sign{inst->GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}) {
sign->SetDefinition(ctx.OpSLessThan(ctx.U1, result, ctx.u32_zero_value));
sign->Invalidate();
}
if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) {
// https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c
constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())};
const Id is_positive{ctx.OpSGreaterThanEqual(ctx.U1, a, ctx.u32_zero_value)};
const Id sub_a{ctx.OpISub(ctx.U32[1], ctx.Constant(ctx.U32[1], s32_max), a)};
const Id positive_test{ctx.OpSGreaterThan(ctx.U1, b, sub_a)};
const Id negative_test{ctx.OpSLessThan(ctx.U1, b, sub_a)};
const Id carry_flag{ctx.OpSelect(ctx.U1, is_positive, positive_test, negative_test)};
overflow->SetDefinition(carry_flag);
overflow->Invalidate();
}
return result;
}
void EmitIAdd64(EmitContext&) {
@ -49,16 +78,16 @@ void EmitShiftRightArithmetic32(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
void EmitBitwiseAnd32(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) {
return ctx.OpBitwiseAnd(ctx.U32[1], a, b);
}
void EmitBitwiseOr32(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b) {
return ctx.OpBitwiseOr(ctx.U32[1], a, b);
}
void EmitBitwiseXor32(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b) {
return ctx.OpBitwiseXor(ctx.U32[1], a, b);
}
void EmitBitFieldInsert(EmitContext&) {
@ -77,36 +106,36 @@ Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpSLessThan(ctx.U1, lhs, rhs);
}
void EmitULessThan(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpULessThan(ctx.U1, lhs, rhs);
}
void EmitIEqual(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpIEqual(ctx.U1, lhs, rhs);
}
void EmitSLessThanEqual(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitSLessThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpSLessThanEqual(ctx.U1, lhs, rhs);
}
void EmitULessThanEqual(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitULessThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpULessThanEqual(ctx.U1, lhs, rhs);
}
Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpSGreaterThan(ctx.U1, lhs, rhs);
}
void EmitUGreaterThan(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpUGreaterThan(ctx.U1, lhs, rhs);
}
void EmitINotEqual(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpINotEqual(ctx.U1, lhs, rhs);
}
void EmitSGreaterThanEqual(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
return ctx.OpSGreaterThanEqual(ctx.U1, lhs, rhs);
}
Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) {