// 1. a_2 = a_1 >> 1 // 2. C_2 = cond(a_2) // 3. b_2 = b_1 rorc 1, C // 4. flags_3 = cond(b_2) // 1. tmp_1 = a_1 // 3. tmp_2 = b_2 // *. tmp_3 = (tmp1:tmp2) >> 1 // 1'. a_2 = slice(tmp3,16) // 2'. b_2 = (cast) tmp3 // 4. flags_3 = cond(b_2) private Instruction TransformRorC(Application rorc, Assignment a) { var sidOrigLo = ssaIds[a.Dst]; var sidCarry = ssaIds[(Identifier)rorc.Arguments[2]]; var cond = sidCarry.DefExpression as ConditionOf; if (cond == null) { return(a); } var condId = cond.Expression as Identifier; if (condId == null) { return(a); } var sidOrigHi = ssaIds[condId]; var shift = sidOrigHi.DefExpression as BinaryExpression; if (shift == null || shift.Operator != Operator.Shr) { return(a); } var block = sidOrigLo.DefStatement.Block; var sidShift = sidOrigHi.DefStatement; var expShrSrc = shift.Left; var expRorSrc = rorc.Arguments[0]; var stmGrf = sidGrf.DefStatement; block.Statements.Remove(stmGrf); var tmpHi = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType); var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, expShrSrc, false); sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, expShrSrc); var tmpLo = ssa.Procedure.Frame.CreateTemporary(rorc.Arguments[0].DataType); var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, rorc.Arguments[0], false); sidOrigLo.DefStatement.Instruction = new Assignment(sidTmpLo.Identifier, rorc.Arguments[0]); var iRorc = block.Statements.IndexOf(sidOrigLo.DefStatement); var dt = PrimitiveType.Create(Domain.UnsignedInt, expShrSrc.DataType.Size + expRorSrc.DataType.Size); var tmp = ssa.Procedure.Frame.CreateTemporary(dt); var expMkLongword = m.Shr(m.Seq(sidTmpHi.Identifier, sidTmpLo.Identifier), 1); var sidTmp = ssaIds.Add(tmp, sidGrf.DefStatement, expMkLongword, false); var stmTmp = block.Statements.Insert(iRorc + 1, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidTmp.Identifier, expMkLongword)); sidTmp.DefStatement = stmTmp; sidTmpHi.Uses.Add(stmTmp); sidTmpLo.Uses.Add(stmTmp); ssa.RemoveUses(sidCarry.DefStatement); block.Statements.Remove(sidCarry.DefStatement); ssaIds.Remove(sidCarry); var expNewHi = m.Slice( PrimitiveType.CreateWord(tmpHi.DataType.Size), sidTmp.Identifier, (uint)tmpLo.DataType.BitSize); var stmNewHi = block.Statements.Insert( iRorc + 2, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidOrigHi.Identifier, expNewHi)); sidTmp.Uses.Add(stmNewHi); sidOrigHi.DefStatement = stmNewHi; sidOrigHi.DefExpression = expNewHi; var expNewLo = m.Cast( PrimitiveType.CreateWord(tmpLo.DataType.Size), sidTmp.Identifier); var stmNewLo = block.Statements.Insert( iRorc + 3, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidOrigLo.Identifier, expNewLo)); sidTmp.Uses.Add(stmNewLo); sidOrigLo.DefStatement = stmNewLo; sidOrigLo.DefStatement = stmNewLo; sidGrf.DefExpression = m.Cond(sidTmp.Identifier); sidGrf.DefStatement.Instruction = new Assignment( sidGrf.Identifier, sidGrf.DefExpression); sidTmp.Uses.Add(sidGrf.DefStatement); ssa.DebugDump(true); Debug.Print("sidGrf: *** {0}", sidGrf); return(sidOrigLo.DefStatement.Instruction); }