Пример #1
0
        private void RewriteDacDsb(string intrinsicName)
        {
            var opLeft  = Operand(instr.Operands[0]);
            var opRight = Operand(instr.Operands[0]);

            var c = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.st, (uint)FlagM.CF));

            m.Assign(c, host.PseudoProcedure(
                         intrinsicName,
                         PrimitiveType.Bool,
                         opLeft,
                         opRight,
                         c,
                         m.Out(opLeft.DataType, opLeft)));
            CNZ(opLeft);
        }
Пример #2
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand iop:
                return(iop.Value);

            case AddressOperand aop:
                return(aop.Address);

            case MemoryOperand mop:
                Expression ea;
                if (mop.Base != null)
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (mop.Offset != 0)
                    {
                        ea = m.IAddS(ea, mop.Offset);
                    }
                }
                else
                {
                    ea = m.Ptr32((uint)mop.Offset);
                }
                if (mop.Index != null)
                {
                    var idx = binder.EnsureRegister(mop.Index);
                    ea = m.IAdd(ea, idx);
                }
                return(m.Mem(op.Width, ea));

            case BitOperand bit:
                var bitSrc = RewriteSrc(bit.Operand);
                return(host.PseudoProcedure(
                           "__bit",
                           PrimitiveType.Bool,
                           bitSrc,
                           Constant.Byte((byte)bit.BitPosition)));

            case FlagGroupOperand fop:
                return(binder.EnsureFlagGroup(fop.FlagGroup));

            default:
                throw new NotImplementedException($"Rl87Rewriter: operand type {op.GetType().Name} not implemented yet.");
            }
        }
Пример #3
0
        private void OperandDst(MachineOperand op, Action <Expression, Expression> write, Expression src)
        {
            switch (op)
            {
            case RegisterOperand rop:
                write(binder.EnsureRegister(rop.Register), src);
                return;

            case MemoryOperand mem:
                write(RewriteMemoryOperand(mem), src);
                MaybeEmitIncrement(mem);
                return;

            case RegisterPairOperand pair:
                write(binder.EnsureSequence(PrimitiveType.Word64, pair.HighRegister, pair.LowRegister), src);
                return;

            case DecoratorOperand dec:
                if (dec.Width.BitSize < dec.Operand.Width.BitSize)
                {
                    var dst = binder.EnsureRegister(((RegisterOperand)dec.Operand).Register);
                    var dt  = PrimitiveType.CreateWord(32 - dec.Width.BitSize);
                    if (dec.BitOffset == 0)
                    {
                        var hi = m.Slice(dt, dst, dec.Width.BitSize);
                        write(dst, m.Seq(hi, src));
                    }
                    else
                    {
                        var lo = m.Slice(dt, dst, 0);
                        write(dst, m.Seq(src, lo));
                    }
                    return;
                }
                break;

            case ApplicationOperand app:
                var appOps = app.Operands.Select(OperandSrc).Concat(new[] { src }).ToArray();
                m.SideEffect(host.PseudoProcedure(app.Mnemonic.ToString(), VoidType.Instance, appOps));
                return;
            }
            throw new NotImplementedException($"Hexagon rewriter for {op.GetType().Name} not implemented yet.");
        }
Пример #4
0
        private void RewriteFninit()
        {
            var ppp = host.PseudoProcedure("__fninit", VoidType.Instance);

            m.SideEffect(ppp);
        }
Пример #5
0
 private void RewriteBrk()
 {
     m.SideEffect(host.PseudoProcedure("__brk", VoidType.Instance));
 }
Пример #6
0
        private Expression Rol(Expression a, Expression b)
        {
            var intrinsic = host.PseudoProcedure(PseudoProcedure.RolC, a.DataType, a, b);

            return(intrinsic);
        }
Пример #7
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                rtlc       = new RtlInstructionCluster(dasm.Current.Address, dasm.Current.Length);
                rtlc.Class = RtlClass.Linear;
                emitter    = new RtlEmitter(rtlc.Instructions);
                switch (dasm.Current.Code)
                {
                default: throw new AddressCorrelatedException(
                              dasm.Current.Address,
                              "Rewriting of Z80 instruction '{0}' not implemented yet.",
                              dasm.Current.Code);

                case Opcode.adc: RewriteAdc(); break;

                case Opcode.add: RewriteAdd(); break;

                case Opcode.and: RewriteAnd(); break;

                case Opcode.bit: RewriteBit(); break;

                case Opcode.call: RewriteCall(dasm.Current); break;

                case Opcode.ccf: RewriteCcf(); break;

                case Opcode.cp: RewriteCp(); break;

                case Opcode.cpd: RewriteCp(emitter.ISub, false);  break;

                case Opcode.cpdr: RewriteCp(emitter.ISub, true);   break;

                case Opcode.cpi: RewriteCp(emitter.IAdd, false);  break;

                case Opcode.cpir: RewriteCp(emitter.IAdd, true);   break;

                case Opcode.cpl: RewriteCpl(); break;

                case Opcode.di: RewriteDi(); break;

                case Opcode.daa: RewriteDaa(); break;

                case Opcode.dec: RewriteDec(); break;

                case Opcode.djnz: RewriteDjnz(dasm.Current.Op1); break;

                case Opcode.ei: RewriteEi(); break;

                case Opcode.ex: RewriteEx(); break;

                case Opcode.exx: RewriteExx(); break;

                case Opcode.hlt: emitter.SideEffect(host.PseudoProcedure("__hlt", VoidType.Instance)); break;

                case Opcode.@in: RewriteIn(); break;

                case Opcode.ind:  RewriteIn(emitter.ISub, false); break;

                case Opcode.indr: RewriteIn(emitter.ISub, true); break;

                case Opcode.ini: RewriteIn(emitter.IAdd, false); break;

                case Opcode.inir: RewriteIn(emitter.IAdd, true); break;

                case Opcode.im:
                    emitter.SideEffect(host.PseudoProcedure("__im", VoidType.Instance, RewriteOp(dasm.Current.Op1)));
                    break;

                case Opcode.inc: RewriteInc(); break;

                case Opcode.jp: RewriteJp(dasm.Current); break;

                case Opcode.jr: RewriteJr(); break;

                case Opcode.ld: emitter.Assign(
                        RewriteOp(dasm.Current.Op1),
                        RewriteOp(dasm.Current.Op2));
                    break;

                case Opcode.rl: RewriteRotation(PseudoProcedure.RolC, true); break;

                case Opcode.rla: RewriteRotation(PseudoProcedure.Rol, false); break;

                case Opcode.rlc: RewriteRotation(PseudoProcedure.RolC, false); break;

                case Opcode.rlca: RewriteRotation(PseudoProcedure.RolC, false); break;

                case Opcode.rr: RewriteRotation(PseudoProcedure.RorC, true); break;

                case Opcode.rra: RewriteRotation(PseudoProcedure.Ror, true); break;

                case Opcode.rrc: RewriteRotation(PseudoProcedure.RorC, true); break;

                case Opcode.rrca: RewriteRotation(PseudoProcedure.RorC, true); break;

                case Opcode.ldd: RewriteBlockInstruction(emitter.ISub, false); break;

                case Opcode.lddr: RewriteBlockInstruction(emitter.ISub, true); break;

                case Opcode.ldi: RewriteBlockInstruction(emitter.IAdd, false); break;

                case Opcode.ldir: RewriteBlockInstruction(emitter.IAdd, true); break;

                case Opcode.neg: RewriteNeg(); break;

                case Opcode.nop: emitter.Nop(); break;

                case Opcode.or: RewriteOr(); break;

                case Opcode.@out: RewriteOut(); break;

                case Opcode.pop: RewritePop(); break;

                case Opcode.push: RewritePush(dasm.Current); break;

                case Opcode.res: RewriteResSet("__res"); break;

                case Opcode.ret: RewriteRet(); break;

                case Opcode.rst: RewriteRst(); break;

                case Opcode.sbc: RewriteSbc(); break;

                case Opcode.scf: RewriteScf(); break;

                case Opcode.set: RewriteResSet("__set"); break;

                case Opcode.sla: RewriteShift(dasm.Current, emitter.Shl); break;

                case Opcode.sra: RewriteShift(dasm.Current, emitter.Sar); break;

                case Opcode.srl: RewriteShift(dasm.Current, emitter.Shr); break;

                case Opcode.sub: RewriteSub(); break;

                case Opcode.xor: RewriteXor(); break;

                //$TODO: Not implemented yet; feel free to implement these!
                case Opcode.ex_af: goto default;

                case Opcode.otdr: goto default;

                case Opcode.otir: goto default;

                case Opcode.outd: goto default;

                case Opcode.outi: goto default;

                case Opcode.outr: goto default;

                case Opcode.reti: goto default;

                case Opcode.retn: goto default;

                case Opcode.rld: goto default;

                case Opcode.rrd: goto default;

                case Opcode.swap: goto default;
                }
                yield return(rtlc);
            }
        }
Пример #8
0
 private Expression Dadd(Expression a, Expression b)
 {
     return(host.PseudoProcedure("__dadd", a.DataType, a, b));
 }
Пример #9
0
        private void RewriteRotate(string rot)
        {
            var dst = OpSrc(instr.Operand1);

            m.Assign(dst, host.PseudoProcedure(rot, dst.DataType, dst, m.Byte(1)));
        }
Пример #10
0
 private Expression Rol1(Expression e)
 {
     return(host.PseudoProcedure(PseudoProcedure.Rol, e.DataType, e, Constant.Byte(1)));
 }
Пример #11
0
        private void ParseStatement()
        {
            if (!EatSpaces())
            {
                return;
            }
            byte b = line[i++];

            switch ((Token)b)
            {
            case Token.END:
                var c = new ProcedureCharacteristics {
                    Terminates = true
                };
                var ppp = host.PseudoProcedure("__End", c, VoidType.Instance);
                m.SideEffect(ppp);
                i = line.Length;        // We never return from end.
                return;

            case Token.CLOSE:
                RewriteClose();
                break;

            case Token.CLR:
                RewriteClr();
                break;

            case Token.FOR:
                RewriteFor();
                break;

            case Token.GET:
                RewriteGet();
                break;

            case Token.GOSUB:
                RewriteGosub();
                break;

            case Token.GOTO:
                RewriteGoto();
                break;

            case Token.IF:
                RewriteIf();
                break;

            case Token.INPUT:
                RewriteInput();
                break;

            case Token.INPUT_hash:
                RewriteInput_hash();
                break;

            case Token.NEXT:
                RewriteNext();
                break;

            case Token.OPEN:
                RewriteOpen();
                break;

            case Token.POKE:
                RewritePoke();
                break;

            case Token.PRINT:
                RewritePrint();
                break;

            case Token.PRINT_hash:
                RewritePrint_hash();
                break;

            case Token.REM:
                //$TODO: annotation
                i = line.Length;
                return;

            case Token.RETURN:
                RewriteReturn();
                break;

            case Token.SYS:
                RewriteSys();
                break;

            case Token.COLON:
                // Statement separator.
                break;

            default:
                if (0x41 <= b && b <= 0x5A)
                {
                    --i;
                    RewriteLet();
                    break;
                }
                throw new NotImplementedException(string.Format(
                                                      "Unimplemented BASIC token {0:X2} [{1}].",
                                                      (int)line[i - 1],
                                                      C64BasicInstruction.TokenToString(b)));
            }
        }
Пример #12
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                var addr = dasm.Current.Address;
                var len  = dasm.Current.Length;
                this.rtlc = dasm.Current.InstructionClass;
                var rtlInstructions = new List <RtlInstruction>();
                m = new RtlEmitter(rtlInstructions);
                switch (dasm.Current.Mnemonic)
                {
                default: throw new AddressCorrelatedException(
                              dasm.Current.Address,
                              "Z80 instruction '{0}' is not supported yet.",
                              dasm.Current.Mnemonic);

                case Mnemonic.illegal: m.Invalid(); break;

                case Mnemonic.adc: RewriteAdc(); break;

                case Mnemonic.add: RewriteAdd(); break;

                case Mnemonic.and: RewriteAnd(); break;

                case Mnemonic.bit: RewriteBit(); break;

                case Mnemonic.call: RewriteCall(dasm.Current); break;

                case Mnemonic.ccf: RewriteCcf(); break;

                case Mnemonic.cp: RewriteCp(); break;

                case Mnemonic.cpd: RewriteCp(m.ISub, false);  break;

                case Mnemonic.cpdr: RewriteCp(m.ISub, true);   break;

                case Mnemonic.cpi: RewriteCp(m.IAdd, false);  break;

                case Mnemonic.cpir: RewriteCp(m.IAdd, true);   break;

                case Mnemonic.cpl: RewriteCpl(); break;

                case Mnemonic.di: RewriteDi(); break;

                case Mnemonic.daa: RewriteDaa(); break;

                case Mnemonic.dec: RewriteDec(); break;

                case Mnemonic.djnz: RewriteDjnz(dasm.Current.Operands[0]); break;

                case Mnemonic.ei: RewriteEi(); break;

                case Mnemonic.ex: RewriteEx(); break;

                case Mnemonic.ex_af: RewriteExAf(); break;

                case Mnemonic.exx: RewriteExx(); break;

                case Mnemonic.hlt: RewriteHlt(); break;

                case Mnemonic.@in: RewriteIn(); break;

                case Mnemonic.ind:  RewriteIn(m.ISub, false); break;

                case Mnemonic.indr: RewriteIn(m.ISub, true); break;

                case Mnemonic.ini: RewriteIn(m.IAdd, false); break;

                case Mnemonic.inir: RewriteIn(m.IAdd, true); break;

                case Mnemonic.im:
                    m.SideEffect(host.PseudoProcedure("__im", VoidType.Instance, RewriteOp(dasm.Current.Operands[0])));
                    break;

                case Mnemonic.inc: RewriteInc(); break;

                case Mnemonic.jp: RewriteJp(dasm.Current); break;

                case Mnemonic.jr: RewriteJr(); break;

                case Mnemonic.ld: RewriteLd();  break;

                case Mnemonic.rl: RewriteRotation(PseudoProcedure.RolC, true); break;

                case Mnemonic.rla: RewriteRotation(PseudoProcedure.RolC, true); break;

                case Mnemonic.rlc: RewriteRotation(PseudoProcedure.Rol, false); break;

                case Mnemonic.rlca: RewriteRotation(PseudoProcedure.Rol, false); break;

                case Mnemonic.rr: RewriteRotation(PseudoProcedure.RorC, true); break;

                case Mnemonic.rra: RewriteRotation(PseudoProcedure.RorC, true); break;

                case Mnemonic.rrc: RewriteRotation(PseudoProcedure.Ror, true); break;

                case Mnemonic.rrca: RewriteRotation(PseudoProcedure.Ror, true); break;

                case Mnemonic.ldd: RewriteBlockInstruction(m.ISub, false); break;

                case Mnemonic.lddr: RewriteBlockInstruction(m.ISub, true); break;

                case Mnemonic.ldi: RewriteBlockInstruction(m.IAdd, false); break;

                case Mnemonic.ldir: RewriteBlockInstruction(m.IAdd, true); break;

                case Mnemonic.neg: RewriteNeg(); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.or: RewriteOr(); break;

                case Mnemonic.@out: RewriteOut(); break;

                case Mnemonic.pop: RewritePop(); break;

                case Mnemonic.push: RewritePush(dasm.Current); break;

                case Mnemonic.res: RewriteResSet("__res"); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.rst: RewriteRst(); break;

                case Mnemonic.sbc: RewriteSbc(); break;

                case Mnemonic.scf: RewriteScf(); break;

                case Mnemonic.set: RewriteResSet("__set"); break;

                case Mnemonic.sla: RewriteShift(dasm.Current, m.Shl); break;

                case Mnemonic.sra: RewriteShift(dasm.Current, m.Sar); break;

                case Mnemonic.srl: RewriteShift(dasm.Current, m.Shr); break;

                case Mnemonic.sub: RewriteSub(); break;

                case Mnemonic.xor: RewriteXor(); break;

                //$TODO: Not implemented yet; feel free to implement these!
                case Mnemonic.otdr: goto default;

                case Mnemonic.otir: goto default;

                case Mnemonic.outd: goto default;

                case Mnemonic.outi: goto default;

                case Mnemonic.outr: goto default;

                case Mnemonic.reti: goto default;

                case Mnemonic.retn: goto default;

                case Mnemonic.rld: goto default;

                case Mnemonic.rrd: goto default;

                case Mnemonic.swap: goto default;
                }
                yield return(new RtlInstructionCluster(addr, len, rtlInstructions.ToArray())
                {
                    Class = rtlc
                });
            }
        }
Пример #13
0
 private void RewriteCsync()
 {
     m.SideEffect(host.PseudoProcedure("__csync", VoidType.Instance));
 }
Пример #14
0
        private Expression Operand(MachineOperand op)
        {
            var rop = op as RegisterOperand;

            if (rop != null)
            {
                return(frame.EnsureRegister(rop.Register));
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(immOp.Value);
            }
            var shOp = op as ShiftOperand;

            if (shOp != null)
            {
                var r  = Operand(shOp.Operand);
                var sh = Operand(shOp.Shift);
                switch (shOp.Opcode)
                {
                case Opcode.lsl: return(emitter.Shl(r, sh));

                case Opcode.lsr: return(emitter.Shr(r, sh));

                case Opcode.asr: return(emitter.Sar(r, sh));

                case Opcode.ror: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, r, sh));

                default: throw new NotSupportedException(string.Format("Unsupported shift operation {0}.", shOp.Opcode));
                }
            }
            var memOp = op as ArmMemoryOperand;

            if (memOp != null)
            {
                Expression baseReg = frame.EnsureRegister(memOp.Base);
                Expression ea      = baseReg;
                if (memOp.Base.Number == 0x0F)  // PC-relative address
                {
                    var imm = memOp.Offset as ArmImmediateOperand;
                    if (imm != null)
                    {
                        if (memOp.Writeback)
                        {
                            throw new NotImplementedException();
                        }
                        var dst = (uint)((int)instr.Address.ToUInt32() + imm.Value.ToInt32()) + 8u;

                        return(emitter.Load(memOp.Width, Address.Ptr32(dst)));
                    }
                }
                if (memOp.Offset != null && memOp.Preindexed)
                {
                    var offset = Operand(memOp.Offset);
                    ea = memOp.Subtract
                        ? emitter.ISub(ea, offset)
                        : emitter.IAdd(ea, offset);
                }
                if (memOp.Preindexed && memOp.Writeback)
                {
                    emitter.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(emitter.Load(memOp.Width, ea));
            }
            throw new NotSupportedException(string.Format("Unsupported operand {0}.", op));
        }
Пример #15
0
 private void RewriteBrk()
 {
     rtlc = RtlClass.Linear;
     m.SideEffect(host.PseudoProcedure("__brk", VoidType.Instance));
 }