static List<CStatement> Rlwinm_C(uint pc, uint instruction) { /** * Very complex instruction * RA = RotateLeft(RS, SH) & ((0xFFFFFFFF >> MB) ^ (0xFFFFFFFF >> ME)); * * Can be simplified: * if (MB == 0 && ME + SH == 31) * ShiftLeft (BigEndian) = ShiftRight (LittleEndian) * if (ME == 31 && SH + MB == 32) * ShiftRight (BigEndian) = ShiftLeft * if (SH == 0 && ME == 31) * ClearLeft = ClearRight * if (SH == 0 && MB == 0) * ClearRight = ClearLeft * if (MB == 0 && ME == 31) * Rotate * * extlwi rA,rS,n,b equivalent to rlwinm rA,rS,b,0,n – 1 * extrwi rA,rS,n,b equivalent to rlwinm rA,rS,b + n,32 – n,31 * clrlslwi rA,rS,b,n equivalent to rlwinm rA,rS,n,b – n,31 – n */ List<CStatement> stats = new List<CStatement>(); Instruction i = new Instruction(instruction); if (i.MB() == 0) { if (i.ME() == 31) { /* * Rotate left - Rotate right... * ((x >> n) | (x << (32 - n))) */ uint n = i.SH(); CStatement lsh = new CStatement(CStatement.Kinds.LeftShift, RegName(i.RS()), 32 - n); CStatement rsh = new CStatement(CStatement.Kinds.RightShift, RegName(i.RS()), n); CStatement or = new CStatement(CStatement.Kinds.Or, rsh, lsh); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), or); stats.Add(ass); } else if (i.ME() + i.SH() == 31) { /* ShiftLeft = ShiftRight */ uint n = i.SH(); CStatement rsh = new CStatement(CStatement.Kinds.RightShift, RegName(i.RS()), n); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), rsh); stats.Add(ass); } else if (i.SH() == 0) { /* ClearRight = ClearLeft */ uint n = 31 - i.ME(); uint mask = 0xFFFFFFFF << (int)n; CStatement and = new CStatement(CStatement.Kinds.And, RegName(i.RS()), mask); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), and); stats.Add(ass); } } else if (i.ME() == 31 && i.SH() + i.MB() == 32) { /* ShiftRight = ShiftLeft */ uint n = i.MB(); CStatement lsh = new CStatement(CStatement.Kinds.LeftShift, RegName(i.RS()), n); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), lsh); stats.Add(ass); } else if (i.SH() == 0) { if (i.ME() == 31) { /* ClearLeft = ClearRight */ uint n = i.MB(); uint mask = 0xFFFFFFFF ^ (0xFFFFFFFF << (int)n); CStatement and = new CStatement(CStatement.Kinds.And, RegName(i.RS()), mask); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), and); stats.Add(ass); } else { /* And without rotate */ uint m1 = 0xFFFFFFFF >> (int)(i.ME() + 1); uint m2 = 0xFFFFFFFF >> (int)i.MB(); uint mask = m1 ^ m2; CStatement and = new CStatement(CStatement.Kinds.And, RegName(i.RS()), mask); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), and); stats.Add(ass); } } else { /* Rotate, then and */ uint n = i.SH(); uint m1 = 0xFFFFFFFF << (int)i.MB(); uint m2 = 0xFFFFFFFF << (int)i.ME(); uint mask = m1 ^ m2; CStatement lsh = new CStatement(CStatement.Kinds.LeftShift, RegName(i.RS()), 32 - n); CStatement rsh = new CStatement(CStatement.Kinds.RightShift, RegName(i.RS()), n); CStatement or = new CStatement(CStatement.Kinds.Or, rsh, lsh); CStatement and = new CStatement(CStatement.Kinds.And, or, mask); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), and); stats.Add(ass); } if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RA()))); return stats; }
static List<CStatement> Rlwimi_C(uint pc, uint instruction) { List<CStatement> stats = new List<CStatement>(); Instruction i = new Instruction(instruction); uint m1 = 0xFFFFFFFF << (int)i.ME(); uint m2 = 0xFFFFFFFF << (int)i.MB(); uint mask = m1 ^ m2; CStatement lsh = new CStatement(CStatement.Kinds.LeftShift, RegName(i.RS()), 32 - i.SH()); CStatement rsh = new CStatement(CStatement.Kinds.RightShift, RegName(i.RS()), i.SH()); CStatement orRot = new CStatement(CStatement.Kinds.Or, rsh, lsh); CStatement notMask = new CStatement(CStatement.Kinds.BinaryNot, mask); CStatement and1 = new CStatement(CStatement.Kinds.And, orRot, mask); CStatement and2 = new CStatement(CStatement.Kinds.And, RegName(i.RA()), notMask); CStatement or = new CStatement(CStatement.Kinds.Or, and1, and2); CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), or); stats.Add(ass); /* RA = (ROTL(RS, i.SH) & mask) | (RA & ~mask); */ if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RA()))); return stats; }