Example #1
0
        private bool OnAfterCall(ProcedureSignature sigCallee, ProcedureCharacteristics characteristics)
        {
            UserCallData userCall = null;

            if (program.User.Calls.TryGetUpperBound(ric.Address, out userCall))
            {
                var linStart    = ric.Address.ToLinear();
                var linEnd      = linStart + ric.Length;
                var linUserCall = userCall.Address.ToLinear();
                if (linStart > linUserCall || linUserCall >= linEnd)
                {
                    userCall = null;
                }
            }
            if ((characteristics != null && characteristics.Terminates) ||
                (userCall != null && userCall.NoReturn))
            {
                scanner.TerminateBlock(blockCur, ric.Address + ric.Length);
                return(false);
            }

            if (sigCallee != null)
            {
                if (sigCallee.StackDelta != 0)
                {
                    Expression newVal = new BinaryExpression(
                        Operator.IAdd,
                        stackReg.DataType,
                        stackReg,
                        Constant.Create(
                            PrimitiveType.CreateWord(stackReg.DataType.Size),
                            sigCallee.StackDelta));
                    newVal = newVal.Accept(eval);
                    SetValue(stackReg, newVal);
                }
            }
            state.OnAfterCall(sigCallee);

            // Adjust stack after call
            if (sigCallee != null)
            {
                int delta = sigCallee.StackDelta - sigCallee.ReturnAddressOnStack;
                if (delta != 0)
                {
                    var d = Constant.Create(stackReg.DataType, delta);
                    this.Emit(new Assignment(
                                  stackReg,
                                  new BinaryExpression(Operator.IAdd, stackReg.DataType, stackReg, d)));
                }
            }
            return(true);
        }
Example #2
0
        public Expression?ResolveToImportedValue(Statement stm, Constant c)
        {
            var addrInstruction = program.SegmentMap.MapLinearAddressToAddress(stm.LinearAddress);
            var addrImportThunk = program.Platform.MakeAddressFromConstant(c, true);

            if (addrImportThunk is null)
            {
                return(null);
            }
            if (!program.ImportReferences.TryGetValue(addrImportThunk, out var impref))
            {
                return(null);
            }

            if (impref.SymbolType == SymbolType.Procedure)
            {
                if (!this.localProcs.TryGetValue(impref.EntryName, out var sym))
                {
                    return(null);
                }
                if (!program.Procedures.TryGetValue(sym.Address !, out var proc))
                {
                    return(null);
                }
                return(new ProcedureConstant(program.Platform.PointerType, proc));
            }
            else if (impref.SymbolType == SymbolType.Data)
            {
                // Read an address sized value at the given address.
                if (!program.SegmentMap.TryFindSegment(impref.ReferenceAddress, out ImageSegment seg))
                {
                    return(null);
                }
                var dt = PrimitiveType.CreateWord(impref.ReferenceAddress.DataType.BitSize);
                if (!program.Architecture.TryRead(seg.MemoryArea, impref.ReferenceAddress, dt, out Constant cIndirect))
                {
                    return(Constant.Invalid);
                }
                return(Constant.Create(program.Architecture.WordWidth, cIndirect.ToInt64()));
            }
            else
            {
                //$TODO: need to work on imported data symbols
                // for now, treat them as imported procedures.

                var extProc = impref.ResolveImportedProcedure(
                    this,
                    program.Platform,
                    new AddressContext(program, addrInstruction, this.eventListener));
                return(new ProcedureConstant(program.Platform.PointerType, extProc));
            }
        }
Example #3
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);

                var        f  = EnsureFieldAtOffset(baseType, dt.Pointee, c.ToInt32());
                Expression ex = new FieldAccess(f.DataType, new Dereference(ptrSeg, segId), f);
                if (dereferenced || dt.Pointee is ArrayType)
                {
                    return(ex);
                }
                else
                {
                    var un = new UnaryExpression(Operator.AddrOf, dt, 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 #4
0
        private void RewriteAr()
        {
            var src   = Reg(1);
            var dst   = Reg(0);
            var dt    = PrimitiveType.Word32;
            var tmp   = binder.CreateTemporary(dt);
            var tmpHi = binder.CreateTemporary(PrimitiveType.CreateWord(src.DataType.BitSize - dt.BitSize));

            m.Assign(tmp, m.IAdd(m.Convert(dst, dst.DataType, dt), m.Convert(src, src.DataType, dt)));
            m.Assign(tmpHi, m.Slice(tmpHi.DataType, dst, dt.BitSize));
            m.Assign(dst, m.Seq(tmpHi, tmp));
            SetCc(m.Cond(tmp));
        }
Example #5
0
        private void RewriteCmpp(bool isVex, string name, PrimitiveType element)
        {
            var dst = this.SrcOp(0);
            var src = this.SrcOp(1);

            RewritePackedTernaryop(
                isVex,
                name,
                element,
                CreatePackedArrayType(
                    PrimitiveType.CreateWord(element.BitSize),
                    dst.DataType));
        }
Example #6
0
        private void RewriteMulaIncDec(string fnName, PrimitiveType dtProduct, int increment)
        {
            var addr = RewriteOp(instr.Operands[1]);

            m.Assign(addr, m.AddSubSignedInt(addr, increment));
            var src1    = RewriteOp(instr.Operands[2]);
            var src2    = RewriteOp(instr.Operands[3]);
            var product = host.PseudoProcedure(fnName, dtProduct, src1, src2);
            var dst     = binder.EnsureSequence(PrimitiveType.CreateWord(40), Registers.ACCHI, Registers.ACCLO);

            m.Assign(dst, m.IAdd(dst, product));
            m.Assign(RewriteOp(instr.Operands[0]), m.Mem32(addr));
        }
Example #7
0
        public Expression VisitSequenceStorage(SequenceStorage seq)
        {
            var h      = seq.Head.Storage.Accept(this);
            var t      = seq.Tail.Storage.Accept(this);
            var idHead = h as Identifier;
            var idTail = t as Identifier;

            if (idHead != null && idTail != null)
            {
                return(frame.EnsureSequence(idHead, idTail, PrimitiveType.CreateWord(idHead.DataType.Size + idTail.DataType.Size)));
            }
            throw new NotImplementedException("Handle case when stack parameter is passed.");
        }
Example #8
0
 private void Copy(Expression dst, Expression src, int bitSize)
 {
     if (dst is Identifier && dst.DataType.BitSize > bitSize)
     {
         var tmpHi = binder.CreateTemporary(PrimitiveType.CreateWord(dst.DataType.BitSize - bitSize));
         m.Assign(tmpHi, m.Slice(tmpHi.DataType, dst, bitSize));
         m.Assign(dst, m.Seq(tmpHi, src));
     }
     else
     {
         m.Assign(dst, src);
     }
 }
Example #9
0
        private void RewriteDiv(Func <Expression, Expression, Expression> op, DataType dt)
        {
            var        src = orw.RewriteSrc(instr.Operands[0], instr.Address);
            Expression dividend;
            Expression quot;
            Expression rem;

            if (instr.dataWidth.BitSize == 16)
            {
                instr.dataWidth = PrimitiveType.UInt32;
                rem             = binder.CreateTemporary(dt);
                quot            = binder.CreateTemporary(dt);
                dividend        = binder.EnsureRegister(((RegisterOperand)instr.Operands[1]).Register);
                m.Assign(rem, m.Cast(rem.DataType, m.Remainder(dividend, src)));
                m.Assign(quot, m.Cast(quot.DataType, op(dividend, src)));
                m.Assign(dividend, m.Seq(rem, quot));
            }
            else
            {
                if (instr.Operands[1] is DoubleRegisterOperand dreg)
                {
                    rem  = binder.EnsureRegister(dreg.Register1);
                    quot = binder.EnsureRegister(dreg.Register2);
                    if (instr.code == Mnemonic.divsl)
                    {
                        dividend = quot;
                    }
                    else
                    {
                        var dtDividend = PrimitiveType.CreateWord((int)(dreg.Register1.BitSize + dreg.Register2.BitSize));
                        dividend = binder.EnsureSequence(dtDividend, dreg.Register1, dreg.Register2);
                    }
                    m.Assign(rem, m.Remainder(dividend, src));
                    m.Assign(quot, op(dividend, src));
                }
                else
                {
                    rem  = orw.RewriteSrc(instr.Operands[0], instr.Address);
                    quot = orw.RewriteSrc(instr.Operands[1], instr.Address);
                    var divisor = binder.CreateTemporary(rem.DataType);
                    m.Assign(divisor, rem);
                    m.Assign(rem, m.Remainder(quot, divisor));
                    m.Assign(quot, op(quot, divisor));
                }
            }
            m.Assign(
                orw.FlagGroup(FlagM.NF | FlagM.VF | FlagM.ZF),
                m.Cond(quot));
            m.Assign(
                orw.FlagGroup(FlagM.CF), Constant.False());
        }
Example #10
0
        private void RewritePush()
        {
            if (instrCur.Operands[0] is RegisterOperand reg && reg.Register == Registers.cs)
            {
                // Is it a 'push cs;call near XXXX' sequence that simulates a far call?
                X86Instruction?p1 = dasm.Peek(1);
                if (p1 is not null &&
                    p1.Mnemonic == Mnemonic.call &&
                    p1.Operands[0].Width.BitSize == 16)
                {
                    dasm.MoveNext();
                    MachineOperand targetOperand = dasm.Current.Operands[0];

                    if (targetOperand is ImmediateOperand immOperand)
                    {
                        targetOperand = AddressOperand.Create(orw.ImmediateAsAddress(instrCur.Address, immOperand));
                    }
                    else
                    {
                        m.Assign(StackPointer(), m.ISubS(StackPointer(), reg.Register.DataType.Size));
                    }

                    RewriteCall(targetOperand, targetOperand.Width);
                    this.len = (byte)(this.len + dasm.Current.Length);
                    return;
                }

                X86Instruction?p2 = dasm.Peek(2);
                X86Instruction?p3 = dasm.Peek(3);
                if (p1 is not null && p2 is not null && p3 is not null &&
                    (p1.Mnemonic == Mnemonic.push && (p1.Operands[0] is ImmediateOperand)) &&
                    (p2.Mnemonic == Mnemonic.push && (p2.Operands[0] is ImmediateOperand)) &&
                    (p3.Mnemonic == Mnemonic.jmp && (p3.Operands[0] is AddressOperand)))
                {
                    // That's actually a far call, but the callee thinks its a near call.
                    RewriteCall(p3.Operands[0], instrCur.Operands[0].Width);
                    dasm.MoveNext();
                    dasm.MoveNext();
                    dasm.MoveNext();
                    return;
                }
            }
            var value = SrcOp(0, instrCur.dataWidth);

            Debug.Assert(
                value.DataType.BitSize == 16 ||
                value.DataType.BitSize == 32 ||
                value.DataType.BitSize == 64,
                $"Unexpected size {dasm.Current.dataWidth}");
            RewritePush(PrimitiveType.CreateWord(value.DataType.BitSize), value);
        }
Example #11
0
        public void WriteByteRange(MemoryArea image, IProcessorArchitecture arch, Address begin, Address addrEnd, InstrWriter writer)
        {
            EndianImageReader rdr  = arch.CreateImageReader(image, begin);
            var    byteSize        = (7 + arch.InstructionBitSize) / 8;
            string instrByteFormat = $"{{0:X{byteSize * 2}}} "; // each byte is two nybbles.

            this.instrByteSize = PrimitiveType.CreateWord(arch.InstructionBitSize);

            while (rdr.Address < addrEnd)
            {
                var v = rdr.Read(this.instrByteSize);
                writer.WriteFormat(instrByteFormat, v.ToUInt64());
            }
        }
Example #12
0
        private void RewritePcmp(string fnName, PrimitiveType elementType)
        {
            var       dst     = SrcOp(instrCur.op1);
            ArrayType srcType = CreatePackedArrayType(elementType, dst.DataType);
            ArrayType dstType = new ArrayType(PrimitiveType.CreateWord(srcType.ElementType.Size), srcType.Length);
            var       src1    = SrcOp(instrCur.op1, srcType);
            var       src2    = SrcOp(instrCur.op2, srcType);
            var       tmp1    = binder.CreateTemporary(srcType);
            var       tmp2    = binder.CreateTemporary(srcType);

            m.Assign(tmp1, src1);
            m.Assign(tmp2, src2);
            m.Assign(dst, host.PseudoProcedure(fnName, dstType, tmp1, tmp2));
        }
Example #13
0
        private Expression RewriteOp(MachineOperand op, bool maybe0 = false)
        {
            switch (op)
            {
            case RegisterOperand regOp:
                if (maybe0)
                {
                    if (regOp.Register == Registers.GpRegs32[31])
                    {
                        return(m.Word32(0));
                    }
                    if (regOp.Register == Registers.GpRegs64[31])
                    {
                        return(m.Word64(0));
                    }
                }
                return(binder.EnsureRegister(regOp.Register));

            case ImmediateOperand immOp:
                return(immOp.Value);

            case AddressOperand addrOp:
                return(addrOp.Address);

            case VectorRegisterOperand vectorOp:
                Identifier vreg;
                if (vectorOp.Width.BitSize == 64)
                {
                    vreg = binder.EnsureRegister(Registers.SimdRegs64[vectorOp.VectorRegister.Number - 32]);
                }
                else
                {
                    vreg = binder.EnsureRegister(Registers.SimdRegs128[vectorOp.VectorRegister.Number - 32]);
                }
                if (vectorOp.Index >= 0)
                {
                    var eType = PrimitiveType.CreateWord(Bitsize(vectorOp.ElementType));
                    return(m.ARef(eType, vreg, Constant.Int32(vectorOp.Index)));
                }
                else
                {
                    return(vreg);
                }

            case MemoryOperand mem:
                var ea = binder.EnsureRegister(mem.Base);
                return(m.Mem(mem.Width, ea));
            }
            throw new NotImplementedException($"Rewriting {op.GetType().Name} not implemented yet.");
        }
Example #14
0
        private void RewriteScalarBinop(Func <Expression, Expression, Expression> fn, PrimitiveType size, bool zeroExtend)
        {
            var        dst = SrcOp(instrCur.Operands[0]);
            var        tmp = binder.CreateTemporary(size);
            Expression src1;
            Expression src2;

            if (instrCur.Operands.Length == 3)
            {
                src1 = SrcOp(instrCur.Operands[1]);
                src2 = SrcOp(instrCur.Operands[2]);
            }
            else
            {
                src1 = dst;
                src2 = SrcOp(instrCur.Operands[1]);
            }
            if (src1.DataType.BitSize != size.BitSize)
            {
                src1 = m.Cast(size, src1);
            }
            if (src2.DataType.BitSize != size.BitSize)
            {
                src2 = m.Cast(size, src2);
            }
            m.Assign(tmp, fn(src1, src2));

            //$REVIEW: this does a DPB-ish operation.
            var highBits = dst.DataType.BitSize - size.BitSize;

            if (highBits > 0)
            {
                var        dtHighPart = PrimitiveType.CreateWord(highBits);
                Expression hi;
                if (zeroExtend)
                {
                    hi = Constant.Zero(dtHighPart);
                }
                else
                {
                    hi = binder.CreateTemporary(dtHighPart);
                    m.Assign(hi, m.Slice(dtHighPart, dst, size.BitSize));
                }
                m.Assign(dst, m.Seq(hi, tmp));
            }
            else
            {
                m.Assign(dst, tmp);
            }
        }
Example #15
0
        static Registers()
        {
            var factory = new StorageFactory();

            xt   = factory.Reg32("xt");
            p    = factory.Reg32("p");
            acc  = factory.Reg32("acc");
            sp   = factory.Reg16("sp");
            dp   = factory.Reg16("dp");
            xar0 = factory.Reg16("xar0");
            xar1 = factory.Reg16("xar1");
            xar2 = factory.Reg16("xar2");
            xar3 = factory.Reg16("xar3");
            xar4 = factory.Reg16("xar4");
            xar5 = factory.Reg16("xar5");
            xar6 = factory.Reg16("xar6");
            xar7 = factory.Reg16("xar7");
            pc   = factory.Reg("pc", PrimitiveType.CreateWord(22));
            rpc  = factory.Reg("rpc", PrimitiveType.CreateWord(22));
            st0  = factory.Reg16("st0");
            st1  = factory.Reg16("st1");

            ier    = factory.Reg16("ier");
            dbgier = factory.Reg16("dbgier");
            ifr    = factory.Reg16("ifr");

            t  = new RegisterStorage("t", xt.Number, 16, PrimitiveType.Word16);
            tl = new RegisterStorage("tl", xt.Number, 0, PrimitiveType.Word16);
            ph = new RegisterStorage("ph", p.Number, 16, PrimitiveType.Word16);
            pl = new RegisterStorage("pl", p.Number, 0, PrimitiveType.Word16);
            ah = new RegisterStorage("ah", acc.Number, 16, PrimitiveType.Word16);
            al = new RegisterStorage("al", acc.Number, 0, PrimitiveType.Word16);

            ar0h = new RegisterStorage("ar0h", acc.Number, 16, PrimitiveType.Word16);
            ar0l = new RegisterStorage("ar0l", acc.Number, 0, PrimitiveType.Word16);
            ar1h = new RegisterStorage("ar1h", acc.Number, 16, PrimitiveType.Word16);
            ar1l = new RegisterStorage("ar1l", acc.Number, 0, PrimitiveType.Word16);
            ar2h = new RegisterStorage("ar2h", acc.Number, 16, PrimitiveType.Word16);
            ar2l = new RegisterStorage("ar2l", acc.Number, 0, PrimitiveType.Word16);
            ar3h = new RegisterStorage("ar3h", acc.Number, 16, PrimitiveType.Word16);
            ar3l = new RegisterStorage("ar3l", acc.Number, 0, PrimitiveType.Word16);
            ar4h = new RegisterStorage("ar4h", acc.Number, 16, PrimitiveType.Word16);
            ar4l = new RegisterStorage("ar4l", acc.Number, 0, PrimitiveType.Word16);
            ar5h = new RegisterStorage("ar5h", acc.Number, 16, PrimitiveType.Word16);
            ar5l = new RegisterStorage("ar5l", acc.Number, 0, PrimitiveType.Word16);
            ar6h = new RegisterStorage("ar6h", acc.Number, 16, PrimitiveType.Word16);
            ar6l = new RegisterStorage("ar6l", acc.Number, 0, PrimitiveType.Word16);
            ar7h = new RegisterStorage("ar7h", acc.Number, 16, PrimitiveType.Word16);
            ar7l = new RegisterStorage("ar7l", acc.Number, 0, PrimitiveType.Word16);
        }
Example #16
0
        public void GdwLargeBlob()
        {
            var blobType = PrimitiveType.CreateWord(0x50);

            Given_Memory(0x1000)
            .WriteBytes(Enumerable.Range(0x30, 0x0A).Select(b => (byte)b).ToArray());
            Given_Globals(
                Given_Field(0x1000, blobType));
            RunTest(@"word80 g_n1000 = 
{
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 
};
");
        }
Example #17
0
 /// <summary>
 /// Returns a list of all stack arguments accessed, indexed by their offsets
 /// as seen by a caller. I.e. the first argument is at offset 0, &c.
 /// </summary>
 public IEnumerable <(int, Identifier)> GetSortedStackArguments(Frame frame, IEnumerable <KeyValuePair <Storage, BitRange> > mayuse)
 {
     return(mayuse
            .Select(kv => (stg: kv.Key as StackStorage, range: kv.Value))
            .Where(item => item.stg != null)
            .OrderBy(item => item.stg !.StackOffset)
            .Select(item =>
     {
         var id = frame.EnsureStackArgument(
             item.stg !.StackOffset,
             PrimitiveType.CreateWord(item.range.Extent));
         return (item.stg.StackOffset - frame.ReturnAddressSize, id);
     }));
 }
Example #18
0
        private void RewriteAr()
        {
            var src   = Reg(instr.Operands[1]);
            var dst   = Reg(instr.Operands[0]);
            var dt    = PrimitiveType.Word32;
            var tmp   = binder.CreateTemporary(dt);
            var tmpHi = binder.CreateTemporary(PrimitiveType.CreateWord(src.DataType.BitSize - dt.BitSize));

            m.Assign(tmp, m.IAdd(m.Convert(dst, dst.DataType, dt), m.Convert(src, src.DataType, dt)));
            m.Assign(tmpHi, m.Slice(tmpHi.DataType, dst, dt.BitSize));
            m.Assign(dst, m.Seq(tmpHi, tmp));
            var cc = binder.EnsureFlagGroup(Registers.CC);

            m.Assign(cc, m.Cond(tmp));
        }
Example #19
0
        private void RewriteNc()
        {
            var len   = ((MemoryOperand)instr.Operands[0]).Length;
            var dt    = PrimitiveType.CreateWord(len);
            var eaSrc = EffectiveAddress(1);
            var tmp   = binder.CreateTemporary(dt);
            var eaDst = EffectiveAddress(0);

            m.Assign(tmp, m.And(m.Mem(dt, eaDst), m.Mem(dt, eaSrc)));
            m.Assign(m.Mem(dt, eaDst), tmp);

            var cc = binder.EnsureFlagGroup(Registers.CC);

            m.Assign(cc, m.Cond(tmp));
        }
Example #20
0
        /// <summary>
        /// If the bit size of the expression is less than the target register, pad it with
        /// an IEEE NaN as specified by the RiscV manual.
        /// </summary>
        /// <param name="exp"></param>
        private Expression MaybeNanBox(Expression exp, DataType dtDst)
        {
            int cbNanBox = dtDst.BitSize - exp.DataType.BitSize;

            if (cbNanBox > 0)
            {
                var dtNan = PrimitiveType.CreateWord(cbNanBox);
                var nan   = Constant.Create(dtNan, -1L);
                return(m.Seq(nan, exp));
            }
            else
            {
                return(exp);
            }
        }
Example #21
0
 private DataType GetSymbolDataType(ElfSymbol sym)
 {
     if (sym.Type == ElfSymbolType.STT_FUNC)
     {
         return(new FunctionType());
     }
     else if ((int)sym.Size == Architecture.PointerType.Size)
     {
         return(PrimitiveType.CreateWord(DataType.BitsPerByte * (int)sym.Size));
     }
     else
     {
         return(new UnknownType((int)sym.Size));
     }
 }
Example #22
0
        private void RewriteSrc()
        {
            var src1 = (Identifier)RewriteOp(instr.Operands[1]);
            var src2 = (Identifier)RewriteOp(instr.Operands[2]);
            var dst  = RewriteOp(instr.Operands[0]);
            var sa   = frame.EnsureRegister(Registers.SAR);
            var cat  = frame.EnsureSequence(
                src1.Storage,
                src2.Storage,
                PrimitiveType.CreateWord(src1.DataType.Size + src2.DataType.Size));

            emitter.Assign(
                dst,
                emitter.Cast(dst.DataType, emitter.Shr(cat, sa)));
        }
Example #23
0
        private void RewriteSrc()
        {
            var src1 = (Identifier)RewriteOp(instr.Operands[1]);
            var src2 = (Identifier)RewriteOp(instr.Operands[2]);
            var dst  = RewriteOp(instr.Operands[0]);
            var sa   = binder.EnsureRegister(Registers.SAR);
            var cat  = binder.EnsureSequence(
                PrimitiveType.CreateWord(src1.DataType.BitSize + src2.DataType.BitSize),
                src1.Storage,
                src2.Storage);

            m.Assign(
                dst,
                m.Cast(dst.DataType, m.Shr(cat, sa)));
        }
Example #24
0
        public void VpGitHub942()
        {
            var rax_6       = m.Reg64("rax_6");
            var rbx_7       = m.Reg64("rbx_7");
            var ax_8        = m.Reg16("ax_8");
            var rax_10      = m.Reg64("rax_10");
            var rax_48_16_9 = m.Temp(PrimitiveType.CreateWord(48), "rax_48_16_9");

            m.Assign(rax_6, m.Word64(0x1A2A3A4A5A6A7A8A));
            m.Assign(rax_48_16_9, m.Slice(rax_48_16_9.DataType, rax_6, 16));
            m.Assign(rbx_7, m.Word64(0x1B2B3B4B5B6B7B8B));
            m.Assign(ax_8, m.Slice(ax_8.DataType, rbx_7, 0));
            m.Assign(rax_10, m.Seq(rax_48_16_9, ax_8));
            m.MStore(m.Word32(0x123400), rax_10);

            RunValuePropagator();
            var sExp =
                #region Expected
                @"rax_6: orig: rax_6
    def:  rax_6 = 0x1A2A3A4A5A6A7A8A<64>
rbx_7: orig: rbx_7
    def:  rbx_7 = 0x1B2B3B4B5B6B7B8B<64>
ax_8: orig: ax_8
    def:  ax_8 = 0x7B8B<16>
rax_10: orig: rax_10
    def:  rax_10 = 0x1A2A3A4A5A6A7B8B<64>
rax_48_16_9: orig: rax_48_16_9
    def:  rax_48_16_9 = 0x1A2A3A4A5A6A<48>
Mem5: orig: Mem0
    def:  Mem5[0x123400<32>:word64] = 0x1A2A3A4A5A6A7B8B<64>
// SsaProcedureBuilder
// Return size: 0
define SsaProcedureBuilder
SsaProcedureBuilder_entry:
	// succ:  l1
l1:
	rax_6 = 0x1A2A3A4A5A6A7A8A<64>
	rax_48_16_9 = 0x1A2A3A4A5A6A<48>
	rbx_7 = 0x1B2B3B4B5B6B7B8B<64>
	ax_8 = 0x7B8B<16>
	rax_10 = 0x1A2A3A4A5A6A7B8B<64>
	Mem5[0x123400<32>:word64] = 0x1A2A3A4A5A6A7B8B<64>
SsaProcedureBuilder_exit:
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }
Example #25
0
        public Identifier Deserialize(SerializedSequence sq)
        {
            var      h = arch.GetRegister(sq.Registers[0].Name.Trim());
            var      t = arch.GetRegister(sq.Registers[1].Name.Trim());
            DataType dt;

            if (this.argCur.Type != null)
            {
                dt = this.argCur.Type.Accept(procSer.TypeLoader);
            }
            else
            {
                dt = PrimitiveType.CreateWord(h.DataType.BitSize + h.DataType.BitSize);
            }
            return(frame.EnsureSequence(h, t, dt));
        }
Example #26
0
 public DataType VisitBaseType(LLVMBaseType b)
 {
     switch (b.Domain)
     {
     case Domain.Integral:
         if (b.BitSize == 1)
             return PrimitiveType.Bool;
         else 
             return PrimitiveType.CreateWord(b.BitSize / 8);
     case Domain.Real:
         return PrimitiveType.Create(Core.Types.Domain.Real, b.BitSize / 8);
     case Domain.Void:
         return VoidType.Instance;
     }
     throw new NotImplementedException(string.Format("{0}", b));
 }
Example #27
0
        private void RewritePcmp(string fnName, PrimitiveType elementType)
        {
            var       dst     = SrcOp(0);
            ArrayType srcType = CreatePackedArrayType(elementType, dst.DataType);
            ArrayType dstType = new ArrayType(
                PrimitiveType.CreateWord(srcType.ElementType.BitSize),
                srcType.Length);
            var src1 = SrcOp(0, srcType);
            var src2 = SrcOp(1, srcType);
            var tmp1 = binder.CreateTemporary(srcType);
            var tmp2 = binder.CreateTemporary(srcType);

            m.Assign(tmp1, src1);
            m.Assign(tmp2, src2);
            m.Assign(dst, host.Intrinsic(fnName, false, dstType, tmp1, tmp2));
        }
Example #28
0
        private Identifier ExtendedRegister(RegisterRange range)
        {
            int nRegs       = range.MaxRegister - range.MinRegister + 1;
            var regSequence = new Storage[nRegs];
            int bitsize     = 0;

            for (int i = 0; i < nRegs; ++i)
            {
                var reg = range.Registers[range.MaxRegister - i];
                regSequence[i] = reg;
                bitsize       += reg.DataType.BitSize;
            }
            var dt = PrimitiveType.CreateWord(bitsize);

            return(binder.EnsureSequence(dt, regSequence));
        }
Example #29
0
        public Identifier EnsureIdentifier(Storage stgForeign)
        {
            var reg = stgForeign as RegisterStorage;

            if (reg != null)
            {
                return(EnsureRegister(reg));
            }
            var grf = stgForeign as FlagGroupStorage;

            if (grf != null)
            {
                return(EnsureFlagGroup(grf));
            }
            var seq = stgForeign as SequenceStorage;

            if (seq != null)
            {
                return(EnsureSequence(
                           seq.Name,
                           seq.Head,
                           seq.Tail,
                           PrimitiveType.CreateWord(
                               (int)(seq.Head.BitSize + seq.Tail.BitSize) / DataType.BitsPerByte)));
            }
            var fp = stgForeign as FpuStackStorage;

            if (fp != null)
            {
                return(EnsureFpuStackVariable(fp.FpuStackOffset, fp.DataType));
            }
            var st = stgForeign as StackStorage;

            if (st != null)
            {
                return(EnsureStackVariable(st.StackOffset, st.DataType));
            }
            var tmp = stgForeign as TemporaryStorage;

            if (tmp != null)
            {
                return(CreateTemporary(tmp.Name, tmp.DataType));
            }
            throw new NotImplementedException(string.Format(
                                                  "Unsupported storage {0}.",
                                                  stgForeign != null ? stgForeign.ToString() : "(null)"));
        }
Example #30
0
        private DataType PullDiffDataType(DataType dtLeft, DataType dtRight)
        {
            var ptLeft  = dtLeft as PrimitiveType;
            var ptRight = dtRight.ResolveAs <PrimitiveType>();

            if (ptLeft != null && ptLeft.Domain == Domain.Pointer ||
                dtLeft is Pointer)
            {
                if (ptRight != null)
                {
                    if ((ptRight.Domain & Domain.Integer) != 0)
                    {
                        return(PrimitiveType.Create(Domain.Pointer, dtLeft.BitSize));
                    }
                    else if ((ptRight.Domain & Domain.Pointer) != 0)
                    {
                        return(PrimitiveType.Create(Domain.SignedInt, dtLeft.BitSize));
                    }
                }
                if (dtRight is Pointer)
                {
                    return(PrimitiveType.Create(Domain.SignedInt, dtLeft.BitSize));
                }
                // We are unable to reconcile the differences here.
                return(PrimitiveType.CreateWord(dtLeft.BitSize));
                //$TODO: should be a warning? throw new TypeInferenceException(string.Format("Pulling difference {0} and {1}", dtLeft, dtRight));
            }
            if (ptRight != null && ptRight.Domain == Domain.Pointer ||
                dtRight is Pointer)
            {
                if (ptRight != null && (ptRight.Domain & Domain.Integer) != 0)
                {
                    return(dtLeft);
                }
                // If a dtRight is a pointer and it's being subtracted from
                // something, then the result has to be a ptrdiff_t, i.e.
                // integer.
                if (ptLeft != null && (ptLeft.Domain & Domain.Pointer) != 0)
                {
                    return(PrimitiveType.Create(Domain.Integer, dtLeft.BitSize));
                }
                // We are unable to reconcile the differences here.
                return(PrimitiveType.CreateWord(dtLeft.BitSize));
                //$TODO: should be a warning? throw new TypeInferenceException(string.Format("Pulling difference {0} and {1}", dtLeft, dtRight));
            }
            return(dtLeft);
        }