public Identifier VisitSequenceStorage(SequenceStorage seq) { var dt = this.dt !; var clones = seq.Elements.Select(e => e.Accept(this).Storage); return(procCalling.Frame.EnsureSequence(dt, clones.ToArray())); }
public Identifier VisitSequenceStorage(SequenceStorage seq) { var idSeq = id; var newElems = seq.Elements.Select(e => e.Accept(this).Storage); return(frame.EnsureSequence(idSeq.DataType, newElems.ToArray())); }
public void MspRealModeServices() { IntelArchitecture arch = new IntelArchitecture(ProcessorMode.Real); Platform platform = new MsdosPlatform(null, arch); var state = arch.CreateProcessorState(); state.SetRegister(Registers.ah, Constant.Byte(0x3E)); SystemService svc = platform.FindService(0x21, state); Assert.AreEqual("msdos_close_file", svc.Name); Assert.AreEqual(1, svc.Signature.Parameters.Length); Assert.IsFalse(svc.Characteristics.Terminates, "close() shouldn't terminate program"); state.SetRegister(Registers.ah, Constant.Byte(0x4C)); svc = platform.FindService(0x21, state); Assert.AreEqual("msdos_terminate", svc.Name); Assert.AreEqual(1, svc.Signature.Parameters.Length); Assert.IsTrue(svc.Characteristics.Terminates, "terminate() should terminate program"); state.SetRegister(Registers.ah, Constant.Byte(0x2F)); svc = platform.FindService(0x21, state); Assert.AreEqual("msdos_get_disk_transfer_area_address", svc.Name); Assert.AreEqual(0, svc.Signature.Parameters.Length); SequenceStorage seq = (SequenceStorage)svc.Signature.ReturnValue.Storage; Assert.AreEqual("es", seq.Head.Name); Assert.AreEqual("bx", seq.Tail.Name); }
public void UrfXXX() { var sExp = "Used: [0..31]"; var regDx = new RegisterStorage("dx", 2, 0, PrimitiveType.Word16); var regAx = new RegisterStorage("ax", 0, 0, PrimitiveType.Word16); var seqDxAx = new SequenceStorage(regDx, regAx); RunClassifyTest( sExp, "dx_ax", m => { var ax = m.Reg("dx", regAx); var dx = m.Reg("ax", regDx); var dx_ax = m.SeqId("dx_ax", PrimitiveType.Word32, regDx, regAx); m.Assign(dx_ax, m.Mem32(m.Word32(0x00123400))); m.Alias(ax, m.Slice(ax.DataType, dx_ax, 0)); m.Alias(dx, m.Slice(ax.DataType, dx_ax, 16)); m.AddUseToExitBlock(ax); m.AddUseToExitBlock(dx); }, p => { var flow = new ProcedureFlow(p); flow.BitsLiveOut.Add(seqDxAx, new BitRange(0, 32)); return(flow); }); }
public Identifier VisitSequenceStorage(SequenceStorage seq) { var dt = this.dt; var hd = (Identifier)seq.Head.Accept(this); var tl = (Identifier)seq.Tail.Accept(this); return(procCalling.Frame.EnsureSequence(hd.Storage, tl.Storage, dt)); }
public Identifier VisitSequenceStorage(SequenceStorage seq) { var idSeq = id; var newHead = seq.Head.Accept(this); var newTail = seq.Tail.Accept(this); return(frame.EnsureSequence(newHead.Storage, newTail.Storage, idSeq.DataType)); }
public bool VisitSequenceStorage(SequenceStorage seq, bool defining) { foreach (var e in seq.Elements) { e.Accept(this, defining); } return(true); }
public Identifier VisitSequenceStorage(SequenceStorage seq) { var idSeq = id; var newHead = (Identifier)VisitIdentifier(seq.Head); var newTail = (Identifier)VisitIdentifier(seq.Tail); return(frame.EnsureSequence(newHead, newTail, idSeq.DataType)); }
public bool VisitSequenceStorage(SequenceStorage seq) { var f = seq.Head.Storage.Accept(this); if (!f) { f = seq.Tail.Storage.Accept(this); } return(f); }
public Expression VisitSequenceStorage(SequenceStorage seq) { if (map.TryGetValue(seq, out var binding)) { return(binding.Expression); } var exps = seq.Elements .Select(stg => stg.Accept(this)) .ToArray(); return(new MkSequence(seq.DataType, exps)); }
public Storage VisitSequenceStorage(SequenceStorage seq) { seq.Head.Accept(this); seq.Tail.Accept(this); if (defining) { regDefs[seq] = value; } else { value = regDefs[seq]; } return(seq); }
/// <summary> /// Inserts an alias statement. /// </summary> /// <param name="v">Variable that has been defined</param> /// <param name="vAlias">Other variable that is aliased by v</param> /// <param name="iAt"></param> // If a wide register is being defined by aliasing of a smaller // register, the expression needs to take into account the previous // value of the wide register. For instance, modifying cl aliases // cx = f(cl, cx) // thus: // mov cl,xx // mov cx,DPB(cx,cl,0,8) public Assignment CreateAliasInstruction(Identifier varFrom, Identifier varTo) // Identifier v, Identifier vAlias) { if (!IsAlias(arch, varFrom, varTo)) { throw new ApplicationException(string.Format("Unexpected alias pair {0} and {1}", varTo.Name, varFrom.Name)); } Expression aliasExpr; int offsetTo = varTo.Storage.OffsetOf(varFrom.Storage); int offsetFrom = varFrom.Storage.OffsetOf(varTo.Storage); int cbitsFrom = varFrom.DataType.BitSize; int cbitsTo = varTo.DataType.BitSize; if (cbitsFrom < cbitsTo) { // We are replacing a part of a wider register with a narrower one. SequenceStorage seq = varTo.Storage as SequenceStorage; if (seq != null && (seq.Head == varFrom.Storage || seq.Tail == varFrom.Storage)) { aliasExpr = new MkSequence( varTo.DataType, proc.Frame.EnsureIdentifier(seq.Head), proc.Frame.EnsureIdentifier(seq.Tail)); } else { aliasExpr = new DepositBits(varTo, varFrom, offsetTo); } } else if (cbitsFrom > cbitsTo) { if (offsetFrom == 0) { aliasExpr = new Cast(varTo.DataType, varFrom); } else { aliasExpr = new Slice(varTo.DataType, varFrom, offsetFrom); } } else { aliasExpr = varFrom; } return(new AliasAssignment(varTo, aliasExpr)); }
public Storage VisitSequenceStorage(SequenceStorage seq) { seq.Head.Accept(this); seq.Tail.Accept(this); if (define) { defBitSize = (int)(seq.Head.BitSize + seq.Tail.BitSize); defOffset = 0; } else { //$NOTimplemented: what happens in cases like es_bx = AAAABBBB // but only es is live out? AAAA but not BBBB should be live then. } return(null); }
public void FrSequenceAccess() { var f = new Frame(PrimitiveType.Word16); Identifier ax = f.EnsureRegister(Registers.ax); Identifier dx = f.EnsureRegister(Registers.dx); Identifier dx_ax = f.EnsureSequence(PrimitiveType.Word32, dx.Storage, ax.Storage); SequenceStorage vDx_ax = (SequenceStorage)dx_ax.Storage; using (FileUnitTester fut = new FileUnitTester("Core/FrSequenceAccess.txt")) { f.Write(fut.TextWriter); fut.TextWriter.WriteLine("Head({0}) = {1}", dx_ax.Name, vDx_ax.Elements[0].Name); fut.TextWriter.WriteLine("Tail({0}) = {1}", dx_ax.Name, vDx_ax.Elements[1].Name); fut.AssertFilesEqual(); } }
public void TrashVariable(Storage id) { if (id == null) { return; } var reg = id as RegisterStorage; if (reg != null) { state.SetValue(reg, Constant.Invalid); } SequenceStorage seq = id as SequenceStorage; if (seq != null) { TrashVariable(seq.Head); TrashVariable(seq.Tail); } }
private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr) { int size = dtRet.Size; if ((size & 1) != 0) // odd sized register occupies two regs { // Round size to even # of bytes. size = dtRet.Size + 1; } var iReg = 26 - size; if (dtRet.Size <= 8) { var reg = argRegs[iReg - 8]; if (dtRet.Size == 1) { ccr.RegReturn(reg); return; } SequenceStorage seq = null; for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r) { var regNext = argRegs[r - 8]; if (seq != null) { seq = new SequenceStorage(regNext, seq, PrimitiveType.Word32); } else { seq = new SequenceStorage(regNext, reg, PrimitiveType.Word32); } } ccr.SequenceReturn(seq); } else { throw new NotImplementedException("Large AVR8 return values not implemented yet."); } }
private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr) { int size = dtRet.Size; if ((size & 1) != 0) // odd sized register occupies two regs { // Round size to even # of bytes. size = dtRet.Size + 1; } var iReg = 26 - size; if (dtRet.Size <= 8) { var reg = argRegs[iReg - 8]; if (dtRet.Size == 1) { ccr.RegReturn(reg); return; } var retRegs = new List <RegisterStorage> { reg }; for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r) { var regNext = argRegs[r - 8]; retRegs.Insert(0, regNext); } var seq = new SequenceStorage(retRegs.ToArray()); ccr.SequenceReturn(seq); } else { throw new NotImplementedException("Large AVR8 return values not implemented yet."); } }
public SerializedSequence(SequenceStorage seq) { Registers = seq.Elements .Select(e => new Register_v1(e.Name)) .ToArray(); }
public Storage VisitSequenceStorage(SequenceStorage seq) { ctx.RegisterState[seq] = value; return(seq); }
public SerializedSequence(SequenceStorage seq) { Registers = new Register_v1[2]; Registers[0] = new Register_v1(seq.Head.Name); Registers[1] = new Register_v1(seq.Tail.Name); }
public bool VisitSequenceStorage(SequenceStorage seq, bool defining) { seq.Head.Accept(this, defining); seq.Tail.Accept(this, defining); return(true); }
public Identifier VisitSequenceStorage(SequenceStorage seq) { return(frame.EnsureSequence(id.DataType, seq.Elements)); }
public SequenceOperand(SequenceStorage seq) : base((PrimitiveType)seq.DataType) { this.Sequence = seq; }
public static Identifier Create(SequenceStorage seq) { return(new Identifier(seq.Name, seq.DataType, seq)); }
public Storage VisitSequenceStorage(SequenceStorage seq) { return(null); }
public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams) { /* * To find the register where a function argument is passed, initialize the register number * Rn with R26 and follow this procedure: * * If the argument size is an odd number of bytes, round up the size to the next even number. * Subtract the rounded size from the register number Rn. * * If the new Rn is at least R8 and the size of the object is non-zero, then the low-byte of * the argument is passed in Rn. Subsequent bytes of the argument are passed in the subsequent * registers, i.e. in increasing register numbers. * * If the new register number Rn is smaller than R8 or the size of the argument is zero, the * argument will be passed in memory. * * If the current argument is passed in memory, stop the procedure: All subsequent arguments * will also be passed in memory. * If there are arguments left, goto 1. and proceed with the next argument. * * Return values with a size of 1 byte up to and including a size of 8 bytes will be returned * in registers. Return values whose size is outside that range will be returned in memory. * If a return value cannot be returned in registers, the caller will allocate stack space and * pass the address as implicit first pointer argument to the callee. The callee will put the * return value into the space provided by the caller. * * If the return value of a function is returned in registers, the same registers are used as * if the value was the first parameter of a non-varargs function. For example, an 8-bit value is returned in R24 and an 32-bit value is returned R22...R25. * Arguments of varargs functions are passed on the stack. This applies even to the named arguments. */ ccr.LowLevelDetails(1, 2); if (dtRet != null || dtRet == VoidType.Instance) { GenerateReturnValue(dtRet, ccr); } int iReg = 26; foreach (var dtParam in dtParams) { int size = dtParam.Size; if ((size & 1) != 0) // odd sized register occupies two regs { // Round size to even # of bytes. size = dtParam.Size + 1; } iReg -= size; if (iReg >= 8) { var reg = argRegs[iReg - 8]; if (dtParam.Size == 1) { ccr.RegParam(reg); continue; } SequenceStorage seq = null; for (int r = iReg + 1, i = 1; i < dtParam.Size; ++i, ++r) { var regNext = argRegs[r - 8]; if (seq != null) { seq = new SequenceStorage(regNext, seq, PrimitiveType.CreateWord(regNext.DataType.BitSize + seq.DataType.BitSize)); } else { seq = new SequenceStorage(regNext, reg, PrimitiveType.CreateWord(regNext.DataType.BitSize + reg.DataType.BitSize)); } } ccr.SequenceParam(seq); } else { ccr.StackParam(dtParam); } } }
public string VisitSequenceStorage(SequenceStorage seq) { return("seq"); }