Пример #1
0
        private static Statement ExpandComplex(Statement s)
        {
            if(s is Instruction)
            {
                Instruction src = s as Instruction;

                // TODO: is it complex?
                Instruction dest = new Instruction();
                dest.op = src.op.ToLower();
                dest.srca = src.srca;
                dest.srcb = src.srcb;
                dest.dest = src.dest;
                return dest;
            }
            return s;
        }
Пример #2
0
        private static void ExpandComplex(Statement s, List<Statement> next_pass)
        {
            if(s is Instruction)
            {
                Instruction src = s as Instruction;

                string op_lower = src.op.ToLower();

                // is it complex?
                if (op_lower == "jl")
                {
                    /* Jump with link
                        add PC, 4->LR
                        j x
                    */
                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "add";
                    new_1.srca = new RegisterOperand { val = "PC" };
                    new_1.srcb = new IntegerOperand { val = 4 };
                    new_1.dest = new RegisterOperand { val = "LR" };
                    next_pass.Add(new_1);

                    Instruction new_2 = new Instruction();
                    new_2.cond = src.cond;
                    new_2.op = "j";
                    new_2.srca = src.srca;
                    next_pass.Add(new_2);
                }
                else if (op_lower == "jrel")
                {
                    /* Relative jump
                        only valid if srca is a label/integer
                        -> mov x -> pc (which is interpreted as an add to pc)
                    */
                    Expression new_srca = null;
                    if (src.srca is IntegerOperand)
                        new_srca = src.srca;
                    else if (src.srca is LabelExpression)
                    {
                        new_srca = src.srca;
                        ((LabelExpression)new_srca).addend = -4;
                        ((LabelExpression)new_srca).is_pcrel = true;
                    }
                    else if (src.srca is RegisterOperand)
                    {
                        var r_srca = src.srca as RegisterOperand;
                        if (regs.ContainsKey(r_srca.val.ToUpper()))
                        {
                            throw new Exception("jrel must have an integer or label operand");
                        }
                        new_srca = src.srca;
                        ((LabelExpression)new_srca).addend = -4;
                        ((LabelExpression)new_srca).is_pcrel = true;
                    }

                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "mov";
                    new_1.srca = new_srca;
                    new_1.dest = new RegisterOperand { val = "PC" };
                    next_pass.Add(new_1);
                }
                else if (op_lower == "jlrel")
                {
                    /* Relative jump with link
                        only valid if srca is a label/integer
                        ->  add pc, 4 -> lr
                            mov x -> pc (which is interpreted as an add to pc)
                    */
                    Expression new_srca = null;
                    if (src.srca is IntegerOperand)
                        new_srca = src.srca;
                    else if (src.srca is LabelExpression)
                    {
                        new_srca = src.srca;
                        ((LabelExpression)new_srca).addend = -4;
                        ((LabelExpression)new_srca).is_pcrel = true;
                    }
                    else if (src.srca is RegisterOperand)
                    {
                        var r_srca = src.srca as RegisterOperand;
                        if (regs.ContainsKey(r_srca.val.ToUpper()))
                        {
                            throw new Exception("jrel must have an integer or label operand");
                        }
                        new_srca = src.srca;
                        ((LabelExpression)new_srca).addend = -4;
                        ((LabelExpression)new_srca).is_pcrel = true;
                    }

                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "add";
                    new_1.srca = new RegisterOperand { val = "PC" };
                    new_1.srcb = new IntegerOperand { val = 4 };
                    new_1.dest = new RegisterOperand { val = "LR" };
                    next_pass.Add(new_1);

                    Instruction new_2 = new Instruction();
                    new_2.cond = src.cond;
                    new_2.op = "mov";
                    new_2.srca = new_srca;
                    new_2.dest = new RegisterOperand { val = "PC" };
                    next_pass.Add(new_2);
                }
                else if (op_lower == "ret")
                {
                    /* Return
                        j LR
                    */
                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "j";
                    new_1.srca = new RegisterOperand { val = "LR" };
                    next_pass.Add(new_1);
                }
                else if (op_lower == "push")
                {
                    /* Push x
                        sub SP, 4 -> SP
                        store x, 4 -> SP
                    */
                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "sub";
                    new_1.srca = new RegisterOperand { val = "SP" };
                    new_1.srcb = new IntegerOperand { val = 4 };
                    new_1.dest = new RegisterOperand { val = "SP" };
                    next_pass.Add(new_1);

                    Instruction new_2 = new Instruction();
                    new_2.cond = src.cond;
                    new_2.op = "store";
                    new_2.srca = src.srca;
                    new_2.srcb = new IntegerOperand { val = 4 };
                    new_2.dest = new RegisterOperand { val = "SP" };
                    next_pass.Add(new_2);
                }
                else if (op_lower == "pop")
                {
                    /* Pop x
                        load SP, 4 -> x
                        add SP, 4 -> SP
                    */
                    Instruction new_1 = new Instruction();
                    new_1.cond = src.cond;
                    new_1.op = "load";
                    new_1.srca = new RegisterOperand { val = "SP" };
                    new_1.srcb = new IntegerOperand { val = 4 };
                    new_1.dest = src.srca;
                    next_pass.Add(new_1);

                    Instruction new_2 = new Instruction();
                    new_2.cond = src.cond;
                    new_2.op = "add";
                    new_2.srca = new RegisterOperand { val = "SP" };
                    new_2.srcb = new IntegerOperand { val = 4 };
                    new_2.dest = new RegisterOperand { val = "SP" };
                    next_pass.Add(new_2);
                }
                else
                {
                    Instruction dest = new Instruction();
                    dest.op = op_lower;
                    dest.srca = src.srca;
                    dest.srcb = src.srcb;
                    dest.dest = src.dest;
                    dest.cond = src.cond;
                    next_pass.Add(dest);
                }
            }
            else
                next_pass.Add(s);
        }