/// <summary> /// Inserts the assignment <paramref name="ass"/> before the statement /// <paramref name="stm"/> if it is in the same block. Otherwise append /// it to the end of the statements in the block. /// </summary> public SsaIdentifier InsertBeforeStatement(Block block, Statement stm, Assignment ass) { Statement stmNew; if (stm.Block == block) { int i = stm.Block.Statements.IndexOf(stm); stmNew = new Statement(stm.LinearAddress, ass, stm.Block); stm.Block.Statements.Insert(i, stmNew); } else { ulong uAddr = block.Address.ToLinear(); int i = -1; if (block.Statements.Count > 0) { i = block.Statements.Count - 1; if (block.Statements[i].Instruction.IsControlFlow) { --i; } if (i >= 0) { uAddr = block.Statements[i].LinearAddress; } } stmNew = block.Statements.Insert(i + 1, uAddr, ass); } var sidTo = ssaIds.Add(ass.Dst, stmNew, ass.Src, false); ass.Dst = sidTo.Identifier; return(sidTo); }
private Instruction TransformRolC(Application rolc, Assignment a) { var sidOrigHi = ssaIds[a.Dst]; var sidCarry = ssaIds[(Identifier)rolc.Arguments[2]]; if (!(sidCarry.DefExpression is ConditionOf cond)) { return(a); } if (!(cond.Expression is Identifier condId)) { return(a); } var sidOrigLo = ssaIds[condId]; if (!(sidOrigLo.DefExpression is BinaryExpression shift) || shift.Operator != Operator.Shl) { return(a); } var block = sidOrigHi.DefStatement !.Block; var expShrSrc = shift.Left; var expRorSrc = rolc.Arguments[0]; var stmGrf = sidGrf !.DefStatement; block.Statements.Remove(stmGrf !); // xx = lo var tmpLo = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType); var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, expShrSrc, false); sidOrigLo.DefStatement !.Instruction = new Assignment(sidTmpLo.Identifier, expShrSrc); var tmpHi = ssa.Procedure.Frame.CreateTemporary(rolc.Arguments[0].DataType); var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, rolc.Arguments[0], false); sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, rolc.Arguments[0]); var iRolc = block.Statements.IndexOf(sidOrigHi.DefStatement); var dt = PrimitiveType.Create(Domain.Integer, expShrSrc.DataType.BitSize + expRorSrc.DataType.BitSize); var tmp = ssa.Procedure.Frame.CreateTemporary(dt); var expMkLongword = m.Shl(m.Seq(sidTmpHi.Identifier, sidTmpLo.Identifier), 1); var sidTmp = ssaIds.Add(tmp, sidGrf.DefStatement, expMkLongword, false); var stmTmp = block.Statements.Insert(iRolc + 1, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidTmp.Identifier, expMkLongword)); sidTmp.DefStatement = stmTmp; sidTmpLo.Uses.Add(stmTmp); sidTmpHi.Uses.Add(stmTmp); ssa.RemoveUses(sidCarry.DefStatement !); block.Statements.Remove(sidCarry.DefStatement !); ssaIds.Remove(sidCarry); var expNewLo = m.Cast( PrimitiveType.CreateWord(tmpHi.DataType.BitSize), sidTmp.Identifier); var stmNewLo = block.Statements.Insert( iRolc + 2, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidOrigLo.Identifier, expNewLo)); sidTmp.Uses.Add(stmNewLo); sidOrigLo.DefStatement = stmNewLo; sidOrigLo.DefExpression = expNewLo; var expNewHi = m.Slice( PrimitiveType.CreateWord(tmpLo.DataType.BitSize), sidTmp.Identifier, tmpHi.DataType.BitSize); var stmNewHi = block.Statements.Insert( iRolc + 3, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidOrigHi.Identifier, expNewHi)); sidTmp.Uses.Add(stmNewHi); sidOrigHi.DefStatement = stmNewHi; sidOrigHi.DefStatement = stmNewHi; sidGrf.DefExpression = null; sidGrf.DefStatement = null; return(sidOrigHi.DefStatement.Instruction); }