Example #1
0
        public Constant GetFlagGroup(uint mask)
        {
            bool sigle = Bits.IsSingleBitSet(mask);

            if ((mask & validFlags) == mask)
            {
                if (sigle)
                {
                    return(Constant.Bool((flags & mask) != 0));
                }
                else
                {
                    return(Constant.Byte((byte)(flags & mask)));
                }
            }
            else
            {
                return(Constant.Invalid);
            }
        }
        public void CceShlRclPattern()
        {
            var p = new ProgramBuilder();

            p.Add("main", (m) =>
            {
                var C  = m.Flags("C");
                var r1 = MockReg(m, 1);
                var r2 = MockReg(m, 2);

                m.Assign(r1, m.Shl(r1, 1));
                m.Assign(C, m.Cond(r1));
                m.Assign(r2, m.Fn(
                             new PseudoProcedure(PseudoProcedure.RolC, r2.DataType, 2),
                             r2, Constant.Byte(1), C));
                m.Assign(C, m.Cond(r2));
                m.MStore(m.Word32(0x3000), r1);
                m.MStore(m.Word32(0x3004), r2);
            });
            RunTest(p, "Analysis/CceShlRclPattern.txt");
        }
Example #3
0
        public void RewriteRotation(string procName)
        {
            Expression opDst;

            if (di.op2 != null)
            {
                var opSrc = orw.RewriteSrc(di.op1, di.Address);
                opDst = orw.RewriteDst(di.op2, di.Address, opSrc, (s, d) =>
                                       host.PseudoProcedure(procName, di.dataWidth, d, s));
            }
            else
            {
                opDst = orw.RewriteDst(di.op1, di.Address,
                                       Constant.Byte(1), (s, d) =>
                                       host.PseudoProcedure(procName, PrimitiveType.Word32, d, s));
            }
            emitter.Assign(
                orw.FlagGroup(FlagM.CF | FlagM.NF | FlagM.ZF),
                emitter.Cond(opDst));
            emitter.Assign(orw.FlagGroup(FlagM.VF), Constant.False());
        }
Example #4
0
        public void CceShrRcrPattern()
        {
            var p = new ProgramBuilder(new FakeArchitecture(new ServiceContainer()));

            p.Add("main", (m) =>
            {
                var C  = m.Flags("C");
                var r1 = MockReg(m, 1);
                var r2 = MockReg(m, 2);

                m.Assign(r1, m.Shr(r1, 1));
                m.Assign(C, m.Cond(r1));
                m.Assign(r2, m.Fn(
                             new IntrinsicProcedure(IntrinsicProcedure.RorC, true, r2.DataType, 2),
                             r2, Constant.Byte(1), C));
                m.Assign(C, m.Cond(r2));
                m.MStore(m.Word32(0x3000), r2);
                m.MStore(m.Word32(0x3004), r1);
                m.Return();
            });
            RunTest(p, "Analysis/CceShrRcrPattern.txt");
        }
Example #5
0
        protected override void BuildBody()
        {
            var sp   = Frame.EnsureRegister(Registers.sp);
            var a    = Frame.EnsureRegister(Registers.a);
            var c    = Frame.EnsureRegister(Registers.c);
            var h    = Frame.EnsureRegister(Registers.h);
            var l    = Frame.EnsureRegister(Registers.l);
            var C    = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("C"));
            var Z    = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("Z"));
            var SZC  = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZC"));
            var SZP  = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZP"));
            var rorc = new IntrinsicProcedure(
                IntrinsicProcedure.RorC,
                true,
                PrimitiveType.Byte,
                3);

            Assign(sp, Frame.FramePointer);
            Label("m1Loop");
            Assign(a, h);
            Assign(a, Or(a, a));
            Assign(SZC, Cond(a));
            Assign(C, Constant.False());
            Assign(a, Shr(a, Constant.Byte(1)));
            Assign(C, Cond(a));
            Assign(h, a);
            Assign(a, l);
            Assign(a, Fn(rorc, a, Constant.Byte(1), C));
            Assign(C, Cond(a));
            Assign(l, a);
            Assign(c, ISub(c, 1));
            Assign(SZP, Cond(c));
            BranchIf(Test(ConditionCode.NE, Z), "m1Loop");

            Label("m2Done");
            MStore(Word32(0x1000), l);
            MStore(Word32(0x1001), h);
            Return();
        }
Example #6
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand regOp:
                if (regOp.Register == Registers.pc)
                {
                    return(instr.Address + instr.Length);
                }
                else
                {
                    return(binder.EnsureRegister(regOp.Register));
                }

            case ImmediateOperand immOp:
                if (dasm.Current.DataWidth !.Size == 1)
                {
                    return(Constant.Byte((byte)immOp.Value.ToInt32()));
                }
                else
                {
                    return(immOp.Value);
                }
        private ImmediateOperand GetImmediateUnsignedField(string fmt, ref int i, uint wInstr)
        {
            int offset = 0;

            while (Char.IsDigit(fmt[++i]))
            {
                offset = offset * 10 + (fmt[i] - '0');
            }
            ++i;
            int size = 0;

            while (i < fmt.Length && Char.IsDigit(fmt[i]))
            {
                size = size * 10 + (fmt[i] - '0');
                if (i >= fmt.Length)
                {
                    break;
                }
                ++i;
            }
            uint mask = (1u << size) - 1u;

            return(new ImmediateOperand(Constant.Byte((byte)((wInstr >> offset) & mask))));
        }
Example #8
0
 public PICInstructionMem2Mem(Mnemonic mnemonic, byte srcidx, byte dstidx)
     : base(mnemonic,
            new PICOperandFSRIndexation(Constant.Byte(srcidx)),
            new PICOperandFSRIndexation(Constant.Byte(dstidx)))
 {
 }
Example #9
0
        public void SefConstant()
        {
            var c = Constant.Byte(3);

            Assert.IsFalse(sef.HasSideEffect(c));
        }
Example #10
0
 public void Bctr()
 {
     Add(new PowerPcInstruction(Opcode.bcctr, new ImmediateOperand(Constant.Byte(0x20)), null, null, false));
 }
Example #11
0
 public PICInstructionMem2Mem(Mnemonic mnemonic, byte srcidx, uint dstaddr)
     : base(mnemonic,
            new PICOperandFSRIndexation(Constant.Byte(srcidx)),
            new PICOperandDataMemoryAddress(dstaddr))
 {
 }
Example #12
0
        private static Pdp11Instruction NonDoubleOperandInstruction(ushort opcode, Pdp11Disassembler dasm)
        {
            switch ((opcode >> 8))
            {
            case 0x01: return(dasm.BranchInstruction(opcode, Opcode.br));

            case 0x02: return(dasm.BranchInstruction(opcode, Opcode.bne));

            case 0x03: return(dasm.BranchInstruction(opcode, Opcode.beq));

            case 0x04: return(dasm.BranchInstruction(opcode, Opcode.bge));

            case 0x05: return(dasm.BranchInstruction(opcode, Opcode.blt));

            case 0x06: return(dasm.BranchInstruction(opcode, Opcode.bgt));

            case 0x07: return(dasm.BranchInstruction(opcode, Opcode.ble));

            case 0x80: return(dasm.BranchInstruction(opcode, Opcode.bpl));

            case 0x81: return(dasm.BranchInstruction(opcode, Opcode.bmi));

            case 0x82: return(dasm.BranchInstruction(opcode, Opcode.bhi));

            case 0x83: return(dasm.BranchInstruction(opcode, Opcode.blos));

            case 0x84: return(dasm.BranchInstruction(opcode, Opcode.bvc));

            case 0x85: return(dasm.BranchInstruction(opcode, Opcode.bvs));

            case 0x86: return(dasm.BranchInstruction(opcode, Opcode.bcc));

            case 0x87: return(dasm.BranchInstruction(opcode, Opcode.bcs));
            }

            var            dataWidth = dasm.DataWidthFromSizeBit(opcode & 0x8000u);
            int            cop       = 1;
            MachineOperand op1       = null;
            MachineOperand op2       = null;
            Opcode         oc        = Opcode.illegal;

            switch ((opcode >> 6) & 0x3FF)
            {
            case 0x000:
                switch (opcode & 0x3F)
                {
                case 0x00: cop = 0; oc = Opcode.halt; break;

                case 0x01: cop = 0; oc = Opcode.wait; break;

                case 0x02: cop = 0; oc = Opcode.rti; break;

                case 0x03: cop = 0; oc = Opcode.bpt; break;

                case 0x04: cop = 0; oc = Opcode.iot; break;

                case 0x05: cop = 0; oc = Opcode.reset; break;

                case 0x06: cop = 0; oc = Opcode.rtt; break;

                case 0x07: cop = 0; oc = Opcode.illegal; break;
                }
                break;

            case 0x001: op1 = dasm.DecodeOperand(opcode); oc = Opcode.jmp; break;

            case 0x002:
                switch (opcode & 0x38)
                {
                case 0: op1 = dasm.DecodeOperand(opcode & 7); oc = Opcode.rts; break;

                case 3: op1 = dasm.DecodeOperand(opcode); oc = Opcode.spl; break;

                case 0x20:
                case 0x28:
                case 0x30:
                case 0x38:
                    return(dasm.DecodeCondCode(opcode));
                }
                break;

            case 0x003:
                oc        = Opcode.swab; op1 = dasm.DecodeOperand(opcode);
                dataWidth = PrimitiveType.Byte;
                break;

            case 0x020:
            case 0x021:
            case 0x022:
            case 0x023:
            case 0x024:
            case 0x025:
            case 0x026:
            case 0x027:
                oc        = Opcode.jsr;
                cop       = 2;
                op1       = Reg(opcode >> 6, dasm);
                op2       = dasm.DecodeOperand(opcode);
                dataWidth = PrimitiveType.Word16;
                break;

            case 0x220:
            case 0x221:
            case 0x222:
            case 0x223:
                oc  = Opcode.emt;
                op1 = new ImmediateOperand(Constant.Byte((byte)opcode));
                break;

            case 0x224:
            case 0x225:
            case 0x226:
            case 0x227:
                oc  = Opcode.trap;
                op1 = new ImmediateOperand(Constant.Byte((byte)opcode));
                break;

            case 0x028:
            case 0x228:
                oc  = dataWidth.Size == 1 ? Opcode.clrb : Opcode.clr;
                op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x029:
            case 0x229:
                oc = Opcode.com; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02A:
            case 0x22A:
                oc = Opcode.inc; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02B:
            case 0x22B:
                oc = Opcode.dec; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02C:
            case 0x22C:
                oc = Opcode.neg; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02D:
            case 0x22D:
                oc = Opcode.adc; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02E:
            case 0x22E:
                oc = Opcode.sbc; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x02F:
            case 0x22F:
                oc = Opcode.tst; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x030:
            case 0x230:
                oc = Opcode.ror; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x031:
            case 0x231:
                oc = Opcode.rol; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x032:
            case 0x232:
                oc = Opcode.asr; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x033:
            case 0x233:
                oc = Opcode.asl; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x034:
                oc  = Opcode.mark;
                op1 = new ImmediateOperand(Constant.Byte((byte)opcode));
                break;

            case 0x234:
                oc = Opcode.mtps; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x035:
                oc = Opcode.mfpi; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x235:
                oc = Opcode.mfpd; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x036:
                oc = Opcode.mtpi; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x236:
                oc = Opcode.mtpd; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x037:
                oc = Opcode.sxt; op1 = dasm.DecodeOperand(opcode);
                break;

            case 0x237:
                oc = Opcode.mfps; op1 = dasm.DecodeOperand(opcode);
                break;
            }
            if (cop > 0 && op1 == null ||
                cop > 1 && op2 == null)
            {
                return(new Pdp11Instruction {
                    Opcode = Opcode.illegal
                });
            }
            return(new Pdp11Instruction
            {
                Opcode = oc,
                DataWidth = dataWidth,
                op1 = op1,
                op2 = op2,
            });
        }
Example #13
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                var r   = frame.EnsureRegister(memOp.Register);
                var tmp = frame.CreateTemporary(op.Width);
                switch (memOp.Mode)
                {
                default:
                    throw new AddressCorrelatedException(
                              instrs.Current.Address,
                              "Not implemented: addressing mode {0}.",
                              memOp.Mode);

                case AddressMode.RegDef:
                    return(m.Load(this.instrs.Current.DataWidth, r));

                case AddressMode.Absolute:
                    return(m.Load(
                               instrs.Current.DataWidth,
                               Address.Ptr16(memOp.EffectiveAddress)));

                case AddressMode.AutoIncr:
                    m.Assign(tmp, m.Load(op.Width, r));
                    m.Assign(r, m.IAdd(r, memOp.Width.Size));
                    break;

                case AddressMode.AutoIncrDef:
                    m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r)));
                    m.Assign(r, m.IAdd(r, memOp.Width.Size));
                    break;

                case AddressMode.AutoDecr:
                    m.Assign(r, m.ISub(r, memOp.Width.Size));
                    return(m.Load(op.Width, r));

                case AddressMode.AutoDecrDef:
                    m.Assign(r, m.ISub(r, memOp.Width.Size));
                    m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r)));
                    return(tmp);

                case AddressMode.Indexed:
                    if (memOp.Register == Registers.pc)
                    {
                        var offset   = (short)memOp.EffectiveAddress;
                        var addrBase = (long)rtlCluster.Address.ToLinear();
                        var addr     = Address.Ptr16((ushort)(2 + addrBase + offset));
                        return(m.Load(memOp.Width, addr));
                    }
                    else
                    {
                        return(m.Load(
                                   this.instrs.Current.DataWidth,
                                   m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))));
                    }

                case AddressMode.IndexedDef:
                    return(m.Load(
                               this.instrs.Current.DataWidth,
                               m.Load(
                                   PrimitiveType.Ptr16,
                                   m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))));
                }
                return(tmp);
            }
            var regOp = op as RegisterOperand;

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

            if (immOp != null)
            {
                if (instrs.Current.DataWidth.Size == 1)
                {
                    return(Constant.Byte((byte)immOp.Value.ToInt32()));
                }
                else
                {
                    return(immOp.Value);
                }
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException();
        }
Example #14
0
        void RewriteRlwinm()
        {
            var  rd        = RewriteOperand(instr.Operands[0]);
            var  rs        = RewriteOperand(instr.Operands[1]);
            byte sh        = ((Constant)RewriteOperand(instr.Operands[2])).ToByte();
            byte mb        = ((Constant)RewriteOperand(instr.Operands[3])).ToByte();
            byte me        = ((Constant)RewriteOperand(instr.Operands[4])).ToByte();
            uint maskBegin = (uint)(1ul << (32 - mb));
            uint maskEnd   = 1u << (31 - me);
            uint mask      = maskBegin - maskEnd;

            //Extract and left justify immediate    extlwi RA, RS, n, b     rlwinm RA, RS, b, 0, n-1                32 > n > 0
            //Extract and right justify immediate   extrwi RA, RS, n, b     rlwinm RA, RS, b+n, 32-n, 31            32 > n > 0 & b+n =< 32
            //Insert from left immediate            inslwi RA, RS, n, b     rlwinm RA, RS, 32-b, b, (b+n)-1         b+n <=32 & 32>n > 0 & 32 > b >= 0
            //Insert from right immediate           insrwi RA, RS, n, b     rlwinm RA, RS, 32-(b+n), b, (b+n)-1     b+n <= 32 & 32>n > 0
            //Rotate left immediate                 rotlwi RA, RS, n        rlwinm RA, RS, n, 0, 31                 32 > n >= 0
            //Rotate right immediate                rotrwi RA, RS, n        rlwinm RA, RS, 32-n, 0, 31              32 > n >= 0
            //Rotate left                           rotlw RA, RS, b         rlwinm RA, RS, RB, 0, 31                None
            //Shift left immediate                  slwi RA, RS, n          rlwinm RA, RS, n, 0, 31-n               32 > n >= 0
            //Shift right immediate                 srwi RA, RS, n          rlwinm RA, RS, 32-n, n, 31              32 > n >= 0
            //Clear left immediate                  clrlwi RA, RS, n        rlwinm RA, RS, 0, n, 31                 32 > n >= 0
            //Clear right immediate                 clrrwi RA, RS, n        rlwinm RA, RS, 0, 0, 31-n               32 > n >= 0
            //Clear left and shift left immediate   clrslwi RA, RS, b, n    rlwinm RA, RS, b-n, 31-n                b-n >= 0 & 32 > n >= 0 & 32 > b>= 0
            if (sh == 0)
            {
                m.Assign(rd, m.And(rs, Constant.UInt32(mask)));
            }
            else if (mb == 32 - sh && me == 31)
            {
                m.Assign(rd, m.Shr(rs, (byte)(32 - sh)));
            }
            else if (mb == 0 && me == 31 - sh)
            {
                m.Assign(rd, m.Shl(rs, sh));
            }
            else if (mb == 0 && me == 31)
            {
                if (sh < 16)
                {
                    m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, PrimitiveType.Word32, rs, Constant.Byte(sh)));
                }
                else
                {
                    m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, rs, Constant.Byte((byte)(32 - sh))));
                }
            }
            else if (me == 31)
            {
                int n = 32 - mb;
                int b = sh - n;
                mask = (1u << b) - 1;
                m.Assign(rd, m.And(
                             m.Shr(rs, Constant.Byte((byte)n)),
                             Constant.Word32(mask)));
            }
            else if (mb <= me)
            {
                if (me < 32 - sh)
                {
                    // [                           llll]
                    // [                        mmm....]
                    m.Assign(rd, m.And(
                                 m.Shl(rs, Constant.Byte((byte)sh)),
                                 Constant.Word32(mask)));
                    MaybeEmitCr0(rd);
                    return;
                }
                else if (mb >= 32 - sh)
                {
                    // [                        ll]
                    // [                        m.]

                    m.Assign(rd, m.And(
                                 m.Shr(rs, Constant.Byte((byte)(32 - sh))),
                                 Constant.Word32(mask)));
                    MaybeEmitCr0(rd);
                    return;
                }
            }
            else
            {
                //$TODO: yeah, this one is hard...
                m.Assign(rd,
                         host.PseudoProcedure(
                             "__rlwinm",
                             PrimitiveType.Word32,
                             rs,
                             Constant.Byte(sh),
                             Constant.Byte(mb),
                             Constant.Byte(me)));
            }

            //Error,10034E20,rlwinm	r9,r31,1D,1B,1D not handled yet.
            //Error,10028B50,rlwinm	r8,r8,04,18,1B not handled yet.
            //Error,1002641C,rlwinm	r4,r4,04,18,1B not handled yet.
            //Error,10026364,rlwinm	r4,r4,04,18,1B not handled yet.
            //Error,1003078C,rlwinm	r8,r8,04,1A,1B not handled yet.
            //Error,100294D4,rlwinm	r0,r0,04,18,1B not handled yet.
            //Error,100338A0,rlwinm	r4,r11,08,08,0F not handled yet.
            //rlwinm	r12,r2,09,1D,09
            MaybeEmitCr0(rd);
        }
Example #15
0
 private void Rewrite_CLRW()
 {
     m.Assign(Wreg, Constant.Byte(0));
     m.Assign(binder.EnsureFlagGroup(PICRegisters.Z), Constant.Bool(true));
 }
Example #16
0
        private void RewriteRldicr()
        {
            var   rd      = RewriteOperand(instr.Operands[0]);
            var   rs      = RewriteOperand(instr.Operands[1]);
            byte  sh      = ((Constant)RewriteOperand(instr.Operands[2])).ToByte();
            byte  me      = ((Constant)RewriteOperand(instr.Operands[3])).ToByte();
            ulong maskEnd = 0ul - (ulong)(1ul << (63 - me));

            // Extract double word and right justify immediate | extrdi RA, RS, n, b   | rldicl RA, RS, b + n, 64 - n   | n > 0
            // Rotate double word left immediate               | rotldi RA, RS, n      | rldicl RA, RS, n, 0            | None
            // Rotate double word right immediate              | rotrdi RA, RS, n      | rldicl RA, RS, 64 - n, 0       | None
            // Rotate double word right immediate              | srdi RA, RS, n	       | rldicl RA, RS, 64 - n, n       | n < 64
            // Clear left double word immediate                | clrldi RA, RS, n      | rldicl RA, RS, 0, n	        | n < 64
            // Extract double word and left justify immediate  | extldi RA, RS, n, b   | rldicr RA, RS, b, n - 1        | None
            // Shift left double word immediate                | sldi RA, RS, n        | rldicr RA, RS, n, 63 - n	    | None
            // Clear right double word immediate               | clrrdi RA, RS, n      | rldicr RA, RS, 0, 63 - n	    | None
            // Clear left double word and shift left immediate | clrlsldi RA, RS, b, n | rldic RA, RS, n, b - n         | None
            // Insert double word from right immediate         | insrdi RA, RS, n, b   | rldimi RA, RS, 64 - (b + n), b | None
            // Rotate double word left                         | rotld RA, RS, RB      | rldcl RA, RS, RB, 0	        | None
            if (sh + me == 63)
            {
                // sldi
                m.Assign(rd, m.Shl(rs, sh));
            }
            else if (me == 63)
            {
                // rotldi: The mask is 0b111.....111, so we have a full rotation
                m.Assign(rd, host.Intrinsic(
                             IntrinsicProcedure.Rol,
                             true,
                             PrimitiveType.Word64,
                             rs, Constant.Byte(sh)));
            }
            else if (me != 0 && sh > 0)
            {
                //$TODO: check this logic
                var wordSize = me - 1;
                if (wordSize <= 0)
                {
                    iclass = InstrClass.Invalid;
                    m.Invalid();
                    return;
                }

                var bitpos = 63 - sh;   // convert to reko's little endian bit positions.
                var dt     = PrimitiveType.CreateWord(wordSize);
                var slice  = m.Convert(m.Slice(dt, rs, bitpos), dt, rd.DataType);

                m.Assign(
                    rd,
                    m.Shl(slice, 64 - wordSize));
            }
            else if (sh == 0)
            {
                // No rotation, just mask the low bits.
                var mask = (ulong)-(1L << (63 - me));
                m.Assign(rd, m.And(rs, mask));
            }
            else
            {
                host.Error(
                    instr.Address,
                    string.Format("PowerPC instruction '{0}' is not supported yet.", instr));
                EmitUnitTest();
                iclass = InstrClass.Invalid;
                m.Invalid();
                return;
            }
            MaybeEmitCr0(rd);
        }
Example #17
0
        void RewriteRldicl()
        {
            var   rd        = RewriteOperand(instr.Operands[0]);
            var   rs        = RewriteOperand(instr.Operands[1]);
            byte  sh        = ((Constant)RewriteOperand(instr.Operands[2])).ToByte();
            byte  mb        = ((Constant)RewriteOperand(instr.Operands[3])).ToByte();
            ulong maskBegin = (ulong)(1ul << (64 - mb)) - 1;

            if (sh == 0)
            {
                m.Assign(rd, m.And(rs, Constant.Word64(maskBegin)));
            }
            else if (sh + mb == 64)
            {
                m.Assign(rd, m.Shr(rs, (byte)mb));
            }
            else if (sh == 0x3F && mb == 0x3F)
            {
                m.Assign(rd, m.Shr(rs, (byte)mb));
            }
            else if (sh < mb)
            {
                m.Assign(rd, m.And(
                             m.Shl(rs, (byte)sh),
                             maskBegin));
            }
            else if (sh == 0x39 && mb == 0x38)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x31 && mb == 0x3F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x10 && mb == 0x2F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x08 && mb == 0x37)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x18 && mb == 0x27)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x20 && mb == 0x1F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x02 && mb == 0x1E)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x38 && mb == 0x3F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x37 && mb == 0x3F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x21 && mb == 0x3F)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x08 && mb == 0x30)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x3D && mb == 0x23)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (sh == 0x3E && mb == 0x22)
            {
                m.Assign(rd, m.And(
                             m.Shr(rs, (byte)(64 - sh)),
                             maskBegin));
            }
            else if (mb == 0x00)
            {
                m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, rd.DataType, rs, Constant.Byte((byte)sh)));
            }
            else
            {
                host.Error(
                    instr.Address,
                    string.Format("PowerPC instruction '{0}' is not supported yet.", instr));
                EmitUnitTest();
                rtlc = InstrClass.Invalid;
                m.Invalid();
                return;
            }
            MaybeEmitCr0(rd);
        }
Example #18
0
        void RewriteRldicl()
        {
            var   rd        = RewriteOperand(instr.Operands[0]);
            var   rs        = RewriteOperand(instr.Operands[1]);
            byte  sh        = ((Constant)RewriteOperand(instr.Operands[2])).ToByte();
            byte  mb        = ((Constant)RewriteOperand(instr.Operands[3])).ToByte();
            ulong maskBegin = (1ul << (64 - mb)) - 1;

            if (sh == 0)
            {
                m.Assign(rd, m.And(rs, Constant.Word64(maskBegin)));
            }
            else if (sh + mb == 64)
            {
                m.Assign(rd, m.Shr(rs, mb));
            }
            else if (sh == 0x3F && mb == 0x3F)
            {
                m.Assign(rd, m.Shr(rs, mb));
            }
            else if (sh < mb)
            {
                m.Assign(rd, m.And(
                             m.Shl(rs, (byte)sh),
                             maskBegin));
            }
            else if (mb == 0x00)
            {
                m.Assign(rd, host.Intrinsic(IntrinsicProcedure.Rol, true, rd.DataType, rs, Constant.Byte((byte)sh)));
            }
            else
            {
                var beExtBitpos = (sh + mb) - 64;
                var extBitsize  = 64 - mb;
                if (0 <= beExtBitpos && beExtBitpos < 64)
                {
                    //$TODO: check this logic.
                    var dtSlice = PrimitiveType.CreateWord(extBitsize);
                    m.Assign(rd, m.Convert(m.Slice(dtSlice, rs, 63 - beExtBitpos), dtSlice, rd.DataType));
                }
                else if (sh == 0x39 && mb == 0x38)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x31 && mb == 0x3F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x10 && mb == 0x2F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x08 && mb == 0x37)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x18 && mb == 0x27)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x20 && mb == 0x1F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x02 && mb == 0x1E)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x38 && mb == 0x3F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x37 && mb == 0x3F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x21 && mb == 0x3F)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x08 && mb == 0x30)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x3D && mb == 0x23)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else if (sh == 0x3E && mb == 0x22)
                {
                    m.Assign(rd, m.And(
                                 m.Shr(rs, (byte)(64 - sh)),
                                 maskBegin));
                }
                else
                {
                    host.Error(
                        instr.Address,
                        string.Format("PowerPC instruction '{0}' is not supported yet.", instr));
                    EmitUnitTest();
                    iclass = InstrClass.Invalid;
                    m.Invalid();
                    return;
                }
            }
            MaybeEmitCr0(rd);
        }
Example #19
0
 public PICInstructionMem2Mem(Opcode opcode, byte srcidx, byte dstidx)
     : base(opcode,
            new PICOperandFSRIndexation(Constant.Byte(srcidx)),
            new PICOperandFSRIndexation(Constant.Byte(dstidx)))
 {
 }
Example #20
0
 public PICInstructionMem2Mem(Opcode opcode, byte srcidx, uint dstaddr)
     : base(opcode,
            new PICOperandFSRIndexation(Constant.Byte(srcidx)),
            new PICOperandDataMemoryAddress(dstaddr))
 {
 }
Example #21
0
 private void RewriteSETF()
 {
     var(indMode, memPtr) = GetUnaryPtrs(instrCurr.Operands[0], out Expression memExpr);
     ArithAssignIndirect(memExpr, Constant.Byte(255), indMode, memPtr);
 }
Example #22
0
 public static ImmediateOperand Byte(byte value)
 {
     return(new ImmediateOperand(Constant.Byte(value)));
 }
Example #23
0
 private void Rewrite_CLRF()
 {
     GetSrc(out var srcMem);
     m.Assign(srcMem, Constant.Byte(0));
     m.Assign(binder.EnsureFlagGroup(PICRegisters.Z), Constant.Bool(true));
 }
Example #24
0
        void RewriteRlwinm()
        {
            var rd = RewriteOperand(instr.op1);
            var rs = RewriteOperand(instr.op2);
            byte sh = ((Constant)RewriteOperand(instr.op3)).ToByte();
            byte mb = ((Constant)RewriteOperand(instr.op4)).ToByte();
            byte me = ((Constant)RewriteOperand(instr.op5)).ToByte();
            uint maskBegin = (uint)(1ul << (32 - mb));
            uint maskEnd = 1u << (31 - me);
            uint mask = maskBegin - maskEnd;

//Extract and left justify immediate 	extlwi RA, RS, n, b 	rlwinm RA, RS, b, 0, n-1             	32 > n > 0
//Extract and right justify immediate 	extrwi RA, RS, n, b 	rlwinm RA, RS, b+n, 32-n, 31 	        32 > n > 0 & b+n =< 32
//Insert from left immediate         	inslwi RA, RS, n, b 	rlwinm RA, RS, 32-b, b, (b+n)-1 	    b+n <=32 & 32>n > 0 & 32 > b >= 0
//Insert from right immediate       	insrwi RA, RS, n, b 	rlwinm RA, RS, 32-(b+n), b, (b+n)-1 	b+n <= 32 & 32>n > 0
//Rotate left immediate             	rotlwi RA, RS, n    	rlwinm RA, RS, n, 0, 31 	            32 > n >= 0
//Rotate right immediate            	rotrwi RA, RS, n    	rlwinm RA, RS, 32-n, 0, 31 	            32 > n >= 0
//Rotate left                       	rotlw RA, RS, b      	rlwinm RA, RS, RB, 0, 31             	None
//Shift left immediate              	slwi RA, RS, n       	rlwinm RA, RS, n, 0, 31-n 	            32 > n >= 0
//Shift right immediate             	srwi RA, RS, n      	rlwinm RA, RS, 32-n, n, 31 	            32 > n >= 0
//Clear left immediate              	clrlwi RA, RS, n     	rlwinm RA, RS, 0, n, 31 	            32 > n >= 0
//Clear right immediate             	clrrwi RA, RS, n     	rlwinm RA, RS, 0, 0, 31-n 	            32 > n >= 0
//Clear left and shift left immediate 	clrslwi RA, RS, b, n 	rlwinm RA, RS, b-n, 31-n 	            b-n >= 0 & 32 > n >= 0 & 32 > b>= 0
            if (sh == 0)
            {
                emitter.Assign(rd, emitter.And(rs, Constant.UInt32(mask)));
                return;
            }
            else if (mb == 32 - sh && me == 31)
            {
                emitter.Assign(rd, emitter.Shr(rs, (byte)(32-sh)));
                return;
            }
            else if (mb == 0 && me == 31-sh)
            {
                emitter.Assign(rd, emitter.Shl(rs, sh));
                return;
            }
            else if (mb == 0 && me == 31)
            {
                if (sh < 16)
                    emitter.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, PrimitiveType.Word32, rs, Constant.Byte(sh)));
                else
                    emitter.Assign(rd, host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, rs, Constant.Byte((byte)(32 - sh))));
                return;
            }
            else if (me == 31)
            {
                int n = 32 - mb;
                int b = sh - n;
                mask = (1u << b) - 1;
                emitter.Assign(rd, emitter.And(
                    emitter.Shr(rs, Constant.Byte((byte)n)),
                    Constant.Word32(mask)));
                return;
            }
            else if (mb <= me)
            {
                if (me < 32 - sh)
                {
                    // [                           llll]
                    // [                        mmm....]
                    emitter.Assign(rd, emitter.And(
                        emitter.Shl(rs, Constant.Byte((byte)sh)),
                        Constant.Word32(mask)));
                    return;
                }
                else if (mb >= 32 - sh)
                {
                    // [                        ll]
                    // [                        m.]

                    emitter.Assign(rd, emitter.And(
                        emitter.Shr(rs, Constant.Byte((byte)(32-sh))),
                        Constant.Word32(mask)));
                    return;
                }
            }
            else
                throw new AddressCorrelatedException(dasm.Current.Address, "{0} not handled yet.", dasm.Current);

//Error,10034E20,rlwinm	r9,r31,1D,1B,1D not handled yet.
//Error,10028B50,rlwinm	r8,r8,04,18,1B not handled yet.
//Error,1002641C,rlwinm	r4,r4,04,18,1B not handled yet.
//Error,10026364,rlwinm	r4,r4,04,18,1B not handled yet.
//Error,1003078C,rlwinm	r8,r8,04,1A,1B not handled yet.
//Error,100294D4,rlwinm	r0,r0,04,18,1B not handled yet.
//Error,100338A0,rlwinm	r4,r11,08,08,0F not handled yet.

        }
Example #25
0
 private void Rewrite_INCF()
 {
     GetSrcAndDst(out var srcMem, out var dstMem);
     m.Assign(dstMem, m.IAdd(srcMem, Constant.Byte(1)));
     SetStatusFlags(dstMem);
 }
Example #26
0
 public HExpr Byte(byte b)
 {
     return(MapToHandle(Constant.Byte(b)));
 }
Example #27
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand regOp:
                if (regOp.Register == Registers.pc)
                {
                    return(instr.Address + instr.Length);
                }
                else
                {
                    return(binder.EnsureRegister(regOp.Register));
                }

            case ImmediateOperand immOp:
                if (dasm.Current.DataWidth.Size == 1)
                {
                    return(Constant.Byte((byte)immOp.Value.ToInt32()));
                }
                else
                {
                    return(immOp.Value);
                }

            case AddressOperand addrOp:
                return(addrOp.Address);

            case MemoryOperand memOp:
                var r   = binder.EnsureRegister(memOp.Register);
                var tmp = binder.CreateTemporary(op.Width);
                switch (memOp.Mode)
                {
                default:
                    throw new AddressCorrelatedException(
                              dasm.Current.Address,
                              "Not implemented: addressing mode {0}.",
                              memOp.Mode);

                case AddressMode.RegDef:
                    return(m.Mem(this.dasm.Current.DataWidth, r));

                case AddressMode.Absolute:
                    return(m.Mem(
                               dasm.Current.DataWidth,
                               Address.Ptr16(memOp.EffectiveAddress)));

                case AddressMode.AutoIncr:
                    m.Assign(tmp, m.Mem(op.Width, r));
                    m.Assign(r, m.IAdd(r, memOp.Width.Size));
                    break;

                case AddressMode.AutoIncrDef:
                    m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r)));
                    m.Assign(r, m.IAdd(r, memOp.Width.Size));
                    break;

                case AddressMode.AutoDecr:
                    m.Assign(r, m.ISub(r, memOp.Width.Size));
                    return(m.Mem(op.Width, r));

                case AddressMode.AutoDecrDef:
                    m.Assign(r, m.ISub(r, memOp.Width.Size));
                    m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r)));
                    return(tmp);

                case AddressMode.Indexed:
                    if (memOp.Register == Registers.pc)
                    {
                        var offset   = (short)memOp.EffectiveAddress;
                        var addrBase = (long)instr.Address.ToLinear();
                        var addr     = Address.Ptr16((ushort)(2 + addrBase + offset));
                        return(m.Mem(memOp.Width, addr));
                    }
                    else
                    {
                        return(m.Mem(
                                   this.dasm.Current.DataWidth,
                                   m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))));
                    }

                case AddressMode.IndexedDef:
                    if (memOp.Register == Registers.pc)
                    {
                        var addr = this.dasm.Current.Address + this.dasm.Current.Length + memOp.EffectiveAddress;
                        m.Assign(tmp, m.Mem(PrimitiveType.Ptr16, addr));
                        m.Assign(tmp, m.Mem(memOp.Width, tmp));
                        return(tmp);
                    }
                    else
                    {
                        return(m.Mem(
                                   this.dasm.Current.DataWidth,
                                   m.Mem(
                                       PrimitiveType.Ptr16,
                                       m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))));
                    }
                }
                return(tmp);
            }
            throw new NotImplementedException();
        }
Example #28
0
 private Expression Ror1(Expression e)
 {
     return(host.Intrinsic(IntrinsicProcedure.Ror, true, e.DataType, e, Constant.Byte(1)));
 }
Example #29
0
        private void RewriteSel()
        {
            var bank = (RegisterBankOperand)instr.Operands[0];

            m.SideEffect(host.PseudoProcedure("__select_register_bank", VoidType.Instance, Constant.Byte((byte)bank.Bank)));
        }
Example #30
0
 private Expression Ror1(Expression e)
 {
     return(host.PseudoProcedure(PseudoProcedure.Ror, e.DataType, e, Constant.Byte(1)));
 }