Example #1
0
        public void AddSegmentReference(ulong imageOffset, ushort segmentSelector)
        {
            var c = Constant.Create(PrimitiveType.SegmentSelector, segmentSelector);

            map.Add(imageOffset, c);
        }
Example #2
0
        public void TerArrayAssignment()
        {
            var sExp =
                #region Expected
                @"// Before ///////
// test
// Return size: 0
define test
test_entry:
	// succ:  l000000000040EC30
l000000000040EC30:
	word64 rbx_18 = rdx - 1<64>
	branch rdx == 0<64> l000000000040EC69
	// succ:  l000000000040EC40 l000000000040EC69
l000000000040EC40:
	word64 rax_22 = 0x10000040<64>
	// succ:  l000000000040EC50
l000000000040EC50:
	Mem0[rdi + rbx_18:byte] = CONVERT(Mem0[Mem0[rax_22:word64] + CONVERT(CONVERT(Mem0[rsi + rbx_18:byte], byte, word32), word32, uint64) * 4<64>:word32], word32, byte)
	rbx_18 = rbx_18 - 1<64>
	branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50
	// succ:  l000000000040EC69 l000000000040EC50
l000000000040EC69:
	return
	// succ:  test_exit
test_exit:

// After ///////
// test
// Return size: 0
define test
test_entry:
	// succ:  l000000000040EC30
l000000000040EC30:
	int64 rbx_18 = rdx - 1<64>
	branch rdx == 0<64> l000000000040EC69
	// succ:  l000000000040EC40 l000000000040EC69
l000000000040EC40:
	word32 (** rax_22)[] = (word32 (**)[]) 0x10000040<64>
	// succ:  l000000000040EC50
l000000000040EC50:
	rdi[rbx_18] = (byte) *((char *) *rax_22 + (uint64) ((word32) (rsi + rbx_18)) * 4<64>)
	rbx_18 = rbx_18 - 1<64>
	branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50
	// succ:  l000000000040EC69 l000000000040EC50
l000000000040EC69:
	return
	// succ:  test_exit
test_exit:

";

            #endregion

            // fn000000000040EC30 //////////
            RunStringTest(m =>
            {
                Identifier rbx_18 = m.Local(PrimitiveType.Word64, "rbx_18");
                Identifier rdx    = m.Local(PrimitiveType.Word64, "rdx");
                Identifier rax_22 = m.Local(PrimitiveType.Word64, "rax_22");
                Identifier rsi    = m.Local(PrimitiveType.Word64, "rsi");
                Identifier rdi    = m.Local(PrimitiveType.Word64, "rdi");

                m.Label("l000000000040EC30");
                m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1)));
                m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69");

                m.Label("l000000000040EC40");
                m.Declare(rax_22, m.Word64(0x10000040));

                m.Label("l000000000040EC50");
                m.MStore(m.IAdd(rdi, rbx_18), m.Convert(
                             m.Mem32(m.IAdd(m.Mem64(rax_22), m.IMul(m.Convert(
                                                                        m.Convert(
                                                                            m.Mem8(m.IAdd(rsi, rbx_18)),
                                                                            PrimitiveType.Byte,
                                                                            PrimitiveType.Word32),
                                                                        PrimitiveType.Word32,
                                                                        PrimitiveType.UInt64),
                                                                    Constant.Create(PrimitiveType.Word64, 0x4)))),
                             PrimitiveType.Word32,
                             PrimitiveType.Byte));
                m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Word64, 0x1)));
                m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Word64, 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50");

                m.Label("l000000000040EC69");
                m.Return();
            }, sExp);
        }
Example #3
0
 public RtlInstruction Assign(Expression dst, int n)
 {
     return(Assign(dst, Constant.Create(dst.DataType, n)));
 }
Example #4
0
 public PICOperandImmediate(int immValue, PrimitiveType dataWidth) : base(dataWidth)
 {
     ImmediateValue = Constant.Create(dataWidth, immValue);
 }
Example #5
0
 public Expression Transform()
 {
     return(Constant.Create(slice.DataType, Slice(c.ToInt32())));
 }
Example #6
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));
            }
        }
Example #7
0
        public void VpMulAddShift()
        {
            Identifier       id = Reg32("id");
            var              vp = new ExpressionSimplifier(new SsaEvaluationContext(arch, ssaIds), listener);
            PrimitiveType    t  = PrimitiveType.Int32;
            BinaryExpression b  = new BinaryExpression(Operator.Shl, t,
                                                       new BinaryExpression(Operator.IAdd, t,
                                                                            new BinaryExpression(Operator.SMul, t, id, Constant.Create(t, 4)),
                                                                            id),
                                                       Constant.Create(t, 2));
            Expression e = vp.VisitBinaryExpression(b);

            Assert.AreEqual("id *s 20", e.ToString());
        }
Example #8
0
 private Constant Seg(int seg)
 {
     return(Constant.Create(PrimitiveType.SegmentSelector, seg));
 }
Example #9
0
        public void VpMulAddShift()
        {
            Identifier       id = m.Reg32("id");
            var              vp = new ExpressionSimplifier(segmentMap, new SsaEvaluationContext(arch.Object, m.Ssa.Identifiers, dynamicLinker.Object), listener);
            PrimitiveType    t  = PrimitiveType.Int32;
            BinaryExpression b  = new BinaryExpression(Operator.Shl, t,
                                                       new BinaryExpression(Operator.IAdd, t,
                                                                            new BinaryExpression(Operator.SMul, t, id, Constant.Create(t, 4)),
                                                                            id),
                                                       Constant.Create(t, 2));
            Expression e = vp.VisitBinaryExpression(b);

            Assert.AreEqual("id *s 20<i32>", e.ToString());
        }
Example #10
0
        public Expression Rewrite(Address addr, Expression?basePtr, bool dereferenced)
        {
            if (addr.Selector.HasValue)
            {
                if (!mpSelectorToSegId.TryGetValue(addr.Selector.Value, out Identifier segId))
                {
                    eventListener.Warn(
                        "Selector {0:X4} has no known segment.",
                        addr.Selector.Value);
                    return(addr);
                }
                var ptrSeg = segId.TypeVariable !.DataType.ResolveAs <Pointer>();
                if (ptrSeg == null)
                {
                    //$TODO: what should the warning be?
                    //$BUG: create a fake field for now.
                    var        field = new StructureField((int)addr.Offset, new UnknownType());
                    Expression x     = new FieldAccess(new UnknownType(), new Dereference(segId.DataType, segId), field);
                    if (!dereferenced)
                    {
                        x = new UnaryExpression(Operator.AddrOf, addr.DataType, x);
                    }
                    return(x);
                }
                var baseType = ptrSeg.Pointee.ResolveAs <StructureType>() !;
                var dt       = addr.TypeVariable !.DataType.ResolveAs <Pointer>() !;
                this.c = Constant.Create(
                    PrimitiveType.CreateWord(addr.DataType.BitSize - ptrSeg.BitSize),
                    addr.Offset);
                DataType pointee;
                if (dt != null)
                {
                    pointee = dt.Pointee;
                }
                else
                {
                    pointee = new UnknownType();
                }

                var        f  = EnsureFieldAtOffset(baseType, pointee, c.ToInt32());
                Expression ex = new FieldAccess(f.DataType, new Dereference(ptrSeg, segId), f);
                if (dereferenced || pointee is ArrayType)
                {
                    return(ex);
                }
                else
                {
                    var un = new UnaryExpression(Operator.AddrOf, addr.TypeVariable !.DataType, ex);
                    return(un);
                }
            }
            else
            {
                this.c = addr.ToConstant();
                this.c.TypeVariable = addr.TypeVariable;
                var dtInferred = addr.TypeVariable !.DataType.ResolveAs <DataType>() !;
                this.pOrig        = addr.TypeVariable.OriginalDataType as PrimitiveType;
                this.dereferenced = dereferenced;
                return(dtInferred.Accept(this));
            }
        }
Example #11
0
 public virtual Assignment Assign(Identifier dst, int n)
 {
     return(Assign(dst, Constant.Create((PrimitiveType)dst.DataType, n)));
 }
Example #12
0
        public MipsInstruction DecodeOperands(Opcode opcode, uint wInstr, string opFmt)
        {
            var            ops = new List <MachineOperand>();
            MachineOperand op  = null;

            for (int i = 0; i < opFmt.Length; ++i)
            {
                switch (opFmt[i])
                {
                default: throw new NotImplementedException(string.Format("Operator format {0}", opFmt[i]));

                case ',':
                    continue;

                case 'R':
                    switch (opFmt[++i])
                    {
                    case '1': op = Reg(wInstr >> 21); break;

                    case '2': op = Reg(wInstr >> 16); break;

                    case '3': op = Reg(wInstr >> 11); break;

                    //case '4': op = MemOff(wInstr >> 6, wInstr); break;
                    default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i]));
                    }
                    break;

                case 'F':
                    switch (opFmt[++i])
                    {
                    case '1': op = FReg(wInstr >> 21); break;

                    case '2': op = FReg(wInstr >> 16); break;

                    case '3': op = FReg(wInstr >> 11); break;

                    case '4': op = FReg(wInstr >> 6); break;

                    default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i]));
                    }
                    break;

                case 'f': // FPU control register
                    RegisterOperand fcreg;
                    switch (opFmt[++i])
                    {
                    case '1': if (!TryGetFCReg(wInstr >> 21, out fcreg))
                        {
                            return(null);
                        }
                        op = fcreg; break;

                    case '2': if (!TryGetFCReg(wInstr >> 16, out fcreg))
                        {
                            return(null);
                        }
                        op = fcreg; break;

                    case '3': if (!TryGetFCReg(wInstr >> 11, out fcreg))
                        {
                            return(null);
                        }
                        op = fcreg; break;

                    //case '4': op = MemOff(wInstr >> 6, wInstr); break;
                    default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i]));
                    }
                    break;

                case 'I':
                    op = new ImmediateOperand(Constant.Create(this.signedWord, (short)wInstr));
                    break;

                case 'U':
                    op = new ImmediateOperand(Constant.Create(arch.WordWidth, (ushort)wInstr));
                    break;

                case 'i':
                    op = ImmediateOperand.Int16((short)wInstr);
                    break;

                case 'j':
                    op = RelativeBranch(wInstr);
                    break;

                case 'J':
                    op = LargeBranch(wInstr);
                    break;

                case 'B':
                    op = ImmediateOperand.Word32((wInstr >> 6) & 0xFFFFF);
                    break;

                case 's':   // Shift amount or sync type
                    op = ImmediateOperand.Byte((byte)((wInstr >> 6) & 0x1F));
                    break;

                case 'E':   // effective address w 16-bit offset
                    op = Ea(wInstr, opFmt[++i], 21, (short)wInstr);
                    break;

                case 'e':   // effective address w 9-bit offset
                    op = Ea(wInstr, opFmt[++i], 21, (short)(((short)wInstr) >> 7));
                    break;

                case 'T':   // trap code
                    op = ImmediateOperand.Word16((ushort)((wInstr >> 6) & 0x03FF));
                    break;

                case 'c':   // condition code
                    op = CCodeFlag(wInstr, opFmt, ref i);
                    break;

                case 'C': // FPU condition code
                    op = FpuCCodeFlag(wInstr, opFmt, ref i);
                    break;

                case 'H':   // hardware register, see instruction rdhwr
                    op = ImmediateOperand.Byte((byte)((wInstr >> 11) & 0x1f));
                    break;
                }
                ops.Add(op);
            }
            return(new MipsInstruction
            {
                opcode = opcode,
                Address = addr,
                Length = 4,
                op1 = ops.Count > 0 ? ops[0] : null,
                op2 = ops.Count > 1 ? ops[1] : null,
                op3 = ops.Count > 2 ? ops[2] : null,
            });
        }
Example #13
0
        public void AddSegmentReference(ulong linAddress, ushort segmentSelector)
        {
            var c = Constant.Create(PrimitiveType.SegmentSelector, segmentSelector);

            map.Add(linAddress, c);
        }
Example #14
0
        public void AddPointerReference(ulong linAddress, uint pointer)
        {
            var c = Constant.Create(PrimitiveType.Ptr32, pointer);

            map.Add(linAddress, c);
        }
        public void Execute(Tag action, Stack <Tag> stk, Token tk, ref Environment env)
        {
            #region Sentenças Declarativas
            if (action == Tag._Begin)
            {
                // Sinaliza o início de uma sentença imperativa
                env.SentencaImperativa = true;
            }
            else if (action == Tag._End)
            {
                // Sinaliza o final de uma sentença imperativa
                env.SentencaImperativa = false;
            }

            else if (action == Tag._CreateList)
            {
                List <object> list = new List <object>();

                list.Add(((IdNew)tk).Lexema);

                stk.ElementAt <Tag>(0).Inherited[0] = list;
            }
            else if (action == Tag._InsertList)
            {
                List <object> list = (List <object>)action.Inherited[0];

                list.Add(((IdNew)tk).Lexema);

                stk.ElementAt <Tag>(0).Inherited[0] = list;
            }

            else if (action == Tag._Integer)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = new IntegerType();
                // stk.ElementAt<Tag>(0).Inherited[0] = AbsType.IntegerType;
            }
            else if (action == Tag._Real)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = new RealType();
                // stk.ElementAt<Tag>(0).Inherited[0] = AbsType.RealType;
            }

            else if (action == Tag._BeginRange)
            {
                stk.ElementAt <Tag>(6).Inherited[2] = ((Integer)tk).Value;
            }
            else if (action == Tag._EndRange)
            {
                stk.ElementAt <Tag>(3).Inherited[1] = ((Integer)tk).Value;
            }
            else if (action == Tag._ArrayDec)
            {
                AbsType type       = (AbsType)action.Inherited[0];
                int     rangeEnd   = (int)action.Inherited[1];
                int     rangeBegin = (int)action.Inherited[2];

                stk.ElementAt <Tag>(0).Inherited[0] = new ArrayType(type, rangeBegin, rangeEnd);
            }

            else if (action == Tag._IdVar)
            {
                stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0];
            }
            else if (action == Tag._VarDec)
            {
                List <object> lexemas = (List <object>)action.Inherited[1];
                AbsType       type    = (AbsType)action.Inherited[0];

                foreach (string v in lexemas)
                {
                    env.locals.Add(v, type);
                }
            }

            else if (action == Tag._IdProc)
            {
                // Verificar se o identificador é novo
                if (tk.tag != Tag.IDNEW)
                {
                    throw new NotImplementedException("O Id deve ser novo!");
                }
                string lexema = ((IdNew)tk).Lexema;

                // O contexto deve ser alterado logo antes dos parâmetros serem declarados
                ProcType type = new ProcType(env, env.machine);

                env.locals.Add(lexema, type);

                env = type.Env;

                stk.ElementAt <Tag>(1).Inherited[0] = lexema;
            }
            else if (action == Tag._IdFunc)
            {
                // Verificar se o identificador é novo
                if (tk.tag != Tag.IDNEW)
                {
                    throw new NotImplementedException("O Id deve ser novo!");
                }
                string lexema = ((IdNew)tk).Lexema;

                // O contexto deve ser alterado logo antes dos parâmetros serem declarados
                FuncType type = new FuncType(env, env.machine);

                env.locals.Add(lexema, type);

                env = type.Env;

                stk.ElementAt <Tag>(3).Inherited[1] = lexema;
            }
            else if (action == Tag._ProcDec)
            {
                // Identificador do procedimento
                string lexema = (string)action.Inherited[0];

                ProcType type = (ProcType)Environment.SearchLocal(env.parent, lexema);
            }
            else if (action == Tag._FuncDec)
            {
                // Identificador da função
                string lexema = (string)action.Inherited[1];

                FuncType type = (FuncType)Environment.SearchLocal(env.parent, lexema);

                type.ReturnType = (AbsType)action.Inherited[0];
            }

            else if (action == Tag._EndParList)
            {
                stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0];
            }
            else if (action == Tag._ParDec)
            {
                foreach (string arg in (List <object>)action.Inherited[1])
                {
                    env.parameters.Add(arg, (AbsType)action.Inherited[0]);
                }
            }
            else if (action == Tag._EnvRestore)
            {
                IntermediateInstruction code = ic.CreateReturn();
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                env = env.parent;
            }

            else if (action == Tag._Args)
            {
                // Recebe a lista de argumentos do programa

                foreach (string arg in (List <object>)action.Inherited[0])
                {
                    env.parameters.Add(arg, AbsType.Untyped);
                }
            }
            #endregion

            #region Sentenças Imperativas
            else if (action == Tag._Number)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = Constant.Create(((Integer)tk).Value);
            }
            else if (action == Tag._RValue)
            {
                Address address = (Address)action.Inherited[0];
                stk.ElementAt <Tag>(0).Inherited[0] = address;
            }
            else if (action == Tag._Not)
            {
                Name tmp = new Name();

                IntermediateInstruction code = ic.CreateUnary(Operator.NOT, (Address)action.Inherited[0], tmp);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = tmp;
            }
            else if (action == Tag._Skip1)
            {
                stk.ElementAt <Tag>(1).Inherited[0] = action.Inherited[0];
            }
            else if (action == Tag._FAddress) // Endereço da função
            {
                FuncType func = (FuncType)Environment.Search(env, ((IdFunc)tk).Lexema);

                stk.ElementAt <Tag>(1).Inherited[1] = func;
            }
            else if (action == Tag._PAddress) // Endereço do procedimento
            {
                ProcType proc = (ProcType)Environment.Search(env, ((IdProc)tk).Lexema);

                stk.ElementAt <Tag>(1).Inherited[1] = proc.Env.CodeAddress;
            }
            else if (action == Tag._FCall) // Chamada de função
            {
                // Destino
                FuncType func  = (FuncType)action.Inherited[1];
                Label    label = new Label(func.Env.CodeAddress);
                // Número de argumentos
                int n = (int)action.Inherited[0];

                IntermediateInstruction code = ic.CreateCall(label, n);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = func.Env.returnvalue;
            }
            else if (action == Tag._PCall) // Chamada de procedimento
            {
                // Destino
                Label label = new Label((int)action.Inherited[1]);
                // Número de argumentos
                int n = (int)action.Inherited[0];

                IntermediateInstruction code = ic.CreateCall(label, n);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);
            }
            else if (action == Tag._FirstActualPar) // Primeiro parâmetro atual
            {
                IntermediateInstruction code = ic.CreateParam((Address)action.Inherited[0]);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = 1; // Primeiro parametro
            }
            else if (action == Tag._NextActualPar)       // Próximo parâmetro atual
            {
                IntermediateInstruction code = ic.CreateParam((Address)action.Inherited[0]);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = (int)action.Inherited[1] + 1;
            }
            else if (action == Tag._EndActualPar)                               // Lista de parâmetros atuais completa
            {
                stk.ElementAt <Tag>(1).Inherited[0] = (int)action.Inherited[0]; // Número de parâmetros
            }
            else if (action == Tag._NoArgs)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = 0; // Não há parâmetros atuais
            }
            else if (action == Tag._AddOp)
            {
                if (((AddOp)tk).Value == '+')
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.ADD;
                }
                else // if (((AddOp)tk).Value == '-')
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.SUB;
                }
            }
            else if (action == Tag._Add)
            {
                Address  x  = (Address)action.Inherited[2];
                Operator op = (Operator)action.Inherited[1];
                Address  y  = (Address)action.Inherited[0];

                Name tmp = new Name();

                IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = tmp;
            }
            else if (action == Tag._MulOp)
            {
                if (((MulOp)tk).Value == '*')
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.MUL;
                }
                else // if (((MulOp)tk).Value == '/')
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.DIV;
                }
            }
            else if (action == Tag._Mul)
            {
                Address  x  = (Address)action.Inherited[2];
                Operator op = (Operator)action.Inherited[1];
                Address  y  = (Address)action.Inherited[0];

                Name tmp = new Name();

                IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = tmp;
            }
            else if (action == Tag._RelOp)
            {
                if (((RelOp)tk).Value == "<")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.LT;
                }
                else if (((RelOp)tk).Value == "<=")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.LE;
                }
                else if (((RelOp)tk).Value == ">")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.GT;
                }
                else if (((RelOp)tk).Value == ">=")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.GE;
                }
                else if (((RelOp)tk).Value == "=")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.EQ;
                }
                else // if (((RelOp)tk).Value == "<>")
                {
                    stk.ElementAt <Tag>(1).Inherited[1] = Operator.NEQ;
                }
            }
            else if (action == Tag._Rel)
            {
                Address  x  = (Address)action.Inherited[2];
                Operator op = (Operator)action.Inherited[1];
                Address  y  = (Address)action.Inherited[0];

                Name tmp = new Name();

                IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(0).Inherited[0] = tmp;
            }

            else if (action == Tag._Variable)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = new Name(((IdVar)tk).Lexema);
            }
            else if (action == Tag._ToArray)
            {
                Name tmp = new Name();

                Address y = (Address)action.Inherited[1];
                Address i = (Address)action.Inherited[0];

                IntermediateInstruction code = ic.CreateToArray(tmp, i, y);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(1).Inherited[0] = tmp;
            }
            else if (action == Tag._FromArray)
            {
                Name tmp = new Name();

                Address y = (Address)action.Inherited[1];
                Address i = (Address)action.Inherited[0];

                IntermediateInstruction code = ic.CreateFromArray(tmp, i, y);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(1).Inherited[0] = tmp;
            }
            else if (action == Tag._LValue)
            {
                stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0];
            }
            else if (action == Tag._Assign)
            {
                Address lValue = (Address)action.Inherited[1];
                Address rValue = (Address)action.Inherited[0];

                IntermediateInstruction code = ic.CreateCopy(lValue, rValue);
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);
            }
            else if (action == Tag._RetAssign)
            {
                Address lValue = env.returnvalue;
                Address rValue = (Address)action.Inherited[0];

                if (lValue == null)
                {
                    lValue = new Name();
                }

                IntermediateInstruction code1 = ic.CreateCopy(lValue, rValue);
                // Console.WriteLine(code1.ToString());
                env.machine.AddInstruction(code1);

                env.returnvalue = lValue;

                IntermediateInstruction code2 = ic.CreateRetVal(lValue); // ic.CreateCopy(lValue, rValue);
                // Console.WriteLine(code2.ToString());
                env.machine.AddInstruction(code2);
            }

            else if (action == Tag._IfExp)
            {
                IntermediateInstruction code1 = ic.CreateIfTrue((Address)action.Inherited[0], null);;
                env.machine.AddInstruction(code1);
                IntermediateInstruction code2 = ic.CreateGoto(null);
                env.machine.AddInstruction(code2);

                stk.ElementAt <Tag>(0).Inherited[0] = code1;

                stk.ElementAt <Tag>(3).Inherited[0] = code2;
            }
            else if (action == Tag._Then)
            {
                ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count);
                // Console.WriteLine(action.Inherited[0].ToString());
            }
            else if (action == Tag._Else)
            {
                ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count + 1);
                // Console.WriteLine(action.Inherited[0].ToString());

                IntermediateInstruction code = ic.CreateGoto(null);
                env.machine.AddInstruction(code);

                stk.ElementAt <Tag>(2).Inherited[0] = code;
            }
            else if (action == Tag._ExitIf)
            {
                Label exit = new Label(env.machine.Count + 1);
                ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = exit;
                // Console.WriteLine(action.Inherited[0].ToString());
                IntermediateInstruction code = ic.CreateGoto(exit);
                env.machine.AddInstruction(code);
            }

            else if (action == Tag._Loop)
            {
                Label loop = new Label(env.machine.Count);
                stk.ElementAt <Tag>(5).Inherited[1] = loop;
            }
            else if (action == Tag._WhileExp)
            {
                IntermediateInstruction code1 = ic.CreateIfTrue((Address)action.Inherited[0], null);;
                env.machine.AddInstruction(code1);
                IntermediateInstruction code2 = ic.CreateGoto(null);
                env.machine.AddInstruction(code2);

                stk.ElementAt <Tag>(1).Inherited[0] = code1;

                stk.ElementAt <Tag>(3).Inherited[0] = code2;
            }
            else if (action == Tag._Do)
            {
                ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count);
                // Console.WriteLine(action.Inherited[0].ToString());
            }
            else if (action == Tag._ExitWhile)
            {
                Label loop = (Label)action.Inherited[1];
                IntermediateInstruction code = ic.CreateGoto(loop);
                env.machine.AddInstruction(code);

                ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count);
                // Console.WriteLine(action.Inherited[0].ToString());
            }

            else if (action == Tag._MainCode)
            {
                Environment.root.EntryPoint();
            }
            else if (action == Tag._Done)
            {
                // Insere uma instrução ret no final do código do programa.
                IntermediateInstruction code = ic.CreateReturn();
                // Console.WriteLine(code.ToString());
                env.machine.AddInstruction(code);

                string str = "program " + programName + " " + env.ToString();

                Console.WriteLine(str);

                Console.WriteLine("\nPRESSIONE UMA TECLA PARA CONTINUAR...");

                Console.ReadKey();
            }

            #endregion

            else if (action == Tag._ProgramName)
            {
                programName = ((IdNew)tk).Lexema;
            }

            else if (action == Tag._Echo)
            {
                stk.ElementAt <Tag>(0).Inherited[0] = action.Inherited[0];
            }
            else
            {
                throw new NotImplementedException("Não implementado!");
            }
        }
Example #16
0
        public void EmitStringInstruction(X86Instruction instr, CodeEmitter emitter)
        {
            this.emitter = emitter;

            bool incSi = false;
            bool incDi = false;

            this.instrCur = instr;
            switch (instrCur.code)
            {
            default:
                throw new ApplicationException("NYI");

            case Mnemonic.cmps:
            case Mnemonic.cmpsb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi())));
                incSi = true;
                incDi = true;
                break;

            case Mnemonic.lods:
            case Mnemonic.lodsb:
                emitter.Assign(RegAl, MemSi());
                incSi = true;
                break;

            case Mnemonic.movs:
            case Mnemonic.movsb:
            {
                Identifier tmp = emitter.Frame.CreateTemporary(instrCur.dataWidth);
                emitter.Assign(tmp, MemSi());
                emitter.Store(MemDi(), tmp);
                incSi = true;
                incDi = true;
                break;
            }

            case Mnemonic.ins:
            case Mnemonic.insb:
            {
                Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                emitter.Store(MemDi(), host.PseudoProc("__in", instrCur.dataWidth, regDX));
                incDi = true;
                break;
            }

            case Mnemonic.outs:
            case Mnemonic.outsb:
            {
                Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
                emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl);
                incSi = true;
                break;
            }

            case Mnemonic.scas:
            case Mnemonic.scasb:
                emitter.Assign(
                    orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)),
                    new ConditionOf(
                        new BinaryExpression(Operator.ISub,
                                             instrCur.dataWidth,
                                             RegAl,
                                             MemDi())));
                incDi = true;
                break;

            case Mnemonic.stos:
            case Mnemonic.stosb:
                emitter.Store(MemDi(), RegAl);
                incDi = true;
                break;
            }

            if (incSi)
            {
                emitter.Assign(RegSi,
                               new BinaryExpression(Operator.IAdd,
                                                    instrCur.addrWidth,
                                                    RegSi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }

            if (incDi)
            {
                emitter.Assign(RegDi,
                               new BinaryExpression(Operator.IAdd,
                                                    instrCur.addrWidth,
                                                    RegDi,
                                                    Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size)));
            }
        }
Example #17
0
        public void TtranArrayAssignment()
        {
            var pp = new ProgramBuilder();

            pp.Add("Fn", m =>
            {
                Identifier rbx_18 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rbx_18");
                Identifier rdx    = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdx");
                Identifier rax_22 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rax_22");
                Identifier rsi    = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rsi");
                Identifier rdi    = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdi");

                m.Label("l000000000040EC30");
                m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1)));
                m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69");

                m.Label("l000000000040EC40");
                m.Declare(rax_22, m.Word64(0x10000040));

                m.Label("l000000000040EC50");
                m.MStore(m.IAdd(rdi, rbx_18), m.Cast(PrimitiveType.Byte, m.Mem(PrimitiveType.Word32, m.IAdd(m.Mem(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), rax_22), m.IMul(m.Cast(PrimitiveType.Create(Domain.UnsignedInt, 64), m.Cast(PrimitiveType.Word32, m.Mem(PrimitiveType.Byte, m.IAdd(rsi, rbx_18)))), Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x4))))));
                m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1)));
                m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50");

                m.Label("l000000000040EC69");
                m.Return();
            });
            RunTest(pp.BuildProgram(), $"Typing/{nameof(TtranArrayAssignment)}.txt");
        }
Example #18
0
        /// <summary>
        /// Emits the ModRM byte (and SIB byte if applicable)
        /// </summary>
        /// <param name="reg"></param>
        /// <param name="memOp"></param>
        /// <returns>The offset value to be emitted as the last piece of the instruction</returns>
        public Constant?EmitModRMPrefix(int reg, MemoryOperand memOp)
        {
            offset = null;
            reg  <<= 3;
            if (memOp.Base != RegisterStorage.None || memOp.Index != RegisterStorage.None)
            {
                PrimitiveType baseWidth  = memOp.Base.DataType;
                PrimitiveType indexWidth = memOp.Index.DataType;
                if (memOp.Base != RegisterStorage.None && memOp.Index != RegisterStorage.None)
                {
                    if (baseWidth != indexWidth)
                    {
                        OnError("mismatched base and index registers");
                        return(null);
                    }
                }

                // Add the 'mod' bits

                if (memOp.Offset != null)
                {
                    Debug.Assert(memOp.Offset.IsValid);
                    if (memOp.Offset.DataType == PrimitiveType.SByte)
                    {
                        reg   |= 0x40;
                        offset = memOp.Offset;
                    }
                    else
                    {
                        reg   |= 0x80;
                        offset = Constant.Create(defaultWordSize, memOp.Offset.ToInt32());
                    }
                }

                bool fNeedsSib = false;
                int  sib       = 0;
                if (baseWidth == PrimitiveType.Word16)
                {
                    reg |= Get16AddressingModeMask(memOp);
                }
                else if (baseWidth == PrimitiveType.Word32 || indexWidth == PrimitiveType.Word32)
                {
                    if (memOp.Index == RegisterStorage.None)
                    {
                        if (memOp.Base != Registers.esp)
                        {
                            reg |= X86Assembler.RegisterEncoding(memOp.Base);
                            if (memOp.Offset == null && memOp.Base == Registers.ebp)
                            {
                                reg   |= 0x40;
                                offset = Constant.Byte(0);
                            }
                        }
                        else
                        {
                            reg      |= 0x04;
                            fNeedsSib = true;
                            sib       = 0x24;
                        }
                    }
                    else
                    {
                        reg      |= 0x04;
                        fNeedsSib = true;
                        switch (memOp.Scale)
                        {
                        case 1: sib = 0; break;

                        case 2: sib = 0x40; break;

                        case 4: sib = 0x80; break;

                        case 8: sib = 0xC0; break;

                        default: OnError("Scale factor must be 1, 2, 4, or 8"); return(Constant.Invalid);
                        }

                        if (memOp.Base == RegisterStorage.None)
                        {
                            sib |= 0x05;
                            reg &= ~0xC0;                                               // clear mod part of modRM.

                            if (memOp.Offset == null)
                            {
                                offset = Constant.Word32(0);
                            }
                        }
                        else
                        {
                            sib |= X86Assembler.RegisterEncoding(memOp.Base);
                        }

                        if (memOp.Index != Registers.esp)
                        {
                            sib |= X86Assembler.RegisterEncoding(memOp.Index) << 3;
                        }
                        else
                        {
                            throw new ApplicationException("ESP register can't be used as an index register");
                        }
                    }
                }
                else
                {
                    throw new ApplicationException("unexpected address width");
                }

                emitter.EmitByte(reg);
                if (fNeedsSib)
                {
                    emitter.EmitByte(sib);
                }
                return(offset);
            }
            else
            {
                return(EmitDirectAddress(reg, memOp));
            }
        }
Example #19
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);
        }
Example #20
0
 public Expression Transform()
 {
     ctx.RemoveIdentifierUse(idLeft);
     return(new BinaryExpression(Operator.IMul, idLeft.DataType, idLeft, Constant.Create(idLeft.DataType, 2)));
 }
Example #21
0
 public override IExpression Invoke(IExpressionContext context)
 {
     return(Constant.Create(nameof(Select), Expressions.SafeInvoke(context).ToList()));
 }
Example #22
0
 public Expression Const(DataType dataType, int p)
 {
     return(Constant.Create(dataType, p));
 }
Example #23
0
        public virtual Expression VisitMkSequence(MkSequence seq)
        {
            var newSeq = seq.Expressions.Select(e =>
            {
                var eNew = e.Accept(this);
                if (eNew == Constant.Invalid)
                {
                    eNew = e;
                }
                return(eNew);
            }).ToArray();

            if (newSeq.Length == 2)
            {
                // Special case for the frequent case of segment:offset or
                // two concatenated bit vectors.
                if (newSeq[0] is Constant c1 && newSeq[1] is Constant c2)
                {
                    PrimitiveType tHead = (PrimitiveType)c1.DataType;
                    PrimitiveType tTail = (PrimitiveType)c2.DataType;
                    PrimitiveType t;
                    Changed = true;
                    if (tHead.Domain == Domain.Selector)            //$REVIEW: seems to require Address, SegmentedAddress?
                    {
                        t = PrimitiveType.Create(Domain.Pointer, tHead.BitSize + tTail.BitSize);
                        return(ctx.MakeSegmentedAddress(c1, c2));
                    }
                    else
                    {
                        t = PrimitiveType.Create(tHead.Domain, tHead.BitSize + tTail.BitSize);
                        return(Constant.Create(t, (c1.ToUInt64() << tTail.BitSize) | c2.ToUInt64()));
                    }
                }
            }
            else if (newSeq.All(e => e is Constant))
            {
                //$TODO: > 64 bit values?
                ulong value = 0;
                for (int i = 0; i < newSeq.Length; ++i)
                {
                    var c = (Constant)newSeq[i];
                    value = (value << c.DataType.BitSize) | c.ToUInt64();
                }
                return(Constant.Create(seq.DataType, value));
            }
            if (newSeq.Take(newSeq.Length - 1).All(e => e.IsZero))
            {
                var tail = newSeq.Last();
                // leading zeros imply a conversion to unsigned.
                return(new Conversion(
                           tail,
                           PrimitiveType.Create(Domain.UnsignedInt, tail.DataType.BitSize),
                           PrimitiveType.Create(Domain.UnsignedInt, seq.DataType.BitSize)));
            }
            var mem = FuseAdjacentMemoryAccesses(seq.DataType, newSeq);

            if (mem != null)
            {
                return(mem);
            }
            return(FuseAdjacentSlices(seq.DataType, newSeq));
        }
 public void ExaUsrGlobals_Real32()
 {
     Given_GlobalVariable(
         Address.Ptr32(0x10001200), PrimitiveType.Real32);
     RunTest(Constant.Create(PrimitiveType.Real32, 0x10001200));
 }
Example #25
0
        }                                                // the data width of the current instruction being rewritten.

        /// <summary>
        /// Rewrite operands being used as sources.
        /// </summary>
        /// <param name="operand"></param>
        /// <param name="addrInstr">Address of the current instruction</param>
        /// <returns></returns>
        public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false)
        {
            var reg = operand as RegisterOperand;

            if (reg != null)
            {
                Expression r = binder.EnsureRegister(reg.Register);
                if (DataWidth != null && DataWidth.Size != reg.Width.Size)
                {
                    r = m.Cast(DataWidth, r);
                }
                return(r);
            }
            var imm = operand as M68kImmediateOperand;

            if (imm != null)
            {
                if (imm.Width.Domain == Domain.Real)
                {
                    return(imm.Constant.CloneExpression());
                }
                if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize)
                {
                    return(Constant.Create(DataWidth, imm.Constant.ToInt64()));
                }
                else
                {
                    return(Constant.Create(imm.Width, imm.Constant.ToUInt32()));
                }
            }
            var mem = operand as MemoryOperand;

            if (mem != null)
            {
                return(RewriteMemoryAccess(mem, DataWidth, addrInstr));
            }
            var addr = operand as M68kAddressOperand;

            if (addr != null)
            {
                if (addressAsAddress)
                {
                    return(addr.Address);
                }
                else
                {
                    return(m.Mem(DataWidth, addr.Address));
                }
            }
            var pre = operand as PredecrementMemoryOperand;

            if (pre != null)
            {
                var ea = binder.EnsureRegister(pre.Register);
                m.Assign(ea, m.ISub(ea, m.Int32(DataWidth.Size)));
                return(m.Mem(DataWidth, ea));
            }
            var post = operand as PostIncrementMemoryOperand;

            if (post != null)
            {
                var r   = binder.EnsureRegister(post.Register);
                var tmp = binder.CreateTemporary(DataWidth);
                m.Assign(tmp, m.Mem(DataWidth, r));
                m.Assign(r, m.IAdd(r, m.Int32(DataWidth.Size)));
                return(tmp);
            }
            var indidx = operand as IndirectIndexedOperand;

            if (indidx != null)
            {
                Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr);
                Expression ix = binder.EnsureRegister(indidx.XRegister);
                if (indidx.XWidth.Size != 4)
                {
                    ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix));
                }
                if (indidx.Scale > 1)
                {
                    ix = m.IMul(ix, Constant.Int32(indidx.Scale));
                }
                return(m.Mem(DataWidth, m.IAdd(ea, ix)));
            }
            var indop = operand as IndexedOperand;

            if (indop != null)
            {
                Expression ea = Combine(indop.Base, indop.base_reg);
                if (indop.postindex)
                {
                    ea = m.Mem32(ea);
                }
                if (indop.index_reg != null)
                {
                    var idx = Combine(null, indop.index_reg);
                    if (indop.index_reg_width.BitSize != 32)
                    {
                        idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx));
                    }
                    if (indop.index_scale > 1)
                    {
                        idx = m.IMul(idx, indop.index_scale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.Mem32(ea);
                }
                ea = Combine(ea, indop.outer);
                return(m.Mem(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
Example #26
0
 private void RewriteOne(PrimitiveType dt)
 {
     m.Assign(RewriteSrc(instr.Operands[0]), Constant.Create(dt, 1));
 }
Example #27
0
        public virtual Expression VisitConversion(Conversion conversion)
        {
            var exp = conversion.Expression.Accept(this);

            if (exp != Constant.Invalid)
            {
                var ptCvt = conversion.DataType.ResolveAs <PrimitiveType>();
                var ptSrc = conversion.SourceDataType.ResolveAs <PrimitiveType>();
                if (exp is Constant c && ptCvt != null)
                {
                    if (ptSrc != null)
                    {
                        if (ptCvt.Domain == Domain.Real)
                        {
                            if (ptSrc.Domain == Domain.Real)
                            {
                                if (ptCvt.Size < ptSrc.Size)
                                {
                                    // Real-to-real conversion.
                                    Changed = true;
                                    return(ConstantReal.Create(ptCvt, c.ToReal64()));
                                }
                            }
                            else if (ptSrc.IsWord)
                            {
                                // Raw bit pattern reinterpretation.
                                Changed = true;
                                return(CastRawBitsToReal(ptCvt, c));
                            }
                            else
                            {
                                // integer to real conversion
                                Changed = true;
                                return(ConstantReal.Create(ptCvt, c.ToInt64()));
                            }
                        }
                        else if ((ptSrc.Domain & Domain.Integer) != 0)
                        {
                            if (ptSrc != null)
                            {
                                if (ptSrc.Domain == Domain.SignedInt)
                                {
                                    Changed = true;
                                    return(Constant.Create(ptCvt, c.ToInt64()));
                                }
                                else if (ptSrc.Domain.HasFlag(Domain.SignedInt))
                                {
                                    Changed = true;
                                    return(Constant.Create(ptCvt, c.ToUInt64()));
                                }
                            }
                        }
                    }
                }
                if (exp is Identifier id &&
                    ctx.GetDefiningExpression(id) is MkSequence seq)
                {
                    // If we are casting a SEQ, and the corresponding element is >=
                    // the size of the cast, then use deposited part directly.
                    var lsbElem  = seq.Expressions[seq.Expressions.Length - 1];
                    int sizeDiff = lsbElem.DataType.Size - conversion.DataType.Size;
                    if (sizeDiff >= 0)
                    {
                        foreach (var elem in seq.Expressions)
                        {
                            ctx.RemoveExpressionUse(elem);
                        }
                        ctx.UseExpression(lsbElem);
                        Changed = true;
                        if (sizeDiff > 0)
                        {
                            return(new Conversion(lsbElem, lsbElem.DataType, conversion.DataType));
                        }
                        else
                        {
                            return(lsbElem);
                        }
                    }
                }
                if (exp is ProcedureConstant pc && conversion.DataType.BitSize == pc.DataType.BitSize)
                {
                    // (wordnn) procedure_const => procedure_const
                    return(pc);
                }
                if (exp.DataType.BitSize == conversion.DataType.BitSize)
                {
                    // Redundant word-casts can be stripped.
                    if (conversion.DataType.IsWord)
                    {
                        return(exp);
                    }
                }
                conversion = new Conversion(exp, exp.DataType, conversion.DataType);
            }
            if (convertConvertRule.Match(conversion))
            {
                Changed = true;
                return(convertConvertRule.Transform());
            }
            return(conversion);
        }
Example #28
0
 private BinaryExpression CmpExpressionToZero(Expression e)
 {
     return(new BinaryExpression(Operator.ISub, e.DataType, e, Constant.Create(e.DataType, 0)));
 }
Example #29
0
        /// <summary>
        /// Memory accesses are translated into expressions, performing simplifications
        /// where possible.
        /// </summary>
        public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem)
        {
            Expression?eIndex      = null;
            Expression?eBase       = null;
            Expression?expr        = null;
            bool       ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = m.IAdd(eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset !.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long           l  = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l  = -l;
                        op = Operator.ISub;
                    }

                    DataType dt      = (eBase != null) ? eBase.DataType : eIndex !.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = m.IMul(eIndex, Constant.Create(mem.Index.DataType, mem.Scale));
                }
                expr = m.IAdd(expr !, eIndex);
            }
            if (!IsSegmentedAccessRequired && expr is Constant c && mem.SegOverride == RegisterStorage.None)
            {
                return(arch.MakeAddressFromConstant(c, false) !);
            }
            return(expr !);
        }
Example #30
0
        public void AddPointerReference(ulong imageOffset, uint pointer)
        {
            var c = Constant.Create(PrimitiveType.Pointer32, pointer);

            map.Add(imageOffset, c);
        }