virtual void Process()override { FNiagaraCompiler_VectorVM* VMCompiler = (FNiagaraCompiler_VectorVM*)Compiler; //Should be invalid at this point. check(ResultIndex == INDEX_NONE); check(ComponentIndex == INDEX_NONE); //Special case where we're splatting but we don't know the component until now. E.g. Getting constants. //Choose the component now based on the source expressions component index if (OpCode == VectorVM::EOp::splatx) { check(SourceExpressions.Num() == 1); TNiagaraExprPtr Src0 = GetSourceExpression(0); if (Src0->ComponentIndex != INDEX_NONE) { switch (Src0->ComponentIndex) { case 0: OpCode = VectorVM::EOp::splatx; break; case 1: OpCode = VectorVM::EOp::splaty; break; case 2: OpCode = VectorVM::EOp::splatz; break; case 3: OpCode = VectorVM::EOp::splatw; break; } } } ResultIndex = VMCompiler->AquireTemporary(); ResultLocation = ENiagaraExpressionResultLocation::Temporaries; check(ResultIndex < VectorVM::NumTempRegisters); VMCompiler->WriteCode((uint8)OpCode); VMCompiler->WriteCode(VMCompiler->GetResultVMIndex( this )); //Add the bitfield defining whether each source operand comes from a constant or a register. int32 NumOperands = SourceExpressions.Num(); check(NumOperands <= 4); uint8 OpTypeMask = VectorVM::CreateSrcOperandMask(NumOperands > 0 ? VMCompiler->GetVMOperandType(GetSourceExpression(0).Get()) : VectorVM::RegisterOperandType, NumOperands > 1 ? VMCompiler->GetVMOperandType(GetSourceExpression(1).Get()) : VectorVM::RegisterOperandType, NumOperands > 2 ? VMCompiler->GetVMOperandType(GetSourceExpression(2).Get()) : VectorVM::RegisterOperandType, NumOperands > 3 ? VMCompiler->GetVMOperandType(GetSourceExpression(3).Get()) : VectorVM::RegisterOperandType); VMCompiler->WriteCode(OpTypeMask); //Add the locations for each of the source operands. for (int32 SrcIdx = 0; SrcIdx < SourceExpressions.Num(); ++SrcIdx) { VMCompiler->WriteCode(VMCompiler->GetResultVMIndex(GetSourceExpression(SrcIdx).Get())); } }
virtual bool Process()override { FNiagaraCompiler_VectorVM* VMCompiler = (FNiagaraCompiler_VectorVM*)Compiler; //Should be invalid at this point. check(ResultIndex == INDEX_NONE); ResultIndex = VMCompiler->AquireTemporary(); if (ResultIndex == INDEX_NONE) { return false; } ResultLocation = ENiagaraExpressionResultLocation::Temporaries; check(ResultIndex < VectorVM::NumTempRegisters); VMCompiler->WriteCode((uint8)OpCode); //Add the bitfield defining whether each source operand comes from a constant or a register. int32 NumOperands = SourceExpressions.Num(); check(NumOperands <= 4); uint8 OpTypeMask = VectorVM::CreateSrcOperandMask(NumOperands > 0 ? VMCompiler->GetVMOperandType(GetSourceExpression(0).Get()) : EVectorVMOperandLocation::TemporaryRegister, NumOperands > 1 ? VMCompiler->GetVMOperandType(GetSourceExpression(1).Get()) : EVectorVMOperandLocation::TemporaryRegister, NumOperands > 2 ? VMCompiler->GetVMOperandType(GetSourceExpression(2).Get()) : EVectorVMOperandLocation::TemporaryRegister, NumOperands > 3 ? VMCompiler->GetVMOperandType(GetSourceExpression(3).Get()) : EVectorVMOperandLocation::TemporaryRegister); VMCompiler->WriteCode(OpTypeMask); //Write dest VMCompiler->WriteCode(VMCompiler->GetResultVMIndex(this)); //Add the locations for each of the source operands. for (int32 SrcIdx = 0; SrcIdx < SourceExpressions.Num(); ++SrcIdx) { VMCompiler->WriteCode(VMCompiler->GetResultVMIndex(GetSourceExpression(SrcIdx).Get())); } return true; }
virtual void Process()override { FNiagaraCompiler_VectorVM* VMCompiler = (FNiagaraCompiler_VectorVM*)Compiler; check(ResultLocation == ENiagaraExpressionResultLocation::OutputData); ResultIndex = VMCompiler->GetAttributeIndex(Result); FNiagaraExpression* SrcExpr = GetSourceExpression(0).Get(); check(SourceExpressions.Num() == 1); uint8 DestIndex = VMCompiler->GetResultVMIndex(this); uint8 SrcIndex = VMCompiler->GetResultVMIndex(SrcExpr); VMCompiler->WriteCode((uint8)VectorVM::EOp::output); VMCompiler->WriteCode(DestIndex); VMCompiler->WriteCode(VectorVM::CreateSrcOperandMask( VMCompiler->GetVMOperandType(SrcExpr) ) ); VMCompiler->WriteCode(SrcIndex); }