private Identifier RegisterPair(RegisterStorage reg) { return(binder.EnsureSequence( PrimitiveType.Word16, reg, arch.GpRegs[reg.Number - 1])); }
private Identifier RegisterPair(MachineOperand operand) { var regN = ((RegisterOperand)operand).Register; var regN1 = arch.GetRegister(regN.Number + 1); var regPair = binder.EnsureSequence(PrimitiveType.Word16, regN1, regN); return(regPair); }
private Expression RewriteDoubleRegister(MachineOperand op) { var reg = ((RegisterOperand)op).Register; var iReg = reg.Number - Registers.FloatRegisters[0].Number; var regLo = Registers.FloatRegisters[iReg + 1]; return(binder.EnsureSequence(PrimitiveType.Word64, reg, regLo)); }
private void RewriteMul() { var a = binder.EnsureRegister(Registers.A); var b = binder.EnsureRegister(Registers.B); var ab = binder.EnsureSequence(PrimitiveType.Word16, Registers.B, Registers.A); m.Assign(ab, m.UMul(a, b)); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.PSW, (uint)FlagM.P)), m.Cond(ab)); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.PSW, (uint)FlagM.OV)), m.Ugt(ab, m.Word16(0xFF))); m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.PSW, (uint)FlagM.C)), Constant.False()); }
private Identifier?FpRegPair(int iop, PrimitiveType dt) { var reghi = ((RegisterOperand)instr.Operands[iop]).Register; var iregLo = reghi.Number - Registers.FpRegisters[0].Number + 1; if (iregLo >= Registers.FpRegisters.Length) { return(null); } var reglo = Registers.FpRegisters[iregLo]; return(binder.EnsureSequence(dt, reghi, reglo)); }
private void RewriteMaci() { var src1 = Reg(instrCur.Operands[0]); var src2 = Imm(instrCur.Operands[1]); var mul = m.IMul(src1, src2); mul.DataType = PrimitiveType.Word64; var product = binder.CreateTemporary(mul.DataType); m.Assign(product, mul); var hi_lo = binder.EnsureSequence(mul.DataType, Registers.machi, Registers.maclo); m.Assign(hi_lo, m.IAdd(hi_lo, product)); }
private Expression RewriteOp(int iOp) { switch (instr.Operands[iOp]) { case RegisterOperand reg: if (reg.Register == Registers.pc) { return(instr.Address); } else { return(binder.EnsureRegister(reg.Register)); } case ImmediateOperand imm: return(imm.Value); case AddressOperand addr: return(addr.Address); case MemoryOperand mem: return(RewriteMemoryOperand(mem)); case RegisterImmediateOperand regimm: { var innerReg = binder.EnsureRegister(regimm.Register); switch (regimm.Mnemonic) { case Mnemonic.lsl: return(regimm.Value != 0 ? m.Shl(innerReg, regimm.Value) : (Expression)innerReg); case Mnemonic.lsr: return(regimm.Value != 0 ? m.Shl(innerReg, regimm.Value) : (Expression)innerReg); default: throw new NotImplementedException($"{regimm.Mnemonic} not implemented yet."); } } case RegisterPairOperand pair: var idPair = binder.EnsureSequence(pair.Width, pair.HiRegister, pair.LoRegister); return(idPair); } throw new NotImplementedException($"AVR32 operand type {instr.Operands[iOp].GetType()} not implemented yet."); }
public HExpr EnsureSequence(int regHi, int regLo, BaseType size) { var hi = regs[regHi]; var lo = regs[regLo]; var id = frame.EnsureSequence(Interop.DataTypes[size], hi, lo); return(m.MapToHandle(id)); }
public void TrashSequence() { Identifier es = frame.EnsureRegister(Registers.es); Identifier bx = frame.EnsureRegister(Registers.bx); Identifier es_bx = frame.EnsureSequence(es.Storage, bx.Storage, PrimitiveType.Pointer32); tsh.Trash(es_bx, trash); Assert.AreEqual("(bx:TRASH) (es:TRASH) (Sequence es:bx:TRASH) ", Dump(tsh.TrashedRegisters)); }
public Expression VisitSequenceStorage(SequenceStorage seq) { var exps = seq.Elements.Select(e => e.Accept(this) as Identifier).ToArray(); if (exps.All(e => e != null)) { return(binder.EnsureSequence(seq.DataType, exps.Select(i => i !.Storage).ToArray())); } throw new NotImplementedException("Handle case when stack parameter is passed."); }
private Expression?OperandSrc(MachineOperand op) { switch (op) { case RegisterOperand rop: return(binder.EnsureRegister(rop.Register)); case ImmediateOperand imm: return(imm.Value); case AddressOperand addr: return(addr.Address); case ApplicationOperand app: return(RewriteApplication(app)); case MemoryOperand mem: var src = RewriteMemoryOperand(mem); MaybeEmitIncrement(mem); return(src); case RegisterPairOperand pair: return(binder.EnsureSequence(PrimitiveType.Word64, pair.HighRegister, pair.LowRegister)); case DecoratorOperand dec: return(RewriteDecorator(dec)); } throw new NotImplementedException($"Hexagon rewriter for {op.GetType().Name} not implemented yet."); }
private Identifier ExtendedRegister(RegisterRange range) { int nRegs = range.MaxRegister - range.MinRegister + 1; var regSequence = new Storage[nRegs]; int bitsize = 0; for (int i = 0; i < nRegs; ++i) { var reg = range.Registers[range.MaxRegister - i]; regSequence[i] = reg; bitsize += reg.DataType.BitSize; } var dt = PrimitiveType.CreateWord(bitsize); return(binder.EnsureSequence(dt, regSequence)); }
private Expression RewriteSrcOp(int iOp, PrimitiveType width) { var op = dasm.Current.Operands[iOp]; var regOp = op as RegisterOperand; if (regOp != null) { var reg = binder.EnsureRegister(regOp.Register); if (reg == null) { return(null); } if (width.Size == 4) { return(reg); } else if (width.Size == 8) { var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain); if (rHi == null) { return(null); } var regHi = binder.EnsureRegister(rHi); return(binder.EnsureSequence(regHi.Storage, reg.Storage, width)); } else if (width.Size == 16) { var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain)); var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain)); var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain)); var regLo = binder.EnsureSequence(regHi1.Storage, reg.Storage, PrimitiveType.Word64); var regHi = binder.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64); return(binder.EnsureSequence(regHi.Storage, regLo.Storage, width)); } else { return(m.Cast(width, reg)); } } var immOp = op as ImmediateOperand; if (immOp != null) { return(immOp.Value); } var memOp = op as MemoryOperand; if (memOp != null) { Expression ea; if (memOp.Base != null) { var reg = binder.EnsureRegister(memOp.Base); if (memOp.AutoDecrement) { m.Assign(reg, m.ISub(reg, width.Size)); } else if (memOp.AutoIncrement) { var tmp = binder.CreateTemporary(reg.DataType); m.Assign(tmp, reg); reg = tmp; } ea = reg; if (memOp.Offset != null) { ea = m.IAdd(ea, memOp.Offset); } if (memOp.Index != null) { Expression idx = binder.EnsureRegister(memOp.Index); if (width.Size != 1) { idx = m.IMul(idx, Constant.Int32(width.Size)); } ea = m.IAdd(ea, idx); } Expression load; if (memOp.Deferred) { load = m.Mem(width, m.Mem32(ea)); } else { load = m.Mem(width, ea); } if (memOp.AutoIncrement) { if (memOp.AutoIncrement) { reg = binder.EnsureRegister(memOp.Base); int inc = (memOp.Deferred) ? 4 : width.Size; m.Assign(reg, m.IAdd(reg, inc)); } } return(load); } else { } } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } throw new NotImplementedException(op.GetType().Name); }
public Expression RewriteDst( MachineOperand operand, Address addrInstr, PrimitiveType dataWidth, Expression src, Func <Expression, Expression, Expression> opGen) { var reg = operand as RegisterOperand; if (reg != null) { Expression r = binder.EnsureRegister(reg.Register); Expression tmp = r; if (dataWidth != null && reg.Width.BitSize > dataWidth.BitSize && reg.Width.Domain != Domain.Real) { Expression rSub = m.Cast(dataWidth, r); var srcExp = opGen(src, rSub); if (srcExp is Identifier || srcExp is Constant || srcExp is DepositBits) { tmp = srcExp; } else { tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, srcExp); } src = m.Dpb(r, tmp, 0); } else { src = opGen(src, r); } m.Assign(r, src); return(tmp); } var dbl = operand as DoubleRegisterOperand; if (dbl != null) { Identifier h = binder.EnsureRegister(dbl.Register1); Identifier l = binder.EnsureRegister(dbl.Register2); var d = binder.EnsureSequence(h.Storage, l.Storage, PrimitiveType.Word64); var result = opGen(src, l); m.Assign(d, result); return(d); } var addr = operand as M68kAddressOperand; if (addr != null) { var load = m.Mem(dataWidth, addr.Address); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(src, load)); m.Assign(load, tmp); return(tmp); } var mem = operand as MemoryOperand; if (mem != null) { var load = RewriteMemoryAccess(mem, dataWidth, addrInstr); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(src, load)); m.Assign(load, tmp); return(tmp); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(src, m.Mem(dataWidth, r))); m.Assign(m.Mem(dataWidth, r), tmp); m.Assign(r, m.IAdd(r, m.Int32(dataWidth.Size))); return(tmp); } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var r = binder.EnsureRegister(pre.Register); src = Spill(src, r); m.Assign(r, m.ISub(r, m.Int32(dataWidth.Size))); var load = m.Mem(dataWidth, r); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(src, load)); m.Assign(m.Mem(dataWidth, r), tmp); return(tmp); } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = binder.EnsureRegister(indidx.ARegister); if (indidx.Imm8 != 0) { ea = m.IAdd(ea, Constant.Int32(indidx.Imm8)); } Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } var load = m.Mem(dataWidth, m.IAdd(ea, ix)); var tmp = binder.CreateTemporary(dataWidth); m.Assign(tmp, opGen(src, load)); m.Assign(load, tmp); return(tmp); } return(null); }
private Expression RewriteSrcOp(int iOp, PrimitiveType width) { var op = this.instr.Operands[iOp]; switch (op) { case RegisterOperand regOp: var reg = binder.EnsureRegister(regOp.Register); if (reg == null) { return(null); } if (width.Size == 4) { return(reg); } else if (width.Size == 8) { var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain); if (rHi == null) { return(null); } var regHi = binder.EnsureRegister(rHi); return(binder.EnsureSequence(width, regHi.Storage, reg.Storage)); } else if (width.Size == 16) { var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain)); var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain)); var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain)); var regLo = binder.EnsureSequence(PrimitiveType.Word64, regHi1.Storage, reg.Storage); var regHi = binder.EnsureSequence(PrimitiveType.Word64, regHi3.Storage, regHi2.Storage); return(binder.EnsureSequence(width, regHi.Storage, regLo.Storage)); } else { return(m.Slice(width, reg, 0)); } case ImmediateOperand immOp: return(immOp.Value); case MemoryOperand memOp: Expression ea; if (memOp.Base != null) { reg = binder.EnsureRegister(memOp.Base); if (memOp.AutoDecrement) { m.Assign(reg, m.ISub(reg, width.Size)); } else if (memOp.AutoIncrement) { var tmp = binder.CreateTemporary(reg.DataType); m.Assign(tmp, reg); reg = tmp; } ea = reg; if (memOp.Offset != null) { if (memOp.Offset.DataType.BitSize < ea.DataType.BitSize) { ea = m.IAddS(ea, memOp.Offset.ToInt32()); } else { ea = m.IAdd(ea, memOp.Offset); } } if (memOp.Index != null) { Expression idx = binder.EnsureRegister(memOp.Index); if (width.Size != 1) { idx = m.IMul(idx, Constant.Int32(width.Size)); } ea = m.IAdd(ea, idx); } Expression load; if (memOp.Deferred) { load = m.Mem(width, m.Mem32(ea)); } else { load = m.Mem(width, ea); } if (memOp.AutoIncrement) { reg = binder.EnsureRegister(memOp.Base); int inc = (memOp.Deferred) ? 4 : width.Size; m.Assign(reg, m.IAdd(reg, inc)); } return(load); } else { ea = arch.MakeAddressFromConstant(memOp.Offset, false); Expression load; if (memOp.Deferred) { load = m.Mem(width, m.Mem32(ea)); } else { load = m.Mem(width, ea); } return(load); } case AddressOperand addrOp: //$BUG: enabling the commented code causes huge regressions in the // unzip subject. /*if (addrOp.Width.BitSize > width.BitSize) * { * var c = addrOp.Address.ToUInt32(); * return Constant.Create(width, c); * } * else*/ { return(addrOp.Address); } } throw new NotImplementedException(op.GetType().Name); }
public Expression?RewriteDst( MachineOperand operand, Address addrInstr, PrimitiveType dataWidth, Expression src, Func <Expression, Expression, Expression> opGen) { switch (operand) { case RegisterOperand reg: { var r = binder.EnsureRegister(reg.Register); Expression tmpLo = r; if (dataWidth != null && reg.Width.BitSize > dataWidth.BitSize && !reg.Width.IsReal) { Expression rSub = m.Slice(dataWidth, r, 0); var srcExp = opGen(src, rSub); if (srcExp is Identifier || srcExp is Constant || srcExp is MkSequence) { tmpLo = srcExp; } else { tmpLo = binder.CreateTemporary(dataWidth); m.Assign(tmpLo, srcExp); } var tmpHi = binder.CreateTemporary(PrimitiveType.CreateWord(reg.Width.BitSize - tmpLo.DataType.BitSize)); m.Assign(tmpHi, m.Slice(tmpHi.DataType, r, tmpLo.DataType.BitSize)); src = m.Seq(tmpHi, tmpLo); } else { src = opGen(src, r); } m.Assign(r, src); return(tmpLo); } case DoubleRegisterOperand dbl: { Identifier h = binder.EnsureRegister(dbl.Register1); Identifier l = binder.EnsureRegister(dbl.Register2); var d = binder.EnsureSequence(PrimitiveType.Word64, h.Storage, l.Storage); var result = opGen(src, l); m.Assign(d, result); return(d); } case M68kAddressOperand addr: { var load = m.Mem(dataWidth, addr.Address); return(EmitStore(load, opGen(src, load))); } case MemoryOperand mem: { var load = RewriteMemoryAccess(mem, dataWidth, addrInstr); return(EmitStore(load, opGen(src, load))); } case PostIncrementMemoryOperand post: { var r = binder.EnsureRegister(post.Register); var access = m.Mem(dataWidth, r); var tmp = EmitStore(access, opGen(src, access)); m.Assign(r, m.IAddS(r, dataWidth.Size)); return(tmp); } case PredecrementMemoryOperand pre: { var r = binder.EnsureRegister(pre.Register); src = Spill(src, r); m.Assign(r, m.ISubS(r, dataWidth.Size)); var access = m.Mem(dataWidth, r); return(EmitStore(access, opGen(src, access))); } case IndirectIndexedOperand indidx: { Expression ea = binder.EnsureRegister(indidx.ARegister); if (indidx.Imm8 != 0) { ea = m.IAddS(ea, indidx.Imm8); } Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } var access = m.Mem(dataWidth, m.IAdd(ea, ix)); return(EmitStore(access, opGen(src, access))); } } return(null); }
public void AddSequenceArgument(SequenceStorage seq) { AddInParam(binder.EnsureSequence(seq.DataType, seq.Elements)); }