static List<CStatement> Add_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); /* op1 + op2 */ CStatement stat = new CStatement(CStatement.Kinds.Addition, RegName(i.RA()), RegName(i.RB())); /* dest = expr */ CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RD()), stat); List<CStatement> stats = new List<CStatement>(); stats.Add(ass); if (i.OE()) MessageBox.Show("This instruction sets the O bit. I don't know how to translate it! Ignoring."); if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RD()))); return stats; }
static List<CStatement> And_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); /* op1 & op2 */ CStatement stat = new CStatement(CStatement.Kinds.And, RegName(i.RS()), RegName(i.RB())); /* dest = expr */ CStatement ass = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), stat); List<CStatement> stats = new List<CStatement>(); stats.Add(ass); if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RA()))); return stats; }
static List<CStatement> Stw_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat = new CStatement(CStatement.Kinds.Assignment); stat.OperandSizes = CStatement.Sizes.Int; if (i.RS() == 0) stat.Op2 = new CStatement.COperand(0); else stat.Op2 = new CStatement.COperand(RegName(i.RS())); int ds = (int)i.SIMM(); if (i.RA() != 0) stat.Op1 = new CStatement.COperand(RegName(i.RA()), ds); else { stat.Op1 = new CStatement.COperand(); stat.Op1.Kind = CStatement.OperandKinds.AddressPointer; stat.Op1.Offset = ds; } List<CStatement> stats = new List<CStatement>(); stats.Add(stat); return stats; }
static List<CStatement> Addi_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RD())); if (i.RA() == 0) stat.Op2 = new CStatement.COperand((ulong)(long)i.SIMM()); else if (i.SIMM() == 0) stat.Op2 = new CStatement.COperand(RegName(i.RA())); else { CStatement add = new CStatement(CStatement.Kinds.Addition, RegName(i.RA()), (ulong)(long)i.SIMM()); long val = (long)add.Op2.Value; if (val < 0) { add.Kind = CStatement.Kinds.Subtraction; add.Op2.Value = (ulong)-val; } stat.Op2 = new CStatement.COperand(add); } List<CStatement> stats = new List<CStatement>(); stats.Add(stat); return stats; }
static List<CStatement> Srawi_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement shift = new CStatement(CStatement.Kinds.RightShift, RegName(i.RS()), i.SH()); shift.OperandSizes = CStatement.Sizes.Int; CStatement stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), shift); stat.OperandSizes = CStatement.Sizes.Int; List<CStatement> stats = new List<CStatement>(); stats.Add(stat); if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RA()))); return stats; }
static List<CStatement> Stwu_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); List<CStatement> stats = Stw_C(pc, instruction); if (i.SIMM() == 0) return stats; CStatement add = new CStatement(CStatement.Kinds.Addition, RegName(i.RA()), (ulong)(long)i.SIMM()); CStatement stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), add); stat.OperandSizes = CStatement.Sizes.Int; stats.Add(stat); 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; }
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> Ori_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); /* NOP */ if (i.RA() == i.RS() && i.RS() == 0 && i.UIMM() == 0) return new List<CStatement>(); CStatement stat; if (i.RS() == 0) stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), i.UIMM()); else if (i.UIMM() == 0) stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), RegName(i.RS())); else { CStatement or = new CStatement(CStatement.Kinds.Or, RegName(i.RS()), i.UIMM()); or.OperandSizes = CStatement.Sizes.Long; stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), or); } stat.OperandSizes = CStatement.Sizes.Long; List<CStatement> stats = new List<CStatement>(); stats.Add(stat); return stats; }
static List<CStatement> Ld_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RD())); int ds = (int)i.DS() << 2; if (i.RA() != 0) stat.Op2 = new CStatement.COperand(RegName(i.RA()), ds); else { stat.Op2 = new CStatement.COperand(); stat.Op2.Kind = CStatement.OperandKinds.AddressPointer; stat.Op2.Offset = ds; } List<CStatement> stats = new List<CStatement>(); stats.Add(stat); return stats; }
static List<CStatement> Lbzx_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RD())); stat.OperandSizes = CStatement.Sizes.Byte; if (i.RA() != 0) { if (i.RB() != 0) stat.Op2 = new CStatement.COperand(RegName(i.RA()), RegName(i.RB())); else stat.Op2 = new CStatement.COperand(RegName(i.RA()), 0); } else stat.Op2 = new CStatement.COperand(RegName(i.RB()), 0); List<CStatement> stats = new List<CStatement>(); stats.Add(stat); return stats; }
static List<CStatement> Cmp_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat = new CStatement(CStatement.Kinds.Subtraction, RegName(i.RA()), RegName(i.RB())); CStatement ass = new CStatement(CStatement.Kinds.Assignment, "cr" + i.CRFD(), stat); if (!i.CmpLong()) ass.OperandSizes = stat.OperandSizes = CStatement.Sizes.Int; List<CStatement> stats = new List<CStatement>(); stats.Add(ass); return stats; }
static List<CStatement> Or_C(uint pc, uint instruction) { Instruction i = new Instruction(instruction); CStatement stat; if (i.RS() == 0 && i.RB() != 0) stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), RegName(i.RB())); else if (i.RB() == 0 && i.RS() != 0) stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), RegName(i.RS())); else if (i.RS() == i.RB()) { if (i.RS() != 0) stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), RegName(i.RS())); else stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), 0); } else { CStatement or = new CStatement(CStatement.Kinds.Or, RegName(i.RS()), RegName(i.RB())); or.OperandSizes = CStatement.Sizes.Long; stat = new CStatement(CStatement.Kinds.Assignment, RegName(i.RA()), or); } stat.OperandSizes = CStatement.Sizes.Long; List<CStatement> stats = new List<CStatement>(); stats.Add(stat); if (i.RC()) stats.Add(new CStatement(CStatement.Kinds.Assignment, "cr0", RegName(i.RA()))); return stats; }