private void RewriteCvtD(MipsInstruction instr, DataType dt) { var regPair = GetFpuRegPair(instr.op2); emitter.Assign( RewriteOperand(instr.op1), emitter.Cast(dt, regPair)); }
private void RewriteAddD(MipsInstruction instr) { var dst = GetFpuRegPair(instr.op1); var src1 = GetFpuRegPair(instr.op2); var src2 = GetFpuRegPair(instr.op3); emitter.Assign(dst, emitter.FAdd(src1, src2)); }
private void RewriteBreak(MipsInstruction instr) { emitter.SideEffect( PseudoProc( "__break", VoidType.Instance, this.RewriteOperand(instr.op1))); }
private void RewriteTrap(MipsInstruction instr, Operator op) { var trap = host.PseudoProcedure("__trap", VoidType.Instance, RewriteOperand(instr.op3)); emitter.If(new BinaryExpression(op, PrimitiveType.Bool, RewriteOperand(instr.op1), RewriteOperand(instr.op2)), new RtlSideEffect(trap)); }
private void RewriteTrap(MipsInstruction instr, Func<Expression,Expression,Expression> op) { var trap = host.PseudoProcedure("__trap", VoidType.Instance, RewriteOperand(instr.op3)); emitter.If(op( RewriteOperand(instr.op1), RewriteOperand(instr.op2)), new RtlSideEffect(trap)); }
private void RewriteLoad(MipsInstruction instr) { var opSrc = RewriteOperand(instr.op2); var opDst = RewriteOperand(instr.op1); if (opDst.DataType.Size != opSrc.DataType.Size) opSrc = emitter.Cast(arch.WordWidth, opSrc); emitter.Assign(opDst, opSrc); }
private void RewriteFpuCmpD(MipsInstruction instr, Operator cmp) { emitter.Assign( RewriteOperand(instr.op1), new BinaryExpression(cmp, PrimitiveType.Bool, GetFpuRegPair(instr.op2), GetFpuRegPair(instr.op3))); }
private void RewriteJal(MipsInstruction instr) { //$TODO: if we want explicit representation of the continuation of call // use the line below //emitter.Assign( frame.EnsureRegister(Registers.ra), instr.Address + 8); cluster.Class = RtlClass.Transfer; emitter.CallD(RewriteOperand(instr.op1), 0); }
private void RewriteLui(MipsInstruction instr) { var immOp = (ImmediateOperand)instr.op2; long v = immOp.Value.ToInt16(); var opSrc = Constant.Create(arch.WordWidth, v << 16); var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, opSrc); }
private void RewriteDiv(MipsInstruction instr, Func<Expression, Expression, Expression> ctor) { var hi = frame.EnsureRegister(Registers.hi); var lo = frame.EnsureRegister(Registers.lo); var opLeft = RewriteOperand(instr.op1); var opRight = RewriteOperand(instr.op2); emitter.Assign(lo, ctor(opLeft, opRight)); emitter.Assign(hi, emitter.Mod(opLeft, opRight)); }
private void RewriteBc1f(MipsInstruction instr, bool opTrue) { var cond = RewriteOperand(instr.op1); if (!opTrue) cond = emitter.Not(cond); var addr = (Address)RewriteOperand(instr.op2); cluster.Class = RtlClass.ConditionalTransfer | RtlClass.Delay; emitter.Branch(cond, addr, cluster.Class); }
private void RewriteMfc0(MipsInstruction instr) { var cpregFrom = ((RegisterOperand)instr.op2).Register; Identifier from; switch (cpregFrom.Number) { case 9: from = frame.CreateTemporary("__counter__", PrimitiveType.UInt32); break; default: from = frame.CreateTemporary("__cp" + cpregFrom.Number, PrimitiveType.UInt32); break; } emitter.Assign(RewriteOperand(instr.op1), from); }
private void RewriteBranch0(MipsInstruction instr, BinaryOperator condOp, bool link) { if (!link) { var reg = RewriteOperand(instr.op1); var addr = (Address)RewriteOperand(instr.op2); var cond = new BinaryExpression(condOp, PrimitiveType.Bool, reg, Constant.Zero(reg.DataType)); cluster.Class = RtlClass.ConditionalTransfer; emitter.Branch(cond, addr, RtlClass.ConditionalTransfer | RtlClass.Delay); } else throw new NotImplementedException("Linked branches not implemented yet."); }
private void RewriteAnd(MipsInstruction instr) { var opLeft = RewriteOperand(instr.op2); var opRight = RewriteOperand(instr.op3); Expression opSrc; if (opLeft.IsZero) opSrc = opLeft; else if (opRight.IsZero) opSrc = opRight; else opSrc = emitter.IAdd(opLeft, opRight); var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, opSrc); }
private void RewriteJalr(MipsInstruction instr) { //$TODO: if we want explicit representation of the continuation of call // use the line below //emitter.Assign( frame.EnsureRegister(Registers.ra), instr.Address + 8); cluster.Class = RtlClass.Transfer; var dst = RewriteOperand(instr.op2); var lr = RewriteOperand(instr.op1); if (((Identifier)lr).Storage == Registers.ra) { emitter.CallD(dst, 0); return; } throw new NotImplementedException("jalr to register other than ra not implemented yet."); }
private void RewriteLx(MipsInstruction instr, PrimitiveType dt, int scale) { var dst = RewriteOperand(instr.Operands[0]); var idx = (IndexedOperand)instr.Operands[1]; var idBase = binder.EnsureRegister(idx.Base); Expression index = binder.EnsureRegister(idx.Index); if (scale != 1) { index = m.IMul(index, scale); } Expression src = m.Mem32(m.IAdd(idBase, index)); if (dst.DataType.Size != dt.Size) { // If the source is smaller than the destination register, // perform a sign/zero extension. src.DataType = dt; src = m.Convert(src, src.DataType, dst.DataType); } m.Assign(dst, src); }
private void RewriteAnd(MipsInstruction instr) { var opLeft = RewriteOperand0(instr.Operands[1]); var opRight = RewriteOperand0(instr.Operands[2]); Expression opSrc; if (opLeft.IsZero) { opSrc = opLeft; } else if (opRight.IsZero) { opSrc = opRight; } else { opSrc = m.IAdd(opLeft, opRight); } var opDst = RewriteOperand0(instr.Operands[0]); m.Assign(opDst, opSrc); }
private void RewriteSub(MipsInstruction instr, PrimitiveType size) { var opLeft = RewriteOperand0(instr.Operands[1]); var opRight = RewriteOperand0(instr.Operands[2]); Expression opSrc; if (opLeft.IsZero) { opSrc = m.Neg(opRight); } else if (opRight.IsZero) { opSrc = opLeft; } else { opSrc = m.ISub(opLeft, opRight); } var opDst = RewriteOperand0(instr.Operands[0]); m.Assign(opDst, opSrc); }
private void RewriteXor(MipsInstruction instr) { var opLeft = RewriteOperand0(instr.op2); var opRight = RewriteOperand0(instr.op3); Expression opSrc; if (opLeft.IsZero) { opSrc = opRight; } else if (opRight.IsZero) { opSrc = opLeft; } else { opSrc = m.Xor(opLeft, opRight); } var opDst = RewriteOperand0(instr.op1); m.Assign(opDst, opSrc); }
private void RewriteAdd(MipsInstruction instr, PrimitiveType size) { var opLeft = RewriteOperand0(instr.op2); var opRight = RewriteOperand0(instr.op3); Expression opSrc; if (opLeft.IsZero) { opSrc = opRight; } else if (opRight.IsZero) { opSrc = opLeft; } else { opSrc = m.IAdd(opLeft, opRight); } var opDst = RewriteOperand0(instr.op1); m.Assign(opDst, opSrc); }
private void RewriteBranch0(MipsInstruction instr, BinaryOperator condOp, bool link) { if (link) { emitter.Assign( frame.EnsureRegister(Registers.ra), instr.Address + 8); } var reg = RewriteOperand(instr.op1); var addr = (Address)RewriteOperand(instr.op2); if (reg is Constant) { // r0 has been replaced with '0'. if (condOp == Operator.Lt) { return; // Branch will never be taken } } var cond = new BinaryExpression(condOp, PrimitiveType.Bool, reg, Constant.Zero(reg.DataType)); cluster.Class = RtlClass.ConditionalTransfer; emitter.Branch(cond, addr, RtlClass.ConditionalTransfer | RtlClass.Delay); }
private void RewriteAnd(MipsInstruction instr) { var opLeft = RewriteOperand(instr.op2); var opRight = RewriteOperand(instr.op3); Expression opSrc; if (opLeft.IsZero) { opSrc = opLeft; } else if (opRight.IsZero) { opSrc = opRight; } else { opSrc = emitter.IAdd(opLeft, opRight); } var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, opSrc); }
public override MipsInstruction Decode(uint wInstr, MicroMipsDisassembler dasm) { foreach (var mutator in mutators) { if (!mutator(wInstr, dasm)) { return(dasm.CreateInvalidInstruction()); } } var ops = dasm.ops; var instr = new MipsInstruction { opcode = this.opcode, InstructionClass = this.iclass, op1 = ops.Count > 0 ? ops[0] : null, op2 = ops.Count > 1 ? ops[1] : null, op3 = ops.Count > 2 ? ops[2] : null, op4 = ops.Count > 3 ? ops[3] : null, }; ops.Clear(); return(instr); }
private void RewriteSave(MipsInstruction instr) { var sp = binder.EnsureRegister(arch.GetRegister(29)); int count = ((ImmediateOperand)instr.Operands[2]).Value.ToInt32(); int rt = ((RegisterOperand)instr.Operands[1]).Register.Number; int u = ((ImmediateOperand)instr.Operands[0]).Value.ToInt32(); bool gp = false; int i = 0; while (i != count) { var this_rt = (gp && (i + 1 == count)) ? 28 : rt + i < 32 ? rt + i : rt + i - 16; var reg = binder.EnsureRegister(arch.GetRegister(this_rt)); var this_offset = -((i + 1) << 2); var ea = m.Mem32(m.IAddS(sp, this_offset)); m.Assign(ea, reg); ++i; } m.Assign(sp, m.ISubS(sp, u)); }
private void RewriteBranch0(MipsInstruction instr, Func <Expression, Expression, Expression> condOp, bool link) { if (link) { m.Assign( binder.EnsureRegister(Registers.ra), instr.Address + 8); } var reg = RewriteOperand0(instr.op1); var addr = (Address)RewriteOperand0(instr.op2); if (reg is Constant) { // r0 has been replaced with '0'. if (condOp == m.Lt) { return; // Branch will never be taken } } var cond = condOp(reg, Constant.Zero(reg.DataType)); rtlc = RtlClass.ConditionalTransfer; m.Branch(cond, addr, RtlClass.ConditionalTransfer | RtlClass.Delay); }
private void RewriteTrap(MipsInstruction instr, Func <Expression, Expression, Expression> op) { var op1 = RewriteOperand(instr.Operands[0]); var op2 = RewriteOperand(instr.Operands[1]); if (op != m.Eq || !cmp.Equals(op1, op2)) { m.BranchInMiddleOfInstruction( op(op1, op2).Invert(), instr.Address + instr.Length, InstrClass.ConditionalTransfer); } Expression trap; if (instr.Operands.Length == 3) { trap = host.PseudoProcedure("__trap_code", VoidType.Instance, RewriteOperand(instr.Operands[2])); } else { trap = host.PseudoProcedure("__trap", VoidType.Instance); } m.SideEffect(trap); }
private void RewriteBranch(MipsInstruction instr, Func <Expression, Expression, Expression> condOp, bool link) { if (!link) { var reg1 = RewriteOperand0(instr.Operands[0]); var reg2 = RewriteOperand0(instr.Operands[1]); var addr = (Address)RewriteOperand0(instr.Operands[2]); var cond = condOp(reg1, reg2); if (condOp == m.Eq && ((RegisterOperand)instr.Operands[0]).Register == ((RegisterOperand)instr.Operands[1]).Register) { m.Goto(addr, instr.InstructionClass & ~InstrClass.Conditional); } else { m.Branch(cond, addr, instr.InstructionClass); } } else { throw new NotImplementedException("Linked branches not implemented yet."); } }
private void RewriteBranch0(MipsInstruction instr, Func <Expression, Expression, Expression> condOp, bool link) { if (link) { m.Assign( binder.EnsureRegister(arch.LinkRegister), instr.Address + 8); } var reg = RewriteOperand0(instr.Operands[0]); var addr = (Address)RewriteOperand0(instr.Operands[1]); if (reg is Constant) { // r0 has been replaced with '0'. if (condOp == m.Lt) { iclass = InstrClass.Linear; return; // Branch will never be taken } } var cond = condOp(reg, Constant.Zero(reg.DataType)); m.Branch(cond, addr, instr.InstructionClass); }
private void RewriteBgezal(MipsInstruction instr) { // The bgezal r0,XXXX instruction is aliased to bal (branch and link, or fn call) // We handle that case here explicitly. if (((RegisterOperand)instr.Operands[0]).Register.Number == 0) { // A special case is when we call to the location after // the delay slot. This is an idiom to capture the // program counter in the la register. var dst = ((AddressOperand)instr.Operands[1]).Address; if (instr.Address.ToLinear() + 8 == dst.ToLinear()) { iclass = InstrClass.Linear; var ra = binder.EnsureRegister(arch.LinkRegister); m.Assign(ra, dst); } else { m.CallD(dst, 0); } return; } RewriteBranch0(instr, m.Ge, false); }
private void RewriteBranch(MipsInstruction instr, BinaryOperator condOp, bool link) { if (!link) { var reg1 = RewriteOperand(instr.op1); var reg2 = RewriteOperand(instr.op2); var addr = (Address)RewriteOperand(instr.op3); if (condOp == Operator.Eq && ((RegisterOperand)instr.op1).Register == ((RegisterOperand)instr.op2).Register) { cluster.Class = RtlClass.Transfer; emitter.GotoD(addr); } else { var cond = new BinaryExpression(condOp, PrimitiveType.Bool, reg1, reg2); cluster.Class = RtlClass.ConditionalTransfer; emitter.Branch(cond, addr, RtlClass.ConditionalTransfer | RtlClass.Delay); } } else throw new NotImplementedException("Linked branches not implemented yet."); }
private void RewriteSync(MipsInstruction instr) { emitter.SideEffect(host.PseudoProcedure("__sync", VoidType.Instance, this.RewriteOperand(instr.op1))); }
private void RewriteSxx(MipsInstruction instr, Func<Expression,Expression,Expression> op) { var dst = RewriteOperand(instr.op1); var src1 = RewriteOperand(instr.op2); var src2 = RewriteOperand(instr.op3); emitter.Assign( dst, emitter.Cast(dst.DataType, op(src1,src2))); }
private void RewriteMf(MipsInstruction instr, RegisterStorage reg) { var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, frame.EnsureRegister(reg)); }
private void RewriteSync(MipsInstruction instr) { m.SideEffect(host.PseudoProcedure("__sync", VoidType.Instance, this.RewriteOperand0(instr.Operands[0]))); }
private void RewriteWait(MipsInstruction instr) { m.SideEffect(host.PseudoProcedure("__wait", VoidType.Instance)); }
private void RewriteSync(MipsInstruction instr) { m.SideEffect(host.Intrinsic("__sync", true, VoidType.Instance, this.RewriteOperand0(instr.Operands[0]))); }
private void RewriteMul(MipsInstruction instr, Func<Expression,Expression,Expression> fn, PrimitiveType ret) { var hilo = frame.EnsureSequence( frame.EnsureRegister(Registers.hi), frame.EnsureRegister(Registers.lo), ret); emitter.Assign( hilo, fn(RewriteOperand(instr.op1), RewriteOperand(instr.op2))); }
private void RewriteTlbwi(MipsInstruction instr) { //$REVIEW: MIPS documentation mentions 'Index' register. Contact // @uxmal if you care strongly about this. m.SideEffect(host.Intrinsic("__tlbwi", true, VoidType.Instance)); }
private void RewriteLoadLinked64(MipsInstruction instr) { var opSrc = RewriteOperand(instr.op2); var opDst = RewriteOperand(instr.op1); emitter.Assign(opDst, host.PseudoProcedure("__load_linked_64", PrimitiveType.Word64, opSrc)); }
private void RewriteSwr(MipsInstruction instr) { var opDst = RewriteOperand(instr.op2); var opSrc = RewriteOperand(instr.op1); emitter.Assign(opDst, host.PseudoProcedure("__swr", PrimitiveType.Word32, opSrc)); }
private void RewriteJump(MipsInstruction instr) { var dst = RewriteOperand(instr.op1); cluster.Class = RtlClass.Transfer; emitter.GotoD(dst); }
private void RewriteMf(MipsInstruction instr, RegisterStorage reg) { var opDst = RewriteOperand0(instr.op1); m.Assign(opDst, binder.EnsureRegister(reg)); }
private void RewriteSdbbp(MipsInstruction instr) { var arg = RewriteOperand(instr.Operands[0]); m.SideEffect(host.Intrinsic("__software_debug_breakpoint", true, VoidType.Instance, arg), iclass); }
private void RewriteMt(MipsInstruction instr, RegisterStorage reg) { var opSrc = RewriteOperand0(instr.op1); m.Assign(binder.EnsureRegister(reg), opSrc); }
private void RewriteMtc1(MipsInstruction instr) { m.Assign(RewriteOperand0(instr.op2), RewriteOperand0(instr.op1)); }
private void RewriteWait(MipsInstruction instr) { m.SideEffect(host.Intrinsic("__wait", true, VoidType.Instance)); }
private void RewriteSxx(MipsInstruction instr, Operator op) { var dst = RewriteOperand(instr.op1); var src1 = RewriteOperand(instr.op2); var src2 = RewriteOperand(instr.op3); emitter.Assign( dst, emitter.Cast( dst.DataType, new BinaryExpression( op, PrimitiveType.Bool, src1, src2))); }
private void RewriteSyscall(MipsInstruction instr) { m.SideEffect(host.Intrinsic(IntrinsicProcedure.Syscall, true, VoidType.Instance, this.RewriteOperand0(instr.Operands[0]))); }
private void RewriteSub(MipsInstruction instr) { var opDst = RewriteOperand(instr.op1); var opSrc = RewriteOperand(instr.op2); var opShift = RewriteOperand(instr.op3); emitter.Assign(opDst, emitter.ISub(opSrc, opShift)); }
private void RewriteTlbwr(MipsInstruction instr) { //$REVIEW: MIPS documentation mentions 'Index' register. Contact // @uxmal if you care strongly about this. m.SideEffect(host.PseudoProcedure("__tlbwr", VoidType.Instance)); }
private void RewriteReadHardwareRegister(MipsInstruction instr) { var rdhwr = host.PseudoProcedure("__read_hardware_register", PrimitiveType.UInt32, this.RewriteOperand0(instr.Operands[1])); m.Assign(this.RewriteOperand0(instr.Operands[0]), rdhwr); }
private void RewriteMt(MipsInstruction instr, RegisterStorage reg) { var opSrc = RewriteOperand(instr.op1); emitter.Assign(frame.EnsureRegister(reg), opSrc); }
private void RewriteStore(MipsInstruction instr) { var opSrc = RewriteOperand(instr.op1); var opDst = RewriteOperand(instr.op2); if (opDst.DataType.Size < opSrc.DataType.Size) opSrc = emitter.Cast(opDst.DataType, opSrc); emitter.Assign(opDst, opSrc); }
private void RewriteMtc1(MipsInstruction instr) { m.Assign(RewriteOperand0(instr.Operands[1]), RewriteOperand0(instr.Operands[0])); }
private void RewriteLwl(MipsInstruction instr) { var opDst = RewriteOperand(instr.op1); var opSrc = RewriteOperand(instr.op2); emitter.Assign(opDst, PseudoProc("__lwl", PrimitiveType.Word32, opSrc)); }
protected void EmitUnitTest(MipsInstruction instr) { var testGenSvc = arch.Services.GetService <ITestGenerationService>(); testGenSvc?.ReportMissingRewriter("MipsRw", instr, rdr, ""); }
private void RewriteJr(MipsInstruction instr) { cluster.Class = RtlClass.Transfer; var dst = RewriteOperand(instr.op1); var reg = (RegisterStorage)((Identifier)dst).Storage; if (reg == Registers.ra) { emitter.ReturnD(0, 0); } else { emitter.GotoD(dst); } }