示例#1
0
        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);
        }
示例#2
0
        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();
            }
        }
示例#3
0
        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);
        }
示例#4
0
 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;
 }
示例#5
0
 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
         }
     });
 }
示例#6
0
 // 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
         }
     });
 }
示例#7
0
 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);
     }
 }
示例#8
0
        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));
            }
        }
示例#9
0
        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);
        }
示例#10
0
 public List <Instruction> FetchToReg(RegVRef dest)
 {
     throw new NotImplementedException();
 }
示例#11
0
 public Push(RegVRef reg, PointerIndex stack = PointerIndex.CallStack)
 {
     this.reg   = reg;
     this.stack = stack;
 }
示例#12
0
        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);
        }
示例#13
0
 public static FieldSRef IntArg(string funcname, string intname)
 {
     return(new FieldSRef(RegVRef.rIntArgs(funcname), intname));
 }
示例#14
0
 public static FieldSRef LocalInt(string funcname, string intname)
 {
     return(new FieldSRef(RegVRef.rLocalInts(funcname), intname));
 }
示例#15
0
 public FieldSRef InRegister(RegVRef reg)
 {
     return(new FieldSRef(reg.AsType(varref.datatype), fieldname));
 }
示例#16
0
        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);
        }
示例#17
0
 public Exchange(RegVRef reg, PointerIndex frame = PointerIndex.CallStack) : this(reg, frame, IntSExpr.Zero)
 {
 }
示例#18
0
 public Exchange(RegVRef reg, PointerIndex frame, SExpr addr) : this(reg, reg, frame, addr)
 {
 }
示例#19
0
 public List <Instruction> FetchToReg(RegVRef dest)
 {
     return(BaseVRef().FetchToReg(dest));
 }
示例#20
0
 public List <Instruction> FetchToReg(RegVRef dest)
 {
     return(new Table(this.text).FetchToReg(dest));
 }
示例#21
0
 public List <Instruction> PutFromReg(RegVRef src)
 {
     return(BaseVRef().PutFromReg(src));
 }