Пример #1
0
        public List <Instruction> CodeGen(int truejump, int falsejump)
        {
            var b = new List <Instruction>();

            var f1 = S1.AsDirectField() ?? (S1.IsConstant() ? FieldSRef.Imm1() : null);

            if (f1 == null)
            {
                f1 = FieldSRef.ScratchInt();
                b.AddRange(S1.FetchToField(f1));
            }

            var f2 = S2.AsDirectField() ?? (S2.IsConstant() ? FieldSRef.Imm2() : null);

            if (f2 == null)
            {
                f2 = FieldSRef.ScratchInt();
                b.AddRange(S2.FetchToField(f2));
            }

            b.Add(new Instruction
            {
                opcode = Opcode.Branch,
                op1    = f1,
                imm1   = S1.IsConstant() ? new IntSExpr(S1.Evaluate()) : null,
                op2    = f2,
                imm2   = S2.IsConstant() ? new IntSExpr(S2.Evaluate()) : null,
                rjmpeq = this.Op.HasFlag(CompSpec.Equal) ? truejump : falsejump,
                rjmplt = this.Op.HasFlag(CompSpec.Less) ? truejump : falsejump,
                rjmpgt = this.Op.HasFlag(CompSpec.Greater) ? truejump : falsejump,
            });

            return(b);
        }
Пример #2
0
        public List <Instruction> CodeGen()
        {
            var code = new List <Instruction>();

            if (source.IsConstant())
            {
                code.AddRange(target.PutFromInt(source.Evaluate()));
            }
            else
            {
                var src = source.AsDirectField();

                if (src == null)
                {
                    var tgt = target.AsDirectField();
                    if (tgt == null)
                    {
                        var scratch = FieldSRef.ScratchInt();
                        code.AddRange(source.FetchToField(scratch));
                        code.AddRange(target.PutFromField(scratch));
                    }
                    else
                    {
                        code.AddRange(source.FetchToField(tgt));
                    }
                }
                else
                {
                    code.AddRange(target.PutFromField(src));
                }
            }

            return(code);
        }
Пример #3
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;
 }
Пример #4
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));
            }
        }
Пример #5
0
        public List <Instruction> FetchToField(FieldSRef dest)
        {
            var code = new List <Instruction>();

            var f1 = S1.AsDirectField();

            if (f1 == null)
            {
                if (S1.IsConstant())
                {
                    f1 = FieldSRef.Imm1();
                }
                else
                {
                    f1 = FieldSRef.ScratchInt();
                    code.AddRange(S1.FetchToField(f1));
                }
            }

            var f2 = S2.AsDirectField();

            if (f2 == null)
            {
                if (S2.IsConstant())
                {
                    f2 = FieldSRef.Imm2();
                }
                else
                {
                    f2 = FieldSRef.ScratchInt();
                    code.AddRange(S2.FetchToField(f2));
                }
            }

            Opcode op;

            switch (Op)
            {
            case ArithSpec.Add:
                op = Opcode.Add;
                break;

            case ArithSpec.Subtract:
                op = Opcode.Sub;
                break;

            case ArithSpec.Multiply:
                op = Opcode.Mul;
                break;

            case ArithSpec.Divide:
                op = Opcode.Div;
                break;

            default:
                throw new InvalidOperationException();
            }

            var tmp = FieldSRef.ScratchInt();

            code.Add(new Instruction
            {
                opcode = op,
                op1    = f1,
                imm1   = S1.IsConstant() ? S1 : null,
                op2    = f2,
                imm2   = S2.IsConstant() ? S2 : null,
                dest   = tmp,
                acc    = true
            });

            //TODO: optimize this one day?
            code.AddRange(dest.PutFromField(tmp));

            return(code);
        }