Пример #1
0
 private Identifier RegisterPair(RegisterStorage reg)
 {
     return(binder.EnsureSequence(
                PrimitiveType.Word16,
                reg,
                arch.GpRegs[reg.Number - 1]));
 }
Пример #2
0
        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);
        }
Пример #3
0
        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));
        }
Пример #4
0
 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());
 }
Пример #5
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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.");
        }
Пример #8
0
        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));
        }
Пример #9
0
        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));
        }
Пример #10
0
        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.");
        }
Пример #11
0
        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.");
        }
Пример #12
0
        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));
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }
Пример #16
0
        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);
        }
Пример #17
0
 public void AddSequenceArgument(SequenceStorage seq)
 {
     AddInParam(binder.EnsureSequence(seq.DataType, seq.Elements));
 }