shader: Rename, implement FADD.SAT and P2R (imm)
This commit is contained in:
		| @@ -110,7 +110,7 @@ void EmitCompositeExtractF64x3(EmitContext& ctx); | ||||
| void EmitCompositeExtractF64x4(EmitContext& ctx); | ||||
| void EmitSelect8(EmitContext& ctx); | ||||
| void EmitSelect16(EmitContext& ctx); | ||||
| void EmitSelect32(EmitContext& ctx); | ||||
| Id EmitSelect32(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||||
| void EmitSelect64(EmitContext& ctx); | ||||
| void EmitBitCastU16F16(EmitContext& ctx); | ||||
| Id EmitBitCastU32F32(EmitContext& ctx, Id value); | ||||
| @@ -130,9 +130,9 @@ void EmitGetZeroFromOp(EmitContext& ctx); | ||||
| void EmitGetSignFromOp(EmitContext& ctx); | ||||
| void EmitGetCarryFromOp(EmitContext& ctx); | ||||
| void EmitGetOverflowFromOp(EmitContext& ctx); | ||||
| void EmitFPAbs16(EmitContext& ctx); | ||||
| void EmitFPAbs32(EmitContext& ctx); | ||||
| void EmitFPAbs64(EmitContext& ctx); | ||||
| Id EmitFPAbs16(EmitContext& ctx, Id value); | ||||
| Id EmitFPAbs32(EmitContext& ctx, Id value); | ||||
| Id EmitFPAbs64(EmitContext& ctx, Id value); | ||||
| Id EmitFPAdd16(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| Id EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| Id EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| @@ -146,9 +146,9 @@ void EmitFPMin64(EmitContext& ctx); | ||||
| Id EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); | ||||
| void EmitFPNeg16(EmitContext& ctx); | ||||
| void EmitFPNeg32(EmitContext& ctx); | ||||
| void EmitFPNeg64(EmitContext& ctx); | ||||
| Id EmitFPNeg16(EmitContext& ctx, Id value); | ||||
| Id EmitFPNeg32(EmitContext& ctx, Id value); | ||||
| Id EmitFPNeg64(EmitContext& ctx, Id value); | ||||
| void EmitFPRecip32(EmitContext& ctx); | ||||
| void EmitFPRecip64(EmitContext& ctx); | ||||
| void EmitFPRecipSqrt32(EmitContext& ctx); | ||||
| @@ -161,9 +161,9 @@ void EmitFPExp2NotReduced(EmitContext& ctx); | ||||
| void EmitFPCos(EmitContext& ctx); | ||||
| void EmitFPCosNotReduced(EmitContext& ctx); | ||||
| void EmitFPLog2(EmitContext& ctx); | ||||
| void EmitFPSaturate16(EmitContext& ctx); | ||||
| void EmitFPSaturate32(EmitContext& ctx); | ||||
| void EmitFPSaturate64(EmitContext& ctx); | ||||
| Id EmitFPSaturate16(EmitContext& ctx, Id value); | ||||
| Id EmitFPSaturate32(EmitContext& ctx, Id value); | ||||
| Id EmitFPSaturate64(EmitContext& ctx, Id value); | ||||
| Id EmitFPRoundEven16(EmitContext& ctx, Id value); | ||||
| Id EmitFPRoundEven32(EmitContext& ctx, Id value); | ||||
| Id EmitFPRoundEven64(EmitContext& ctx, Id value); | ||||
| @@ -186,21 +186,21 @@ void EmitIAbs32(EmitContext& ctx); | ||||
| Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); | ||||
| void EmitShiftRightLogical32(EmitContext& ctx); | ||||
| void EmitShiftRightArithmetic32(EmitContext& ctx); | ||||
| void EmitBitwiseAnd32(EmitContext& ctx); | ||||
| void EmitBitwiseOr32(EmitContext& ctx); | ||||
| void EmitBitwiseXor32(EmitContext& ctx); | ||||
| Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b); | ||||
| Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); | ||||
| Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); | ||||
| void EmitBitFieldInsert(EmitContext& ctx); | ||||
| void EmitBitFieldSExtract(EmitContext& ctx); | ||||
| Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); | ||||
| Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs); | ||||
| void EmitULessThan(EmitContext& ctx); | ||||
| void EmitIEqual(EmitContext& ctx); | ||||
| void EmitSLessThanEqual(EmitContext& ctx); | ||||
| void EmitULessThanEqual(EmitContext& ctx); | ||||
| Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitSLessThanEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitULessThanEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs); | ||||
| void EmitUGreaterThan(EmitContext& ctx); | ||||
| void EmitINotEqual(EmitContext& ctx); | ||||
| void EmitSGreaterThanEqual(EmitContext& ctx); | ||||
| Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs); | ||||
| void EmitLogicalOr(EmitContext& ctx); | ||||
| void EmitLogicalAnd(EmitContext& ctx); | ||||
|   | ||||
| @@ -12,37 +12,21 @@ Id Decorate(EmitContext& ctx, IR::Inst* inst, Id op) { | ||||
|     if (flags.no_contraction) { | ||||
|         ctx.Decorate(op, spv::Decoration::NoContraction); | ||||
|     } | ||||
|     switch (flags.rounding) { | ||||
|     case IR::FpRounding::DontCare: | ||||
|         break; | ||||
|     case IR::FpRounding::RN: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTE); | ||||
|         break; | ||||
|     case IR::FpRounding::RM: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTN); | ||||
|         break; | ||||
|     case IR::FpRounding::RP: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTP); | ||||
|         break; | ||||
|     case IR::FpRounding::RZ: | ||||
|         ctx.Decorate(op, spv::Decoration::FPRoundingMode, spv::FPRoundingMode::RTZ); | ||||
|         break; | ||||
|     } | ||||
|     return op; | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| void EmitFPAbs16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPAbs16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFAbs(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPAbs32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPAbs32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFAbs(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPAbs64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPAbs64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFAbs(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| Id EmitFPAdd16(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
| @@ -97,16 +81,16 @@ Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { | ||||
|     return Decorate(ctx, inst, ctx.OpFMul(ctx.F64[1], a, b)); | ||||
| } | ||||
|  | ||||
| void EmitFPNeg16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPNeg16(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFNegate(ctx.F16[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPNeg32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPNeg32(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFNegate(ctx.F32[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPNeg64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPNeg64(EmitContext& ctx, Id value) { | ||||
|     return ctx.OpFNegate(ctx.F64[1], value); | ||||
| } | ||||
|  | ||||
| void EmitFPRecip32(EmitContext&) { | ||||
| @@ -157,16 +141,22 @@ void EmitFPLog2(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitFPSaturate16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPSaturate16(EmitContext& ctx, Id value) { | ||||
|     const Id zero{ctx.Constant(ctx.F16[1], u16{0})}; | ||||
|     const Id one{ctx.Constant(ctx.F16[1], u16{0x3c00})}; | ||||
|     return ctx.OpFClamp(ctx.F32[1], value, zero, one); | ||||
| } | ||||
|  | ||||
| void EmitFPSaturate32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPSaturate32(EmitContext& ctx, Id value) { | ||||
|     const Id zero{ctx.Constant(ctx.F32[1], f32{0.0})}; | ||||
|     const Id one{ctx.Constant(ctx.F32[1], f32{1.0})}; | ||||
|     return ctx.OpFClamp(ctx.F32[1], value, zero, one); | ||||
| } | ||||
|  | ||||
| void EmitFPSaturate64(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitFPSaturate64(EmitContext& ctx, Id value) { | ||||
|     const Id zero{ctx.Constant(ctx.F64[1], f64{0.0})}; | ||||
|     const Id one{ctx.Constant(ctx.F64[1], f64{1.0})}; | ||||
|     return ctx.OpFClamp(ctx.F64[1], value, zero, one); | ||||
| } | ||||
|  | ||||
| Id EmitFPRoundEven16(EmitContext& ctx, Id value) { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -14,8 +14,8 @@ void EmitSelect16(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| } | ||||
|  | ||||
| void EmitSelect32(EmitContext&) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
| Id EmitSelect32(EmitContext& ctx, Id cond, Id true_value, Id false_value) { | ||||
|     return ctx.OpSelect(ctx.U32[1], cond, true_value, false_value); | ||||
| } | ||||
|  | ||||
| void EmitSelect64(EmitContext&) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user