public List <Instruction> FetchToReg(RegVRef dest) { var code = new List <Instruction>(); FieldSRef addr = this.addr.AsDirectField(); if (addr == null) { if (this.addr.IsConstant()) { addr = FieldSRef.Imm1(); } else { addr = FieldSRef.ScratchInt(); code.AddRange(this.addr.FetchToField(addr)); } } code.Add(new Instruction { opcode = Opcode.MemRead, op1 = addr, dest = dest, imm1 = this.addr.IsConstant() ? this.addr : null, idx = this.addr.frame(), }); return(code); }
public List <Instruction> FetchToReg(RegVRef dest) { //allocate as const if possible, and memread it if (this.IsConstant()) { var constname = "__const" + this.GetHashCode(); var constsym = new Symbol { type = SymbolType.Constant, name = constname, frame = PointerIndex.ProgConst, datatype = this.datatype, data = new List <Table> { this }, }; Program.CurrentProgram.Symbols.Add(constsym); return(new MemVRef(new AddrSExpr(constname), this.datatype).FetchToReg(dest)); } else { //TODO: compose non-const table in a block of code throw new NotImplementedException(); } }
public List <Instruction> PutFromReg(RegVRef src) { var code = new List <Instruction>(); FieldSRef addr = this.addr as FieldSRef; if (addr == null) { if (this.addr.IsConstant()) { addr = FieldSRef.Imm1(); } else { addr = FieldSRef.ScratchInt(); code.AddRange(this.addr.FetchToField(addr)); } } code.Add(new Instruction { opcode = Opcode.MemWrite, op1 = addr, op2 = src, imm1 = this.addr.IsConstant() ? this.addr : null, }); return(code); }
public Exchange(RegVRef source, RegVRef dest, PointerIndex frame, SExpr addr) { if (addr.AsDirectField() == null && !addr.IsConstant()) { throw new ArgumentException("must be register field or constant", "addr"); } this.source = source; this.dest = dest; this.frame = frame; this.addr = addr; }
public List <Instruction> PutFromReg(RegVRef src) { if (src == this) { return(new List <Instruction>()); } return(new List <Instruction> { new Instruction { opcode = Opcode.EachAddV, op1 = src, dest = this } }); }
// this would only be used to copy a reg? public List <Instruction> FetchToReg(RegVRef dest) { if (dest == this) { return(new List <Instruction>()); } return(new List <Instruction> { new Instruction { opcode = Opcode.EachAddV, op1 = this, dest = dest } }); }
public List <Instruction> FetchToReg(RegVRef dest) { if (Program.CurrentProgram.VBuiltins.ContainsKey(this.name)) { return(Program.CurrentProgram.VBuiltins[this.name](this, dest)); } else { var code = CodeGen(); code.AddRange(new VAssign { source = RegVRef.rVarArgs, target = dest }.CodeGen()); return(code); } }
public List <Instruction> FetchToReg(RegVRef dest) { Symbol varsym = new Symbol(); if (Program.CurrentFunction != null) { varsym = Program.CurrentFunction.locals.FirstOrDefault(sym => sym.name == this.arrname); } if (varsym.name == null) { varsym = Program.CurrentProgram.Symbols.FirstOrDefault(sym => sym.name == this.arrname); } if (offset.IsConstant()) { return(new MemVRef(new AddrSExpr(arrname, offset.Evaluate()), varsym.datatype).FetchToReg(dest)); } else { return(new MemVRef(new ArithSExpr(new AddrSExpr(arrname), ArithSpec.Add, offset), varsym.datatype).FetchToReg(dest)); } }
public List <Instruction> FetchToReg(RegVRef dest) { var code = new List <Instruction>(); var cmd = Command.AsReg(); if (cmd == null) { cmd = RegVRef.rScratchTab; code.AddRange(Command.FetchToReg(cmd)); } var data = Data.AsReg(); if (data == null) { data = cmd == RegVRef.rScratchTab ? RegVRef.rScratchInts : RegVRef.rScratchTab; if (data == RegVRef.rScratchInts) { FieldSRef.ResetScratchInts(); } code.AddRange(Data.FetchToReg(data)); } code.Add(new Instruction { opcode = Opcode.ConMan, op1 = cmd, op2 = data, dest = dest, }); if (data == RegVRef.rScratchInts) { code.AddRange(data.PutFromReg(RegVRef.rNull)); } return(code); }
public List <Instruction> FetchToReg(RegVRef dest) { throw new NotImplementedException(); }
public Push(RegVRef reg, PointerIndex stack = PointerIndex.CallStack) { this.reg = reg; this.stack = stack; }
public List <Instruction> FetchToReg(RegVRef dest) { var code = new List <Instruction>(); RegVRef other; if (dest == V1.AsReg()) { other = V2.AsReg(); if (other == null) { other = RegVRef.rScratchTab; code.AddRange(V2.FetchToReg(other)); } } else if (dest == V2.AsReg()) { other = V1.AsReg(); if (other == null) { other = RegVRef.rScratchTab; code.AddRange(V1.FetchToReg(other)); } } else { code.AddRange(V1.FetchToReg(dest)); other = V2.AsReg(); if (other == null) { other = RegVRef.rScratchTab; code.AddRange(V2.FetchToReg(other)); } } switch (Op) { case ArithSpec.Add: code.Add(new Instruction { opcode = Opcode.EachAddV, acc = true, op1 = other, dest = dest }); break; case ArithSpec.Subtract: code.Add(new Instruction { opcode = Opcode.EachMulV, acc = true, op1 = other, op2 = FieldSRef.Imm2(), imm2 = new IntSExpr(-1), dest = dest }); break; case ArithSpec.Multiply: code.Add(new Instruction { opcode = Opcode.VMul, op1 = dest, op2 = other, dest = dest }); break; case ArithSpec.Divide: code.Add(new Instruction { opcode = Opcode.VDiv, op1 = dest, op2 = other, dest = dest }); break; default: throw new NotImplementedException(); } return(code); }
public static FieldSRef IntArg(string funcname, string intname) { return(new FieldSRef(RegVRef.rIntArgs(funcname), intname)); }
public static FieldSRef LocalInt(string funcname, string intname) { return(new FieldSRef(RegVRef.rLocalInts(funcname), intname)); }
public FieldSRef InRegister(RegVRef reg) { return(new FieldSRef(reg.AsType(varref.datatype), fieldname)); }
public List <Instruction> BuildFunction() { var b = new List <Instruction>(); // save call site (in r8.signal-0) b.Add(new Push(RegVRef.rScratchInts)); if (localints.Count > 0) { // save parent localints b.Add(new Push(RegVRef.rLocalInts("parent"))); } // push regs as needed foreach (var sym in locals.Where(s => s.type == SymbolType.Register)) { if (sym.fixedAddr.HasValue) { b.Add(new Push(new RegVRef(sym.fixedAddr.Value))); } } // wind stack down for locals if needed if (framesize > 0) { b.Add(new Instruction { opcode = Opcode.Add, op1 = FieldSRef.Imm1(), imm1 = new IntSExpr(-framesize), acc = true, dest = FieldSRef.Pointer(PointerIndex.CallStack) }); } // copy params if named //int args or null in r8 var intparas = locals.Where(sym => sym.type == SymbolType.Parameter && sym.datatype == "int").ToList(); if (intparas.Count() > 0) { for (int i = 0; i < intparas.Count(); i++) { b.Add(new Instruction { opcode = Opcode.Add, op1 = FieldSRef.IntArg(name, intparas[i].name), dest = FieldSRef.LocalInt(name, intparas[i].name), acc = i != 0, }); } } FieldSRef.ResetScratchInts(); b.AddRange(RegVRef.rScratchInts.PutFromReg(RegVRef.rNull)); // body b.AddRange(body.CodeGen()); // convert rjmp __return => rjmp <integer> to here. for (int i = 0; i < b.Count; i++) { var inst = b[i]; if ((inst.imm1 as AddrSExpr)?.symbol == "__return") { inst.imm1 = new IntSExpr(b.Count - i); } if ((inst.imm2 as AddrSExpr)?.symbol == "__return") { inst.imm2 = new IntSExpr(b.Count - i); } b[i] = inst; } // wind stack back up for locals if needed if (framesize > 0) { b.Add(new Instruction { opcode = Opcode.Add, op1 = FieldSRef.Imm1(), imm1 = new IntSExpr(framesize), acc = true, dest = FieldSRef.Pointer(PointerIndex.CallStack) }); } // restore registers foreach (var sym in locals.Where(s => s.type == SymbolType.Register).Reverse()) { if (sym.fixedAddr.HasValue) { b.Add(new Pop(new RegVRef(sym.fixedAddr.Value))); } } if (localints.Count > 0) { // restore parent localints b.Add(new Pop(RegVRef.rLocalInts("parent"))); } // get return site b.Add(new Exchange(RegVRef.rScratchTab)); b.Add(new Instruction { opcode = Opcode.Sub, op1 = FieldSRef.VarField(RegVRef.rScratchTab, "signal-0"), op2 = FieldSRef.CallSite, dest = FieldSRef.CallSite, acc = true }); b.Add(new Pop(RegVRef.rScratchTab)); // jump to return site b.Add(new Jump { target = FieldSRef.CallSite }); return(b); }
public Exchange(RegVRef reg, PointerIndex frame = PointerIndex.CallStack) : this(reg, frame, IntSExpr.Zero) { }
public Exchange(RegVRef reg, PointerIndex frame, SExpr addr) : this(reg, reg, frame, addr) { }
public List <Instruction> FetchToReg(RegVRef dest) { return(BaseVRef().FetchToReg(dest)); }
public List <Instruction> FetchToReg(RegVRef dest) { return(new Table(this.text).FetchToReg(dest)); }
public List <Instruction> PutFromReg(RegVRef src) { return(BaseVRef().PutFromReg(src)); }