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); }
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)); } }
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)); } }
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)); }
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)); }
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)); }
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."); }
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); } }
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()); }
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); }
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()); } }
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)); }
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."); }
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); } }
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); }
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, }; "); }
/// <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); })); }
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)); }
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)); }
/// <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); } }
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)); } }
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))); }
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))); }
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); }
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)); }
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)); }
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)); }
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)); }
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)")); }
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); }