コード例 #1
0
            // reg = T(L, R)
            static Tile makeRegisterAssignmentBinopTile <T, L, R>(Func <RegisterNode, L, R, IEnumerable <Instruction> > tileMaker)
                where T : BinaryOperatorNode
                where L : Node
                where R : Node
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <T> (
                        makeTile <L> (),
                        makeTile <R> ()
                        )
                },
                                (regNode, node) => {
                    var assignment = node as AssignmentNode;
                    var dst = assignment.Target as RegisterNode;
                    var binop = assignment.Source as T;
                    var l = binop.LeftOperand as L;
                    var r = binop.RightOperand as R;

                    var insn = new LinkedList <Instruction> (tileMaker(dst, l, r));
                    insn.AddLast(InstructionFactory.Move(regNode, dst));
                    return insn;
                }
                                ));
            }
コード例 #2
0
            public static Tile Reg_Const()
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <ConstantNode <long> > ()
                },
                                (regNode, node) => {
                    var root = node as AssignmentNode;
                    var target = root.Target as RegisterNode;
                    var valNode = root.Source as ConstantNode <long>;

                    if (valNode.Value == 0L)
                    {
                        return new [] {
                            InstructionFactory.Xor(target, target),
                            InstructionFactory.Move(regNode, target)
                        };
                    }
                    else
                    {
                        return new [] {
                            InstructionFactory.Move(target, valNode),
                            InstructionFactory.Move(regNode, target)
                        };
                    }
                }
                                ));
            }
コード例 #3
0
            // reg = T1(T2(L, M), R)
            static Tile makeRegisterAssignmentTriop2Tile <T1, T2, L, M, R>(
                Func <RegisterNode, L, M, R, IEnumerable <Instruction> > tileMaker
                )
                where T1 : BinaryOperatorNode
                where T2 : BinaryOperatorNode
                where L : Node
                where M : Node
                where R : Node
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <T1> (
                        makeTile <T2> (
                            makeTile <L>(),
                            makeTile <M>()
                            ),
                        makeTile <R>()
                        )
                },
                                (regNode, node) => {
                    var assignment = node as AssignmentNode;
                    var dst = assignment.Target as RegisterNode;
                    var t1 = assignment.Source as T1;
                    var t2 = t1.LeftOperand as T2;
                    var l = t2.LeftOperand as L;
                    var m = t2.RightOperand as M;
                    var r = t1.RightOperand as R;

                    var insn = new LinkedList <Instruction> (tileMaker(dst, l, m, r));
                    insn.AddLast(InstructionFactory.Move(regNode, dst));
                    return insn;
                }
                                ));
            }
コード例 #4
0
 public static Tile Plus_Reg()
 {
     return(makeUnopTile <UnaryPlusOperatorNode, RegisterNode> (
                (regNode, root, left) => new [] {
         InstructionFactory.Move(regNode, left)
     }
                ));
 }
コード例 #5
0
 public static Tile ConstReg()
 {
     return(makeBinopTile <LogAndOperatorNode, ConstantNode <long>, RegisterNode> (
                (regNode, left, right) => left.Value == 0L
                             ? new[] { InstructionFactory.Xor(regNode, regNode) }   // l == 0 -> all = 0
                             : new[] { InstructionFactory.Move(regNode, right) }    // l != 0 -> all = r
                ));
 }
コード例 #6
0
 public static Tile RegConst()
 {
     return(makeBinopTile <LogAndOperatorNode, RegisterNode, ConstantNode <long> > (
                (regNode, left, right) => right.Value == 0L
                             ? new[] { InstructionFactory.Xor(regNode, regNode) }  // r == 0 -> all = 0
                             : new[] { InstructionFactory.Move(regNode, left) }    // r != 0 -> all = l
                ));
 }
コード例 #7
0
 public static Tile Dec_Reg()
 {
     return(makeUnopTile <DecOperatorNode, RegisterNode> (
                (regNode, root, left) => new [] {
         InstructionFactory.Dec(left),
         InstructionFactory.Move(regNode, left)
     }
                ));
 }
コード例 #8
0
 public static Tile ConstTile <T>()
 {
     return(new Tile(typeof(ConstantNode <T>),
                     new Tile[] { },
                     (regNode, node) => new[] {
         InstructionFactory.Move(regNode, node as ConstantNode <T>)
     }
                     ));
 }
コード例 #9
0
 public static Tile Neg_Reg()
 {
     return(makeUnopTile <NegOperatorNode, RegisterNode> (
                (regNode, root, left) => new [] {
         InstructionFactory.Move(regNode, left),
         InstructionFactory.Neg(regNode)
     }
                ));
 }
コード例 #10
0
 public static Tile RegReg()
 {
     return(makeBinopTile <MulOperatorNode, RegisterNode, RegisterNode> (
                (regNode, left, right) => new[] {
         InstructionFactory.Move(Target.RAX, left),                                // RAX = left
         InstructionFactory.Mul(right),                                            // RDX:RAX = left * right
         InstructionFactory.Move(regNode, Target.RAX)                              // result = RAX
     }
                ));
 }
コード例 #11
0
 static Tile makeBinopConstRegTile <T, C>(Func <RegisterNode, RegisterNode, Instruction> specificInsn)
     where T : BinaryOperatorNode
 {
     return(makeBinopTile <T, ConstantNode <C>, RegisterNode> (
                (regNode, left, right) => new[] {
         InstructionFactory.Move(regNode, left),
         specificInsn(regNode, right)
     }
                ));
 }
コード例 #12
0
 public static Tile ConstReg <T>()
 {
     return(makeBinopTile <ModOperatorNode, ConstantNode <T>, RegisterNode> (
                (regNode, left, right) => new[] {
         InstructionFactory.Xor(Target.RDX, Target.RDX),                              // RDX = 0
         InstructionFactory.Move(Target.RAX, left),                                   // RDX:RAX = left
         InstructionFactory.Div(right),                                               // RDX = left % right
         InstructionFactory.Move(regNode, Target.RDX)                                 // result = RDX
     }
                ));
 }
コード例 #13
0
 public static Tile RegConst <T>()
 {
     return(makeBinopTile <DivOperatorNode, RegisterNode, ConstantNode <T> > (
                (regNode, left, right) => new[] {
         InstructionFactory.Xor(Target.RDX, Target.RDX),                              // RDX = 0
         InstructionFactory.Move(Target.RAX, left),                                   // RDX:RAX = left
         InstructionFactory.Move(regNode, right),                                     // reg = rigth
         InstructionFactory.Div(regNode),                                             // RAX = left / reg = left / right
         InstructionFactory.Move(regNode, Target.RAX)                                 // result = RAX
     }
                ));
 }
コード例 #14
0
 public static Tile RegReg()
 {
     // l = 0            ->  first instruction sets reg to 0
     // r = 0 but l > 0  ->  fourth instruction sets reg to 0
     // l > 0 and r > 0  ->  first instruction sets reg = l > 0 and nothing changes
     return(makeBinopTile <LogAndOperatorNode, RegisterNode, RegisterNode> (
                (regNode, left, right) => new[] {
         InstructionFactory.Move(regNode, left),                                // reg = left
         InstructionFactory.Xor(left, left),                                    // left = 0
         InstructionFactory.Cmp(right, left),                                   // if right == 0
         InstructionFactory.Cmove(regNode, left)                                // then reg = 0
     }
                ));
 }
コード例 #15
0
            public static Tile Reg_Reg()
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <RegisterNode> ()
                },
                                (regNode, node) => {
                    var root = node as AssignmentNode;
                    var target = root.Target as RegisterNode;
                    var source = root.Source as RegisterNode;

                    return new [] {
                        InstructionFactory.Move(target, source),
                        InstructionFactory.Move(regNode, target)
                    };
                }
                                ));
            }
コード例 #16
0
 public static Tile MemReg_Reg()
 {
     return(new Tile(typeof(AssignmentNode),
                     new[] {
         makeTile <MemoryNode> (
             makeTile <RegisterNode> ()
             ),
         makeTile <RegisterNode> ()
     },
                     (regNode, node) => {
         var root = node as AssignmentNode;
         var mem = root.Target as MemoryNode;
         var dst = mem.Address as RegisterNode;
         var src = root.Source as RegisterNode;
         return new[] {
             InstructionFactory.MoveToMemory(dst, src),
             InstructionFactory.Move(regNode, src)
         };
     }
                     ));
 }
コード例 #17
0
            static IEnumerable <Instruction> EffectiveMultiplication(RegisterNode dst, RegisterNode mul_reg, ConstantNode <long> mul_val)
            {
                switch (mul_val.Value)
                {
                case 2L:
                case 4L:
                case 8L:
                    return(new [] {
                        InstructionFactory.Lea_Mul(dst, mul_reg, mul_val)
                    });

                case 3L:
                case 5L:
                case 9L:
                    var tmp_val = new ConstantNode <long> (mul_val.Value - 1L);
                    return(new [] {
                        InstructionFactory.Lea_MulAdd(dst, mul_reg, tmp_val, mul_reg)
                    });

                case 1L:
                    return(new [] {
                        InstructionFactory.Move(dst, mul_reg)
                    });

                case 0L:
                    return(new [] {
                        InstructionFactory.Xor(dst, dst)
                    });

                default:
                    // dst = mul_reg * mul_val
                    return(new [] {
                        InstructionFactory.Move(Target.RAX, mul_val),                          // RAX = mul_val
                        InstructionFactory.Mul(mul_reg),                                       // RDX:RAX = mul_reg * mul_val
                        InstructionFactory.Move(dst, Target.RAX)                               // dst = RAX
                    });
                }
            }
コード例 #18
0
            public static Tile Reg_RegRegConstConst()
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <AddOperatorNode>(
                        makeTile <AddOperatorNode>(
                            makeTile <RegisterNode>(),
                            makeTile <MulOperatorNode> (
                                makeTile <RegisterNode> (),
                                makeTile <ConstantNode <long> > ()
                                )
                            ),
                        makeTile <ConstantNode <long> >()
                        )
                },
                                (regNode, node) => {
                    var assignment = node as AssignmentNode;
                    var dst = assignment.Target as RegisterNode;
                    var add1 = assignment.Source as AddOperatorNode;
                    var add2 = add1.LeftOperand as AddOperatorNode;

                    var reg1 = add2.LeftOperand as RegisterNode;
                    var mul = add2.RightOperand as MulOperatorNode;
                    var mul_reg = mul.LeftOperand as RegisterNode;
                    var mul_val = mul.RightOperand as ConstantNode <long>;
                    var val2 = add1.RightOperand as ConstantNode <long>;

                    return new [] {
                        new Instruction(
                            map => string.Format("lea {0}, [{1}+{2}*{3}+{4}]", map [dst], map [reg1], map[mul_reg], mul_val.Value, val2.Value),
                            use(dst, mul_reg), define(dst)),
                        InstructionFactory.Move(regNode, dst)
                    };
                }
                                ));
            }
コード例 #19
0
            // reg1 = reg2 - const
            public static Tile Reg_SubConst()
            {
                return(new Tile(typeof(AssignmentNode),
                                new[] {
                    makeTile <RegisterNode> (),
                    makeTile <SubOperatorNode> (
                        makeTile <RegisterNode> (),
                        makeTile <ConstantNode <long> > ()
                        )
                },
                                (regNode, node) => {
                    var root = node as AssignmentNode;
                    var reg1 = root.Target as RegisterNode;
                    var subop = root.Source as SubOperatorNode;
                    var reg2 = subop.LeftOperand as RegisterNode;
                    var val = subop.RightOperand as ConstantNode <long>;

                    // reg = reg - 1 -> reg--
                    if (reg1 == reg2 && val.Value == 1L)
                    {
                        return new[] {
                            InstructionFactory.Dec(reg1),
                            InstructionFactory.Move(regNode, reg1)
                        };
                    }
                    else
                    {
                        return new[] {
                            InstructionFactory.Move(reg1, reg2),                                       // r = left
                            InstructionFactory.Sub(reg1, val),                                         // r = left - right
                            InstructionFactory.Move(regNode, reg1)
                        };
                    }
                }
                                ));
            }