예제 #1
0
        private Expression GenerateTestExpression(ConditionOperand cOp, bool invert)
        {
            ConditionCode cc    = ConditionCode.ALWAYS;
            string        flags = "";

            switch (cOp.Code)
            {
            case CondCode.F: return(invert ? Constant.True() : Constant.False());

            case CondCode.LT: cc = invert ? ConditionCode.GE : ConditionCode.LT; flags = "SV"; break;

            case CondCode.LE: cc = invert ? ConditionCode.GT : ConditionCode.LE; flags = "SZV"; break;

            case CondCode.ULE: cc = invert ? ConditionCode.UGT : ConditionCode.ULE; flags = "ZC"; break;

            case CondCode.OV: cc = invert ? ConditionCode.NO : ConditionCode.OV; flags = "V"; break;

            case CondCode.MI: cc = invert ? ConditionCode.NS : ConditionCode.SG; flags = "S"; break;

            case CondCode.Z: cc = invert ? ConditionCode.NE : ConditionCode.EQ; flags = "Z"; break;

            case CondCode.C: cc = invert ? ConditionCode.UGE : ConditionCode.ULT; flags = "Z"; break;

            case CondCode.T: return(invert ? Constant.False() : Constant.True());

            case CondCode.GE: cc = invert ? ConditionCode.LT : ConditionCode.GE; flags = "SV"; break;

            case CondCode.GT: cc = invert ? ConditionCode.LE : ConditionCode.GT; flags = "SZV"; break;

            case CondCode.UGT: cc = invert ? ConditionCode.ULE : ConditionCode.UGT; flags = "ZC"; break;

            case CondCode.NV: cc = invert ? ConditionCode.OV : ConditionCode.NO; flags = "V"; break;

            case CondCode.PL: cc = invert ? ConditionCode.SG : ConditionCode.NS; flags = "S"; break;

            case CondCode.NZ: cc = invert ? ConditionCode.EQ : ConditionCode.NE; flags = "Z"; break;

            case CondCode.NC: cc = invert ? ConditionCode.ULT : ConditionCode.UGE; flags = "Z"; break;
            }
            return(m.Test(
                       cc,
                       binder.EnsureFlagGroup(arch.GetFlagGroup(flags))));
        }
예제 #2
0
        private Tlcs900Instruction Decode(byte b, Opcode opcode, string fmt)
        {
            var instr = new Tlcs900Instruction
            {
                Opcode  = opcode,
                Address = this.addr,
            };
            var            ops = new List <MachineOperand>();
            MachineOperand op  = null;

            for (int i = 0; i < fmt.Length; ++i)
            {
                switch (fmt[i++])
                {
                case ',': continue;

                case 'C': // condition code
                    var cc = (CondCode)(b & 0xF);
                    if (cc == CondCode.T)
                    {
                        continue;
                    }
                    op = new ConditionOperand(cc);
                    break;

                case 'A':
                    op = new RegisterOperand(Tlcs900Registers.a);
                    break;

                case '3': // Immediate encoded in low 3 bits
                    var c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]);
                    SetSize(fmt[1]);
                    op = new ImmediateOperand(c);
                    break;

                case 'I': // immediate
                    op = Immediate(fmt[i++]);
                    break;

                case 'j': // Relative jump
                    switch (fmt[i++])
                    {
                    case 'b':
                        byte o8;
                        if (!rdr.TryReadByte(out o8))
                        {
                            op = null;
                        }
                        else
                        {
                            op = AddressOperand.Create(rdr.Address + (sbyte)o8);
                        }
                        break;

                    case 'w':
                        short o16;
                        if (!rdr.TryReadLeInt16(out o16))
                        {
                            op = null;
                        }
                        else
                        {
                            op = AddressOperand.Create(rdr.Address + o16);
                        }
                        break;
                    }
                    break;

                case 'J': // Absolute jump
                    switch (fmt[i++])
                    {
                    case 'w': op = AbsoluteDestination(2); break;

                    case 'l': op = AbsoluteDestination(3); break;

                    default: op = null; break;
                    }
                    break;

                case 'R':   // 16 bit register encoded in lsb
                    op = new RegisterOperand(Reg(fmt[i++], b & 0x7));
                    break;

                case 'S': // status/flag register
                    op = StatusRegister(fmt[i++]);
                    break;
                }
                if (op == null)
                {
                    return(Decode(b, Opcode.invalid, ""));
                }
                ops.Add(op);
            }
            if (ops.Count > 0)
            {
                instr.op1 = ops[0];
                if (ops.Count > 1)
                {
                    instr.op2 = ops[1];
                    if (ops.Count > 2)
                    {
                        instr.op3 = ops[2];
                    }
                }
            }
            return(instr);
        }
예제 #3
0
        private MachineOperand DecodeOperand(byte b, string fmt)
        {
            MachineOperand op;
            byte           r;
            Constant       c;
            byte           o8;
            int            incCode;

            switch (fmt[0])
            {
            case '+': // Predecrement
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PostIncrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '-':
                if (!rdr.TryReadByte(out r))
                {
                    return(null);
                }
                incCode = r & 3;
                if (incCode >= incDecSize.Length)
                {
                    return(null);
                }
                op = MemoryOperand.PreDecrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F));
                SetSize(fmt[1]);
                return(op);

            case '3': // Immediate encoded in low 3 bits
                c = Constant.Create(Size(fmt[1]), b & 7);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case '#': // Immediate encoded in low 3 bits, with 8 encoded as 0
                c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]);
                SetSize(fmt[1]);
                return(new ImmediateOperand(c));

            case 'A': // A register
                op = new RegisterOperand(Tlcs900Registers.a);
                return(op);

            case 'C': // condition code
                op = new ConditionOperand((CondCode)(b & 0xF));
                return(op);

            case 'I': // immediate
                op = Immediate(fmt[1]);
                return(op);

            case 'j': // Relative jump
                switch (fmt[1])
                {
                case 'b':
                    if (!rdr.TryReadByte(out o8))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + (sbyte)o8));
                    }

                case 'w':
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    else
                    {
                        return(AddressOperand.Create(rdr.Address + o16));
                    }
                }
                return(null);

            case 'r': // Register
            case 'R':
                //$TODO: 'r' may encode other registers. manual is dense
                op = new RegisterOperand(Reg(fmt[1], b & 0x7));
                SetSize(fmt[1]);
                return(op);

            case 'M': // Register indirect
                op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', b & 7));
                SetSize(fmt[1]);
                return(op);

            case 'N': // indexed (8-bit offset)
                if (!rdr.TryReadByte(out o8))
                {
                    return(null);
                }
                op = MemoryOperand.Indexed8(Size(fmt[1]), Reg('x', b & 7), (sbyte)o8);
                SetSize(fmt[1]);
                return(op);

            case 'm': // various mem formats
                byte m;
                if (!rdr.TryReadByte(out m))
                {
                    return(null);
                }
                switch (m & 3)
                {
                case 0: // Register indirect
                    op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F));
                    break;

                case 1: // indexed (16-bit offset)
                    short o16;
                    if (!rdr.TryReadLeInt16(out o16))
                    {
                        return(null);
                    }
                    op = MemoryOperand.Indexed16(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F), o16);
                    SetSize(fmt[1]);
                    return(op);

                case 3:
                    if (m != 3 && m != 7)
                    {
                        return(null);
                    }
                    byte rBase;
                    if (!rdr.TryReadByte(out rBase))
                    {
                        return(null);
                    }
                    byte rIdx;
                    if (!rdr.TryReadByte(out rIdx))
                    {
                        return(null);
                    }
                    var regBase = Reg('x', rBase);
                    var regIdx  = Reg(m == 3 ? 'b' : 'w', rIdx);
                    op = MemoryOperand.RegisterIndexed(Size(fmt[1]), regBase, regIdx);
                    SetSize(fmt[1]);
                    return(op);

                default:
                    throw new FormatException(string.Format(
                                                  "Unknown format {0} decoding bytes {1:X2}{2:X2}.",
                                                  fmt[0], (int)b, (int)m));
                }
                SetSize(fmt[1]);
                return(op);

            case 'O': return(Absolute(1, fmt[1]));

            case 'P': return(Absolute(2, fmt[1]));

            case 'Q': return(Absolute(3, fmt[1]));

            default: throw new FormatException(
                          string.Format(
                              "Unknown format {0} decoding byte {1:X2}.", fmt[0], (int)b));
            }
        }