@@ -60,6 +60,7 @@ static constexpr std::array s_operandTypeForUsage = {
6060 OperandUsageType{DestVariableHighLevelOperandUsage, VariableHighLevelOperand},
6161 OperandUsageType{SSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand},
6262 OperandUsageType{DestSSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand},
63+ OperandUsageType{PartialSSAVariableSourceHighLevelOperandUsage, SSAVariableHighLevelOperand},
6364 OperandUsageType{DestExprHighLevelOperandUsage, ExprHighLevelOperand},
6465 OperandUsageType{LeftExprHighLevelOperandUsage, ExprHighLevelOperand},
6566 OperandUsageType{RightExprHighLevelOperandUsage, ExprHighLevelOperand},
@@ -113,6 +114,12 @@ struct HighLevelILOperationTraits
113114
114115 static constexpr uint8_t GetOperandIndexAdvance (OperandUsage usage, size_t /* operandIndex */ )
115116 {
117+ if (usage == PartialSSAVariableSourceHighLevelOperandUsage)
118+ {
119+ // SSA variables are usually two slots, but this one has previously defined
120+ // variables and thus only takes one slot
121+ return 1 ;
122+ }
116123 switch (OperandTypeForUsage (usage))
117124 {
118125 case SSAVariableHighLevelOperand:
@@ -252,6 +259,7 @@ static constexpr std::array s_instructionOperandUsage = {
252259 OperandUsage{HLIL_FORCE_VER_SSA , {DestSSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperandUsage}},
253260 OperandUsage{HLIL_ASSERT_SSA , {SSAVariableHighLevelOperandUsage, ConstantHighLevelOperandUsage}},
254261 OperandUsage{HLIL_VAR_SSA , {SSAVariableHighLevelOperandUsage}},
262+ OperandUsage{HLIL_VAR_SSA_PARTIAL , {SSAVariableHighLevelOperandUsage, PartialSSAVariableSourceHighLevelOperandUsage}},
255263 OperandUsage{HLIL_ARRAY_INDEX_SSA , {SourceExprHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage, IndexExprHighLevelOperandUsage}},
256264 OperandUsage{HLIL_DEREF_SSA , {SourceExprHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage}},
257265 OperandUsage{HLIL_DEREF_FIELD_SSA , {SourceExprHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage, OffsetHighLevelOperandUsage, MemberIndexHighLevelOperandUsage}},
@@ -816,6 +824,12 @@ SSAVariable HighLevelILInstructionBase::GetRawOperandAsSSAVariable(size_t operan
816824}
817825
818826
827+ SSAVariable HighLevelILInstructionBase::GetRawOperandAsPartialSSAVariableSource (size_t operand) const
828+ {
829+ return SSAVariable (Variable::FromIdentifier (operands[operand]), (size_t )operands[operand + 2 ]);
830+ }
831+
832+
819833HighLevelILInstructionList HighLevelILInstructionBase::GetRawOperandAsExprList (size_t operand) const
820834{
821835 return HighLevelILInstructionList (
@@ -1528,6 +1542,10 @@ ExprId HighLevelILInstruction::CopyTo(
15281542 return dest->Var (size, GetVariable<HLIL_VAR >(), loc);
15291543 case HLIL_VAR_SSA :
15301544 return dest->VarSSA (size, GetSSAVariable<HLIL_VAR_SSA >(), loc);
1545+ case HLIL_VAR_SSA_PARTIAL :
1546+ return dest->VarSSAPartial (size, GetDestSSAVariable<HLIL_VAR_SSA_PARTIAL >().var ,
1547+ GetDestSSAVariable<HLIL_VAR_SSA_PARTIAL >().version ,
1548+ GetSourceSSAVariable<HLIL_VAR_SSA_PARTIAL >().version , loc);
15311549 case HLIL_VAR_PHI :
15321550 return dest->VarPhi (GetDestSSAVariable<HLIL_VAR_PHI >(), GetSourceSSAVariables<HLIL_VAR_PHI >(), loc);
15331551 case HLIL_MEM_PHI :
@@ -1925,6 +1943,16 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons
19251943 if (size > other.size )
19261944 return false ;
19271945 return GetSSAVariable<HLIL_VAR_SSA >() < other.GetSSAVariable <HLIL_VAR_SSA >();
1946+ case HLIL_VAR_SSA_PARTIAL :
1947+ if (size < other.size )
1948+ return true ;
1949+ if (size > other.size )
1950+ return false ;
1951+ if (GetDestSSAVariable<HLIL_VAR_SSA_PARTIAL >() < other.GetDestSSAVariable <HLIL_VAR_SSA_PARTIAL >())
1952+ return true ;
1953+ if (other.GetDestSSAVariable <HLIL_VAR_SSA_PARTIAL >() < GetDestSSAVariable<HLIL_VAR_SSA_PARTIAL >())
1954+ return false ;
1955+ return GetSourceSSAVariable<HLIL_VAR_SSA_PARTIAL >() < other.GetSourceSSAVariable <HLIL_VAR_SSA_PARTIAL >();
19281956 case HLIL_STRUCT_FIELD :
19291957 if (size < other.size )
19301958 return true ;
@@ -2324,6 +2352,15 @@ SSAVariable HighLevelILInstruction::GetDestSSAVariable() const
23242352}
23252353
23262354
2355+ SSAVariable HighLevelILInstruction::GetSourceSSAVariable () const
2356+ {
2357+ size_t operandIndex;
2358+ if (GetOperandIndexForUsage (PartialSSAVariableSourceHighLevelOperandUsage, operandIndex))
2359+ return GetRawOperandAsPartialSSAVariableSource (operandIndex - 2 );
2360+ throw MediumLevelILInstructionAccessException ();
2361+ }
2362+
2363+
23272364HighLevelILInstruction HighLevelILInstruction::GetDestExpr () const
23282365{
23292366 size_t operandIndex;
@@ -2831,6 +2868,13 @@ ExprId HighLevelILFunction::VarSSA(size_t size, const SSAVariable& src, const IL
28312868}
28322869
28332870
2871+ ExprId HighLevelILFunction::VarSSAPartial (size_t size, const Variable& dest, size_t newVersion, size_t prevVersion,
2872+ const ILSourceLocation& loc)
2873+ {
2874+ return AddExprWithLocation (HLIL_VAR_SSA_PARTIAL , loc, size, dest.ToIdentifier (), newVersion, prevVersion);
2875+ }
2876+
2877+
28342878ExprId HighLevelILFunction::VarPhi (
28352879 const SSAVariable& dest, const vector<SSAVariable>& sources, const ILSourceLocation& loc)
28362880{
0 commit comments