private void RewriteCvttsd2si() { instrCur.op1.Width = PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size); emitter.Assign(SrcOp(instrCur.op1), emitter.Cast(instrCur.op1.Width, SrcOp(instrCur.op2))); }
public bool VisitBinaryExpression(BinaryExpression binExp, TypeVariable tv) { var eLeft = binExp.Left; var eRight = binExp.Right; if (binExp.Operator == Operator.IAdd) { var dt = PushAddendDataType(binExp.TypeVariable !.DataType, eRight.TypeVariable !.DataType); if (dt != null) { MeetDataType(eLeft, dt); } dt = PushAddendDataType(binExp.TypeVariable !.DataType, eLeft.TypeVariable !.DataType); if (dt != null) { MeetDataType(eRight, dt); } } else if (binExp.Operator == Operator.ISub || binExp.Operator == Operator.USub) { var dt = PushMinuendDataType(binExp.TypeVariable !.DataType, eRight.TypeVariable !.DataType); MeetDataType(eLeft, dt); dt = PushSubtrahendDataType(binExp.TypeVariable !.DataType, eLeft.TypeVariable !.DataType); MeetDataType(eRight, dt); } else if (binExp.Operator == Operator.And || binExp.Operator == Operator.Or) { //$REVIEW: need a push-logical-Data type to push [[a & 3]] = char into its left and right halves. var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character); MeetDataType(eLeft, dt); MeetDataType(eRight, dt); } else if ( binExp.Operator == Operator.IMul || binExp.Operator == Operator.IMod) { var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.Integer); MeetDataType(eLeft, dt); dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.Integer); MeetDataType(eRight, dt); } else if ( binExp.Operator == Operator.SMul || binExp.Operator == Operator.SDiv) { var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt); MeetDataType(eLeft, dt); dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt); MeetDataType(eRight, dt); } else if ( binExp.Operator == Operator.UMul || binExp.Operator == Operator.UDiv) { var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt); MeetDataType(eLeft, dt); dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt); MeetDataType(eRight, dt); } else if (binExp.Operator == Operator.FAdd || binExp.Operator == Operator.FSub || binExp.Operator == Operator.FMul || binExp.Operator == Operator.FDiv) { var dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize); MeetDataType(eLeft, dt); dt = PrimitiveType.Create(Domain.Real, eRight.DataType.BitSize); MeetDataType(eRight, dt); } else if (binExp.Operator is SignedIntOperator) { var dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.SignedInt | Domain.Character); MeetDataType(eLeft, dt); dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.SignedInt | Domain.Character); MeetDataType(eRight, dt); } else if (binExp.Operator is UnsignedIntOperator) { var dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.Pointer | Domain.UnsignedInt | Domain.Character); MeetDataType(eLeft, dt); dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.Pointer | Domain.UnsignedInt | Domain.Character); MeetDataType(eRight, dt); } else if (binExp.Operator == Operator.Eq || binExp.Operator == Operator.Ne || binExp.Operator == Operator.Xor || binExp.Operator == Operator.Cand || binExp.Operator == Operator.Cor) { // Not much can be deduced here, except that the operands should have the same size. Earlier passes // already did that work, so just continue with the operands. } else if (binExp.Operator is RealConditionalOperator) { // We know leaves must be floats var dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize); MeetDataType(eLeft, dt); dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize); MeetDataType(eRight, dt); } else if (binExp.Operator == Operator.Shl) { var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character); MeetDataType(eLeft, dt); dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize); } else if (binExp.Operator == Operator.Shr) { var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt | Domain.Character); MeetDataType(eLeft, dt); dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize); } else if (binExp.Operator == Operator.Sar) { var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt | Domain.Character); MeetDataType(eLeft, dt); dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize); } else { throw new TypeInferenceException($"Unhandled binary operator {binExp.Operator} in expression {binExp}."); } eLeft.Accept(this, eLeft.TypeVariable !); eRight.Accept(this, eRight.TypeVariable !); return(false); }
private DataType UInteger(int bitSize) { return(PrimitiveType.Create(Domain.UnsignedInt, bitSize)); }
/* * We need to handle the case when seeing * 1) ptr(mem(a)) = ptr(mem(a)) + C and * 2) ptr(mem(a)) = ptr(mem(b)) + C expressions. * In the first instance, we may be seeing the increment of an array pointer, where the stride is C. However * if mem(a) has a size > C, then this is actually an expression of the type: * a = &a->fC, where C is the offset of the field fC. This is equivalent to case 2. * * If we see t = x and later t = x + 4, then * [[t]] = [[x]] and [[t]] = [[x + 4]]. If [[t]] is a ptr(mem(Q)), * then we have a problem! * * This analysis is probably best done after TraitCollection, since by then we have discovered max sizes of mems. */ public DataType VisitBinaryExpression(BinaryExpression binExp) { binExp.Left.Accept(this); var ivLeft = ivCur; binExp.Right.Accept(this); var ivRight = ivCur; ivCur = null; if (ivLeft != null) { if (binExp.Operator == Operator.SMul || binExp.Operator == Operator.UMul || binExp.Operator == Operator.IMul || binExp.Operator == Operator.Shl) { ivCur = MergeInductionVariableConstant(ivLeft, binExp.Operator, binExp.Right as Constant); } } TypeVariable tvExp = binExp.TypeVariable; //$BUGBUG: This needs to be redone because the domain of the operation is now in the OPERATOR, not the operands. if (binExp.Operator == Operator.IAdd || binExp.Operator == Operator.ISub || binExp.Operator == Operator.And || binExp.Operator == Operator.Or || binExp.Operator == Operator.Xor) { return(handler.DataTypeTrait(binExp, binExp.DataType)); } else if (binExp.Operator == Operator.SMul || binExp.Operator == Operator.SDiv) { handler.DataTypeTrait(binExp, MakeNonPointer(binExp.DataType)); var dt = handler.DataTypeTrait(binExp, binExp.DataType); handler.DataTypeTrait(binExp.Left, PrimitiveType.Create(DomainOf(binExp.DataType), binExp.Left.DataType.Size)); handler.DataTypeTrait(binExp.Right, PrimitiveType.Create(DomainOf(binExp.DataType), binExp.Right.DataType.Size)); return(dt); } else if (binExp.Operator == Operator.UMul || binExp.Operator == Operator.UDiv || binExp.Operator == Operator.Shr) { handler.DataTypeTrait(binExp, MakeNonPointer(binExp.DataType)); var dt = handler.DataTypeTrait(binExp, MakeUnsigned(binExp.DataType)); handler.DataTypeTrait(binExp.Left, MakeUnsigned(binExp.Left.DataType)); handler.DataTypeTrait(binExp.Right, MakeUnsigned(binExp.Right.DataType)); return(dt); } else if (binExp.Operator == Operator.IMul) { handler.DataTypeTrait(binExp.Left, MakeIntegral(binExp.Left.DataType)); handler.DataTypeTrait(binExp.Right, MakeIntegral(binExp.Right.DataType)); return(handler.DataTypeTrait(binExp, MakeIntegral(binExp.DataType))); } else if (binExp.Operator == Operator.Sar) { var dt = handler.DataTypeTrait(binExp, MakeSigned(binExp.DataType)); handler.DataTypeTrait(binExp.Left, MakeSigned(binExp.Left.DataType)); handler.DataTypeTrait(binExp.Right, MakeUnsigned(binExp.Right.DataType)); return(dt); } else if (binExp.Operator == Operator.Shl) { return(handler.DataTypeTrait(binExp, MakeIntegral(binExp.DataType))); } else if (binExp.Operator == Operator.IMod) { var dt = handler.DataTypeTrait(binExp, binExp.DataType); handler.DataTypeTrait(binExp.Left, binExp.Left.DataType); handler.DataTypeTrait(binExp.Right, binExp.Right.DataType); return(dt); } else if (binExp.Operator == Operator.Eq || binExp.Operator == Operator.Ne) { handler.EqualTrait(binExp.Left, binExp.Right); return(handler.DataTypeTrait(binExp, PrimitiveType.Bool)); } else if (binExp.Operator == Operator.Ge || binExp.Operator == Operator.Gt || binExp.Operator == Operator.Le || binExp.Operator == Operator.Lt) { handler.EqualTrait(binExp.Left, binExp.Right); var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool); handler.DataTypeTrait(binExp.Left, MakeSigned(binExp.Left.DataType)); handler.DataTypeTrait(binExp.Right, MakeSigned(binExp.Right.DataType)); return(dt); } else if (binExp.Operator is RealConditionalOperator) { handler.EqualTrait(binExp.Left, binExp.Right); var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool); handler.DataTypeTrait(binExp.Left, PrimitiveType.Create(Domain.Real, binExp.Left.DataType.Size)); handler.DataTypeTrait(binExp.Right, PrimitiveType.Create(Domain.Real, binExp.Right.DataType.Size)); return(dt); } else if (binExp.Operator == Operator.Uge || binExp.Operator == Operator.Ugt || binExp.Operator == Operator.Ule || binExp.Operator == Operator.Ult) { handler.EqualTrait(binExp.Left, binExp.Right); var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool); handler.DataTypeTrait(binExp.Left, MakeNotSigned(binExp.Left.DataType)); handler.DataTypeTrait(binExp.Right, MakeNotSigned(binExp.Right.DataType)); return(dt); } else if (binExp.Operator == Operator.FAdd || binExp.Operator == Operator.FSub || binExp.Operator == Operator.FMul || binExp.Operator == Operator.FDiv) { var dt = PrimitiveType.Create(Domain.Real, binExp.DataType.Size); handler.DataTypeTrait(binExp, dt); handler.DataTypeTrait(binExp.Left, dt); handler.DataTypeTrait(binExp.Right, dt); return(dt); } throw new NotImplementedException("NYI: " + binExp.Operator + " in " + binExp); }
// 1. a_2 = a_1 >> 1 // 2. C_2 = cond(a_2) // 3. b_2 = b_1 rorc 1, C // 4. flags_3 = cond(b_2) // 1. tmp_1 = a_1 // 3. tmp_2 = b_2 // *. tmp_3 = (tmp1:tmp2) >> 1 // 1'. a_2 = slice(tmp3,16) // 2'. b_2 = (cast) tmp3 // 4. flags_3 = cond(b_2) private Instruction TransformRorC(Application rorc, Assignment a) { var sidOrigLo = ssaIds[a.Dst]; var sidCarry = ssaIds[(Identifier)rorc.Arguments[2]]; var cond = sidCarry.DefExpression as ConditionOf; if (cond == null) { return(a); } var condId = cond.Expression as Identifier; if (condId == null) { return(a); } var sidOrigHi = ssaIds[condId]; if (!(sidOrigHi.DefExpression is BinaryExpression shift && shift.Operator == Operator.Shr)) { return(a); } var block = sidOrigLo.DefStatement.Block; var sidShift = sidOrigHi.DefStatement; var expShrSrc = shift.Left; var expRorSrc = rorc.Arguments[0]; var stmGrf = sidGrf.DefStatement; block.Statements.Remove(stmGrf); var tmpHi = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType); var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, expShrSrc, false); sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, expShrSrc); var tmpLo = ssa.Procedure.Frame.CreateTemporary(rorc.Arguments[0].DataType); var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, rorc.Arguments[0], false); sidOrigLo.DefStatement.Instruction = new Assignment(sidTmpLo.Identifier, rorc.Arguments[0]); var iRorc = block.Statements.IndexOf(sidOrigLo.DefStatement); var dt = PrimitiveType.Create(Domain.UnsignedInt, expShrSrc.DataType.Size + expRorSrc.DataType.Size); var tmp = ssa.Procedure.Frame.CreateTemporary(dt); var expMkLongword = m.Shr(m.Seq(sidTmpHi.Identifier, sidTmpLo.Identifier), 1); var sidTmp = ssaIds.Add(tmp, sidGrf.DefStatement, expMkLongword, false); var stmTmp = block.Statements.Insert(iRorc + 1, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidTmp.Identifier, expMkLongword)); sidTmp.DefStatement = stmTmp; sidTmpHi.Uses.Add(stmTmp); sidTmpLo.Uses.Add(stmTmp); ssa.RemoveUses(sidCarry.DefStatement); block.Statements.Remove(sidCarry.DefStatement); ssaIds.Remove(sidCarry); var expNewHi = m.Slice( PrimitiveType.CreateWord(tmpHi.DataType.Size), sidTmp.Identifier, tmpLo.DataType.BitSize); var stmNewHi = block.Statements.Insert( iRorc + 2, sidOrigHi.DefStatement.LinearAddress, new Assignment(sidOrigHi.Identifier, expNewHi)); sidTmp.Uses.Add(stmNewHi); sidOrigHi.DefStatement = stmNewHi; sidOrigHi.DefExpression = expNewHi; var expNewLo = m.Cast( PrimitiveType.CreateWord(tmpLo.DataType.Size), sidTmp.Identifier); var stmNewLo = block.Statements.Insert( iRorc + 3, sidOrigLo.DefStatement.LinearAddress, new Assignment(sidOrigLo.Identifier, expNewLo)); sidTmp.Uses.Add(stmNewLo); sidOrigLo.DefStatement = stmNewLo; sidOrigLo.DefStatement = stmNewLo; sidGrf.DefExpression = m.Cond(sidTmp.Identifier); sidGrf.DefStatement.Instruction = new Assignment( sidGrf.Identifier, sidGrf.DefExpression); sidTmp.Uses.Add(sidGrf.DefStatement); return(sidOrigLo.DefStatement.Instruction); }
private void RewriteMovsx() { m.Assign( SrcOp(instrCur.op1), m.Cast(PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size), SrcOp(instrCur.op2))); }
protected virtual DataType MakeDataType(PrintfSize size, char cDomain) { Domain domain = Domain.None; int byteSize = this.wordSize; switch (cDomain) { case 'c': case 's': return(program.TypeFactory.CreatePointer( size == PrintfSize.Long ? PrimitiveType.WChar : PrimitiveType.Char, pointerSize)); case 'o': case 'u': case 'x': switch (size) { case PrintfSize.HalfHalf: byteSize = 1; break; case PrintfSize.Half: byteSize = 2; break; case PrintfSize.Long: byteSize = this.longSize; break; case PrintfSize.LongLong: byteSize = 8; break; case PrintfSize.I32: byteSize = 4; break; case PrintfSize.I64: byteSize = 8; break; } domain = Domain.UnsignedInt; break; case 'd': case 'i': switch (size) { case PrintfSize.HalfHalf: byteSize = 1; break; case PrintfSize.Half: byteSize = 2; break; case PrintfSize.Long: byteSize = this.longSize; break; case PrintfSize.LongLong: byteSize = 8; break; case PrintfSize.I32: byteSize = 4; break; case PrintfSize.I64: byteSize = 8; break; } domain = Domain.SignedInt; break; case 'a': case 'e': case 'f': case 'g': byteSize = this.doubleSize; domain = Domain.Real; break; case 'p': byteSize = this.pointerSize; domain = Domain.Pointer; break; default: var el = this.services.RequireService <DecompilerEventListener>(); el.Warn( el.CreateAddressNavigator(program, addr), "The format specifier '%{0}' passed to *scanf is not known.", cDomain); return(new UnknownType()); } return(program.TypeFactory.CreatePointer( PrimitiveType.Create(domain, byteSize), pointerSize)); }
private static PrimitiveType MakeInteger(Domain domain, DataType dt) { return(PrimitiveType.Create(domain, dt.BitSize)); }
/// <summary> /// Creates a constant signed integer whose bit size is the same /// as <paramref name="dt"/>'s bit size. /// </summary> /// <param name="dt">Data type whose bit size is used to build /// the constant.</param> /// <param name="l">Constant value.</param> public static Constant Int(DataType dt, long l) { var dtInt = PrimitiveType.Create(Domain.SignedInt, dt.BitSize); return(Create(dtInt, l)); }
private DataType MakeDataType(PrintfSize size, char cDomain) { Domain domain = Domain.None; int byteSize = this.wordSize; switch (cDomain) { case 'c': if (wideChars) { return(PrimitiveType.WChar); } else { return(PrimitiveType.Char); } case 'C': if (wideChars) { return(PrimitiveType.Char); } else { return(PrimitiveType.WChar); } case 'o': case 'u': case 'x': case 'X': switch (size) { case PrintfSize.HalfHalf: byteSize = 1; break; case PrintfSize.Half: byteSize = 2; break; case PrintfSize.Long: byteSize = this.longSize; break; case PrintfSize.LongLong: byteSize = 8; break; case PrintfSize.I32: byteSize = 4; break; case PrintfSize.I64: byteSize = 8; break; } domain = Domain.UnsignedInt; break; case 'd': case 'i': switch (size) { case PrintfSize.HalfHalf: byteSize = 1; break; case PrintfSize.Half: byteSize = 2; break; case PrintfSize.Long: byteSize = this.longSize; break; case PrintfSize.LongLong: byteSize = 8; break; case PrintfSize.I32: byteSize = 4; break; case PrintfSize.I64: byteSize = 8; break; } domain = Domain.SignedInt; break; case 'a': case 'A': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': domain = Domain.Real; break; case 'p': byteSize = this.pointerSize; domain = Domain.Pointer; break; } return(PrimitiveType.Create(domain, byteSize)); }
private static PrimitiveType MakeReal(DataType dt) { return(PrimitiveType.Create(Domain.Real, dt.BitSize)); }
public static AddressOperand Create(Address addr) { return(new AddressOperand( addr, PrimitiveType.Create(Domain.Pointer, addr.DataType.BitSize))); }
static MilStd1750Architecture() { Real48 = PrimitiveType.Create(Domain.Real, 48); }
private void RewriteFloat() { var src = SrcOp(instr.Operands[0]); var dst = DstOp(instr.Operands[1], src, (a, b) => m.Cast(PrimitiveType.Create(Domain.Real, a.DataType.BitSize), b)); }
public void Hybrid32() { Assert.AreEqual("uip32", PrimitiveType.Create(Domain.SignedInt | Domain.UnsignedInt | Domain.Pointer, 32).ToString()); }
public void CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate) { var totalSize = PrimitiveType.Create( Domain.SignedInt | Domain.UnsignedInt, loCandidate.Dst !.DataType.BitSize + hiCandidate.Dst !.DataType.BitSize); var left = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize); var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize); this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize); var stmts = hiCandidate.Statement !.Block.Statements; var linAddr = hiCandidate.Statement.LinearAddress; var iStm = FindInsertPosition(loCandidate, hiCandidate, stmts); Statement?stmMkLeft = null; if (left is Identifier) { stmMkLeft = stmts.Insert( iStm++, linAddr, CreateMkSeq(left, hiCandidate.Left, loCandidate.Left)); left = ReplaceDstWithSsaIdentifier(left, null !, stmMkLeft); } Statement?stmMkRight = null; if (right is Identifier) { stmMkRight = stmts.Insert( iStm++, linAddr, CreateMkSeq(right, hiCandidate.Right, loCandidate.Right)); right = ReplaceDstWithSsaIdentifier(right, null !, stmMkRight); } var expSum = new BinaryExpression(loCandidate.Op, left.DataType, left, right); Instruction instr = Assign(dst, expSum); var stmLong = stmts.Insert(iStm++, linAddr, instr); this.dst = ReplaceDstWithSsaIdentifier(this.dst, expSum, stmLong); var sidDst = GetSsaIdentifierOf(dst); var sidLeft = GetSsaIdentifierOf(left); var sidRight = GetSsaIdentifierOf(right); if (stmMkLeft != null && sidLeft != null) { GetSsaIdentifierOf(loCandidate.Left)?.Uses.Add(stmMkLeft); GetSsaIdentifierOf(hiCandidate.Left)?.Uses.Add(stmMkLeft); } if (stmMkRight != null && sidRight != null) { GetSsaIdentifierOf(loCandidate.Right)?.Uses.Add(stmMkRight); GetSsaIdentifierOf(hiCandidate.Right)?.Uses.Add(stmMkRight); } if (sidDst != null) { if (sidLeft != null) { sidLeft.Uses.Add(stmLong); } if (sidRight != null) { sidRight.Uses.Add(stmLong); } } var sidDstLo = GetSsaIdentifierOf(loCandidate.Dst); if (sidDstLo != null) { var cast = new Slice(loCandidate.Dst.DataType, dst, 0); var stmCastLo = stmts.Insert(iStm++, linAddr, new AliasAssignment( sidDstLo.Identifier, cast)); var stmDeadLo = sidDstLo.DefStatement; sidDstLo.DefExpression = cast; sidDstLo.DefStatement = stmCastLo; var sidDstHi = GetSsaIdentifierOf(hiCandidate.Dst); var slice = new Slice(hiCandidate.Dst.DataType, dst, loCandidate.Dst.DataType.BitSize); var stmSliceHi = stmts.Insert(iStm++, linAddr, new AliasAssignment( sidDstHi !.Identifier, slice)); var stmDeadHi = sidDstHi.DefStatement; sidDstHi.DefExpression = slice; sidDstHi.DefStatement = stmSliceHi; if (sidDstLo != null) { sidDst !.Uses.Add(stmCastLo); } if (sidDstHi != null) { sidDst !.Uses.Add(stmSliceHi); } ssa.DeleteStatement(stmDeadLo !); ssa.DeleteStatement(stmDeadHi !); } }
private void RewriteMultiply(BinaryOperator op, Domain resultDomain) { Expression product; switch (instrCur.Operands) { case 1: Identifier multiplicator; switch (instrCur.op1.Width.Size) { case 1: multiplicator = orw.AluRegister(Registers.al); product = orw.AluRegister(Registers.ax); break; case 2: multiplicator = orw.AluRegister(Registers.ax); product = binder.EnsureSequence( Registers.dx, multiplicator.Storage, PrimitiveType.Word32); break; case 4: multiplicator = orw.AluRegister(Registers.eax); product = binder.EnsureSequence( Registers.edx, multiplicator.Storage, PrimitiveType.Word64); break; case 8: multiplicator = orw.AluRegister(Registers.rax); product = binder.EnsureSequence( Registers.rdx, multiplicator.Storage, PrimitiveType.Word64); break; default: throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width)); } ; m.Assign( product, new BinaryExpression( op, PrimitiveType.Create(resultDomain, product.DataType.Size), SrcOp(instrCur.op1), multiplicator)); EmitCcInstr(product, X86Instruction.DefCc(instrCur.code)); return; case 2: EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2), CopyFlags.EmitCc); return; case 3: EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3), CopyFlags.EmitCc); return; default: throw new ArgumentException("Invalid number of operands"); } }
public bool Match(Expression e) { elemSize = null; Index = null; ArrayPointer = null; BinaryExpression b = e as BinaryExpression; if (b == null) { return(false); } if (MatchMul(b)) { ArrayPointer = Constant.Zero(b.DataType); return(true); } // (+ x y) if (b.Operator == Operator.IAdd) { BinaryExpression bInner = b.Left as BinaryExpression; if (bInner != null) { if (MatchMul(bInner)) { // (+ (* i c) ptr) ArrayPointer = b.Right; return(true); } } bInner = b.Right as BinaryExpression; if (bInner != null) { if (MatchMul(bInner)) { // (+ ptr (* i c)) ArrayPointer = b.Left; return(true); } if (bInner.Operator == Operator.IAdd) { // (+ x (+ a b)) var bbInner = bInner.Left as BinaryExpression; if (bbInner != null && MatchMul(bbInner)) { // (+ x (+ (* i c) y)) rearranges to become // (+ (* i c) (+ x y)) this.ArrayPointer = new BinaryExpression( Operator.IAdd, PrimitiveType.Create(Domain.Pointer, b.Left.DataType.Size), b.Left, bInner.Right); return(true); } } } } return(false); }
private DataType Integer(int size) { return(PrimitiveType.Create(Domain.SignedInt, size)); }
public Expression SMul(Expression left, Expression right) { return(new BinaryExpression(Operator.SMul, PrimitiveType.Create(Domain.SignedInt, left.DataType.Size), left, right)); }
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); }
public Expression UMul(Expression left, int c) { return(new BinaryExpression(Operator.UMul, PrimitiveType.Create(Domain.UnsignedInt, left.DataType.Size), left, Constant.Create(left.DataType, c))); }
public UnaryExpression AddrOf(Expression expr) { return(new UnaryExpression(Operator.AddrOf, PrimitiveType.Create(Domain.Pointer, arch.WordWidth.Size), expr)); }
public DataType VisitAddress(Address addr) { return(RecordDataType( PrimitiveType.Create(Domain.Pointer, addr.DataType.Size), addr)); }
private DataType Parse(PrimitiveType charPrefix) { if (i >= str.Length) { return(new UnknownType()); } int bitSize; switch (str[i++]) { case 'a': return(ParseArray()); case 'b': return(PrimitiveType.Byte); case 'p': if (i + 2 <= str.Length && str[i] == 'f' && str[i + 1] == 'n') { i += 2; return(new Pointer(new CodeType(), 4)); } var pointee = Parse(PrimitiveType.Char); if (pointee is UnknownType) { return(PrimitiveType.Pointer32); //$ARch-dependent? } else { return(new Pointer(pointee, 4)); //$ARCH-dependent! } case 'i': bitSize = ParseBitSize(); if (bitSize == 0) { return(PrimitiveType.Int32); // Convenient for 2015... most ints are 32 in C code. } return(PrimitiveType.Create(Domain.SignedInt, bitSize / 8)); case 'u': bitSize = ParseBitSize(); if (bitSize == 0) { return(PrimitiveType.UInt32); //$REVIEW: arch word size? } return(PrimitiveType.Create(Domain.UnsignedInt, bitSize / 8)); case 'r': bitSize = ParseBitSize(); if (bitSize == 0) { return(new UnknownType()); } return(PrimitiveType.Create(Domain.Real, bitSize / 8)); case 'f': return(PrimitiveType.Bool); case 'c': if (i < str.Length && str[i] == 'h') { ++i; return(charPrefix); } return(new UnknownType()); case 's': if (i < str.Length) { switch (str[i++]) { case 'z': return(StringType.NullTerminated(charPrefix)); case 'i': return(ParseLengthPrefixString(charPrefix)); } --i; } return(new ArrayType(charPrefix, 0)); case 'w': if (i < str.Length) { var dt = Parse(PrimitiveType.WChar); if (dt is UnknownType) { dt = PrimitiveType.Word32; } return(dt); } return(PrimitiveType.Word32); case 'x': return(new CodeType()); } return(new UnknownType()); }
public DataType VisitBinaryExpression(BinaryExpression binExp) { DataType dtLeft = binExp.Left.Accept(this); DataType dtRight = binExp.Right.Accept(this); DataType dt; if (binExp.Operator == Operator.IAdd) { dt = GetPossibleFieldType(dtLeft, dtRight, binExp.Right); if (dt == null) { dt = PullSumDataType(dtLeft, dtRight); } } else if (binExp.Operator == Operator.ISub) { dt = PullDiffDataType(dtLeft, dtRight); } else if (binExp.Operator == Operator.And || binExp.Operator == Operator.Or) { dt = PrimitiveType.CreateWord(dtLeft.Size).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character); } else if ( binExp.Operator == Operator.IMul || binExp.Operator == Operator.Shl || binExp.Operator == Operator.IMod) { dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.Integer); } else if ( binExp.Operator == Operator.SMul || binExp.Operator == Operator.SDiv) { dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.SignedInt); } else if ( binExp.Operator == Operator.UMul || binExp.Operator == Operator.UDiv) { dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.UnsignedInt); } else if (binExp.Operator is ConditionalOperator) { dt = PrimitiveType.Bool; } else if ( binExp.Operator == Operator.FAdd || binExp.Operator == Operator.FSub || binExp.Operator == Operator.FMul || binExp.Operator == Operator.FDiv) { dt = PrimitiveType.Create(Domain.Real, dtLeft.Size); } else if (binExp.Operator == Operator.Shr) { dt = PrimitiveType.Create(Domain.UnsignedInt, dtLeft.Size); } else if (binExp.Operator == Operator.Sar) { dt = PrimitiveType.Create(Domain.SignedInt, dtLeft.Size); } else if (binExp.Operator == Operator.Xor || binExp.Operator == Operator.Shl) { dt = PrimitiveType.Create(Domain.Integer, dtLeft.Size); } else { throw NYI(binExp); } return(RecordDataType(dt, binExp)); }
/// <summary> /// Creates an instance of PowerPcArchitecture. /// </summary> /// <param name="wordWidth">Supplies the word width of the PowerPC architecture.</param> public PowerPcArchitecture(string archId, PrimitiveType wordWidth, PrimitiveType signedWord) : base(archId) { WordWidth = wordWidth; SignedWord = signedWord; PointerType = PrimitiveType.Create(Domain.Pointer, wordWidth.BitSize); FramePointerType = PointerType; InstructionBitSize = 32; this.lr = new RegisterStorage("lr", 0x48, 0, wordWidth); this.ctr = new RegisterStorage("ctr", 0x49, 0, wordWidth); this.xer = new RegisterStorage("xer", 0x4A, 0, wordWidth); this.fpscr = new RegisterStorage("fpscr", 0x4B, 0, wordWidth); this.cr = new RegisterStorage("cr", 0x4C, 0, wordWidth); this.acc = new RegisterStorage("acc", 0x4D, 0, PrimitiveType.Word64); // gp regs 0..1F // fpu regs 20..3F // CR regs 40..47 // vectors 80..FF fpregs = new ReadOnlyCollection <RegisterStorage>( Enumerable.Range(0, 0x20) .Select(n => new RegisterStorage("f" + n, n + 0x20, 0, PrimitiveType.Word64)) .ToList()); cregs = new ReadOnlyCollection <RegisterStorage>( Enumerable.Range(0, 8) .Select(n => new RegisterStorage("cr" + n, n + CcFieldMin, 0, PrimitiveType.Byte)) .ToList()); vregs = new ReadOnlyCollection <RegisterStorage>( Enumerable.Range(0, 128) // VMX128 extension has 128 regs .Select(n => new RegisterStorage("v" + n, n + 0x80, 0, PrimitiveType.Word128)) .ToList()); ccFlagGroups = Enumerable.Range(0, 8) .Select(n => new FlagGroupStorage(cr, 0xFu << (n * 4), $"cr{n}", PrimitiveType.Byte)) .ToDictionary(f => f.FlagGroupBits); ccFlagGroupsByName = ccFlagGroups.Values .ToDictionary(f => f.Name); regs = new ReadOnlyCollection <RegisterStorage>( Enumerable.Range(0, 0x20) .Select(n => new RegisterStorage("r" + n, n, 0, wordWidth)) .Concat(fpregs) .Concat(cregs) .Concat(new[] { lr, ctr, xer }) .Concat(vregs) .ToList()); spregs = new Dictionary <int, RegisterStorage> { { 26, new RegisterStorage("srr0", 0x0100 + 26, 0, PrimitiveType.Word32) }, { 27, new RegisterStorage("srr1", 0x0100 + 27, 0, PrimitiveType.Word32) }, }; //$REVIEW: using R1 as the stack register is a _convention_. It // should be platform-specific at the very least. StackRegister = regs[1]; Options = new Dictionary <string, object>(); }
public DataType VisitPrimitive(PrimitiveType_v1 primitive) { return(PrimitiveType.Create(primitive.Domain, primitive.ByteSize)); }
private DataType Real(int bitSize) { return(PrimitiveType.Create(Domain.Real, bitSize)); }
private void RewriteFistp() { instrCur.op1.Width = PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size); emitter.Assign(SrcOp(instrCur.op1), emitter.Cast(instrCur.op1.Width, orw.FpuRegister(0, state))); state.ShrinkFpuStack(1); }