예제 #1
0
        private void RewriteRotc(IntrinsicProcedure intrinsic)
        {
            var t   = binder.EnsureFlagGroup(Registers.T);
            var op1 = SrcOp(instr.Operands[0]);

            m.Assign(op1, m.Fn(intrinsic, op1, m.Int32(1), t));
        }
예제 #2
0
        protected override void BuildBody()
        {
            var sp   = Frame.EnsureRegister(Registers.sp);
            var a    = Frame.EnsureRegister(Registers.a);
            var c    = Frame.EnsureRegister(Registers.c);
            var h    = Frame.EnsureRegister(Registers.h);
            var l    = Frame.EnsureRegister(Registers.l);
            var C    = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("C"));
            var Z    = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("Z"));
            var SZC  = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZC"));
            var SZP  = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZP"));
            var rorc = new IntrinsicProcedure(IntrinsicProcedure.RorC, false, PrimitiveType.Byte, 3);

            Assign(sp, Frame.FramePointer);
            Label("m1Loop");
            Assign(a, h);
            Assign(a, Or(a, a));
            Assign(SZC, Cond(a));
            Assign(C, Constant.False());
            Assign(a, Shr(a, Constant.Byte(1)));
            Assign(C, Cond(a));
            Assign(h, a);
            Assign(a, l);
            Assign(a, Fn(rorc, a, Constant.Byte(1), C));
            Assign(C, Cond(a));
            Assign(l, a);
            Assign(c, ISub(c, 1));
            Assign(SZP, Cond(c));
            BranchIf(Test(ConditionCode.NE, Z), "m1Loop");

            Label("m2Done");
            MStore(Word32(0x1000), l);
            MStore(Word32(0x1001), h);
            Return();
        }
예제 #3
0
 private Expression?ShiftRightShiftLeft(BinaryExpression bin)
 {
     if (bin.Operator != Operator.Shl || !(bin.Right is Constant cRight))
     {
         return(null);
     }
     if (bin.Left is Identifier idLeft)
     {
         var innerExp = ctx.GetDefiningExpression(idLeft);
         if (innerExp is null)
         {
             return(null);
         }
         if (innerExp is BinaryExpression binInner &&
             (binInner.Operator == Operator.Shr || binInner.Operator == Operator.Sar) &&
             cmp.Equals(cRight, binInner.Right))
         {
             ctx.RemoveExpressionUse(idLeft);
             ctx.UseExpression(binInner.Left);
             var sig = FunctionType.Func(
                 new Identifier("", bin.DataType, null !),
                 new Identifier("x", binInner.Left.DataType, null !),
                 new Identifier("y", PrimitiveType.Int32, null !));
             var align = new IntrinsicProcedure(IntrinsicProcedure.Align, true, sig);
             return(m.Fn(align, binInner.Left, Constant.Int32(1 << cRight.ToInt32())));
         }
     }
     return(null);
 }
예제 #4
0
        public void RewriteRotationX(IntrinsicProcedure rotation)
        {
            Expression?opDst;

            if (instr.Operands.Length == 2)
            {
                var opSrc = orw.RewriteSrc(instr.Operands[0], instr.Address);
                opDst = orw.RewriteDst(instr.Operands[1], instr.Address, opSrc, (s, d) =>
                                       m.Fn(rotation, d, s, binder.EnsureFlagGroup(Registers.X)));
            }
            else
            {
                opDst = orw.RewriteDst(instr.Operands[0], instr.Address,
                                       Constant.Byte(1), (s, d) =>
                                       m.Fn(rotation, d, s, binder.EnsureFlagGroup(Registers.X)));
            }
            if (opDst is null)
            {
                EmitInvalid();
                return;
            }
            m.Assign(
                binder.EnsureFlagGroup(Registers.CZNX),
                m.Cond(opDst));
            m.Assign(binder.EnsureFlagGroup(Registers.V), Constant.False());
        }
예제 #5
0
        private void RewriteRotateC(IntrinsicProcedure rot)
        {
            var op = Operand(instr.Operands[0]);
            var C  = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.st, (uint)FlagM.CF));

            m.Assign(op, m.Fn(rot, op, m.Byte(1), C));
            m.Assign(C, m.Cond(op));
        }
예제 #6
0
 public IntrinsicProcedure EnsureIntrinsic(string name, bool isIdempotent, DataType returnType, int arity)
 {
     if (!pprocs.TryGetValue(name, out IntrinsicProcedure p))
     {
         p = new IntrinsicProcedure(name, isIdempotent, returnType, arity);
         pprocs.Add(name, p);
     }
     return(p);
 }
예제 #7
0
        private void RewriteRotationX(H8Instruction instr, IntrinsicProcedure intrinsic)
        {
            var src = OpSrc(instr.Operands[0]);
            var c   = binder.EnsureFlagGroup(C);

            m.Assign(src, m.Fn(intrinsic, src, Constant.Int32(1), c));
            EmitCond(NZC, src);
            m.Assign(binder.EnsureFlagGroup(V), Constant.False());
        }
예제 #8
0
 public IntrinsicProcedure EnsureIntrinsic(string name, bool hasSideEffect, DataType returnType, int arity)
 {
     if (intrinsics.TryGetValue(name, out var intrinsic))
     {
         return(intrinsic);
     }
     intrinsic = new IntrinsicProcedure(name, hasSideEffect, returnType, arity);
     intrinsics.Add(name, intrinsic);
     return(intrinsic);
 }
예제 #9
0
        private void RewriteRotate(IntrinsicProcedure intrinsic)
        {
            var src = RewriteSrc(instr.Operands[0]);
            var dst = RewriteDst(instr.Operands[0], src, (a, b) =>
                                 m.Fn(
                                     intrinsic,
                                     b,
                                     RewriteSrc(instr.Operands[1])));

            EmitCond(dst, C());
        }
예제 #10
0
 public Expression CallIntrinsic(string name, bool isIdempotent, FunctionType fnType, params Expression[] args)
 {
     if (!pprocs.TryGetValue(name, out var intrinsic))
     {
         intrinsic = new IntrinsicProcedure(name, isIdempotent, fnType);
         pprocs.Add(name, intrinsic);
     }
     return(new Application(
                new ProcedureConstant(PrimitiveType.Ptr32, intrinsic),
                intrinsic.ReturnType, args));
 }
예제 #11
0
 public Expression CallIntrinsic(string name, bool isIdempotent, FunctionType fnType, params Expression[] args)
 {
     if (!this.intrinsics.TryGetValue(name, out var intrinsic))
     {
         intrinsic = new IntrinsicProcedure(name, isIdempotent, fnType);
         this.intrinsics.Add(name, intrinsic);
     }
     return(new Application(
                new ProcedureConstant(new UnknownType(), intrinsic),
                intrinsic.ReturnType,
                args));
 }
예제 #12
0
 public Expression CallIntrinsic(string name, bool hasSideEffect, FunctionType fnType, params Expression[] args)
 {
     if (!intrinsics.TryGetValue(name, out var intrinsic))
     {
         intrinsic = new IntrinsicProcedure(name, hasSideEffect, fnType);
         intrinsics.Add(name, intrinsic);
     }
     return(new Application(
                new ProcedureConstant(PrimitiveType.Ptr32, intrinsic),
                fnType.ReturnValue.DataType,
                args));
 }
예제 #13
0
        private void RewriteLoadAcquireDouble(IntrinsicProcedure intrinsic)
        {
            var mem = (MemoryOperand)Src2();
            var ea  = binder.EnsureRegister(mem.BaseRegister !);

            ea.DataType = new Pointer(PrimitiveType.Word64, 32);
            var regHi = ((RegisterOperand)instr.Operands[0]).Register;
            var regLo = ((RegisterOperand)instr.Operands[1]).Register;
            var dst   = binder.EnsureSequence(PrimitiveType.Word64, regHi, regLo);
            var src   = m.Fn(intrinsic, ea);

            m.Assign(dst, src);
        }
예제 #14
0
        public void Exs_Ror_ror()
        {
            Given_ExpressionSimplifier();
            var r0     = new RegisterStorage("r0", 0, 0, PrimitiveType.Word32);
            var r1     = new RegisterStorage("r1", 0, 0, PrimitiveType.Word32);
            var sigRol = FunctionType.Func(
                new Identifier("", r0.DataType, r0),
                new Identifier("value", r0.DataType, r0),
                new Identifier("sh", r0.DataType, r1));
            var ror = new IntrinsicProcedure(IntrinsicProcedure.Ror, true, sigRol);
            var exp = m.Fn(ror, m.Fn(ror, foo, m.Word32(2)), m.Word32(1));

            Assert.AreEqual("__ror(foo_1, 3<32>)", exp.Accept(simplifier).ToString());
        }
예제 #15
0
        private IntrinsicProcedure MakeIntrinsic(FunctionType signature)
        {
            IntrinsicProcedure proc;

            if (this.genericTypes is not null)
            {
                proc = new IntrinsicProcedure(intrinsicName, genericTypes, false, hasSideEffect, signature);
            }
            else
            {
                proc = new IntrinsicProcedure(intrinsicName, hasSideEffect, signature);
            }
            proc.Characteristics = characteristics;
            proc.ApplyConstants  = this.applyConstants;
            return(proc);
        }
예제 #16
0
        private void RewriteLoadAcquire(IntrinsicProcedure intrinsic)
        {
            var        mem = (MemoryOperand)Src1();
            var        ea  = binder.EnsureRegister(mem.BaseRegister !);
            var        dst = binder.EnsureRegister(((RegisterOperand)instr.Operands[0]).Register);
            Expression src = m.Fn(intrinsic, ea);

            if (src.DataType.BitSize != dst.DataType.BitSize)
            {
                var dt  = intrinsic.ReturnType;
                var tmp = binder.CreateTemporary(dt);
                m.Assign(tmp, src);
                src = m.Convert(tmp, dt, dst.DataType);
            }
            m.Assign(dst, src);
        }
예제 #17
0
        public void DeadIdempotentIntrinsic()
        {
            var dead      = m.Reg32("dead");
            var intrinsic = new IntrinsicProcedure("useless", true, PrimitiveType.Int32, 0);

            m.Assign(dead, m.Fn(intrinsic));
            m.Return();

            EliminateDeadCode();

            var sExp =
                @"
return
";

            AssertProcedureCode(sExp);
        }
예제 #18
0
 protected void Given_RewriterHost()
 {
     host = new Mock <IRewriterHost>();
     host.Setup(h => h.Intrinsic(
                    It.IsAny <string>(),
                    It.IsAny <bool>(),
                    It.IsAny <DataType>(),
                    It.IsAny <Expression[]>()))
     .Returns((string n, bool i, DataType dt, Expression[] a) =>
     {
         var fn        = new FunctionType();
         var intrinsic = new IntrinsicProcedure(n, i, fn);
         return(new Application(new ProcedureConstant(fn, intrinsic),
                                dt,
                                a));
     });
 }
예제 #19
0
        public void DeadConversion()
        {
            var dead      = m.Reg32("dead");
            var intrinsic = new IntrinsicProcedure("sideffector", true, PrimitiveType.Int32, 0);

            m.Assign(dead, m.Convert(m.Fn(intrinsic), PrimitiveType.Int32, PrimitiveType.Int64));
            m.Return();

            EliminateDeadCode();

            var sExp =
                @"
sideffector()
return
";

            AssertProcedureCode(sExp);
        }
예제 #20
0
        public void DeadIntrinsicWithSideEffect()
        {
            var dead      = m.Reg32("dead");
            var intrinsic = new IntrinsicProcedure("sideffector", false, PrimitiveType.Int32, 0);

            m.Assign(dead, m.Fn(intrinsic));
            m.Return();

            EliminateDeadCode();

            var sExp =
                @"
sideffector()
return
";

            AssertProcedureCode(sExp);
        }
예제 #21
0
 public Expression Intrinsic(string name, bool isIdempotent, ProcedureCharacteristics c, DataType returnType, params Expression[] args)
 {
     if (!this.intrinsics.TryGetValue(name, out var intrinsic))
     {
         var ret     = new Identifier("", returnType, new TemporaryStorage("xx", 42, returnType));
         var formals = args.Select((a, i) =>
                                   new Identifier($"arg{i}", a.DataType, new TemporaryStorage("aa", 43, a.DataType)))
                       .ToArray();
         intrinsic = new IntrinsicProcedure(name, isIdempotent, FunctionType.Func(ret, formals))
         {
             Characteristics = c,
         };
         this.intrinsics.Add(name, intrinsic);
     }
     return(new Application(
                new ProcedureConstant(new UnknownType(), intrinsic),
                intrinsic.ReturnType,
                args));
 }
예제 #22
0
        private void RewriteRotation(IntrinsicProcedure pseudoOp, bool useCarry)
        {
            Expression reg;

            if (instr.Operands.Length >= 1)
            {
                reg = RewriteSrc(instr.Operands[0]);
            }
            else
            {
                reg = binder.EnsureRegister(Registers.a);
            }
            var        c = binder.EnsureFlagGroup(Registers.C);
            Expression src;
            var        one = m.Byte(1);

            if (useCarry)
            {
                src = m.Fn(pseudoOp, reg, one, c);
            }
            else
            {
                src = m.Fn(pseudoOp, reg, one);
            }
            Expression result;

            if (instr.Operands.Length >= 1)
            {
                result = RewriteDst(instr.Operands[0], src, (a, b) => b);
            }
            else
            {
                m.Assign(reg, src);
                result = reg;
            }
            EmitCc(result, "**-0XP0*");
        }
예제 #23
0
 public void Setup()
 {
     m           = new ProcedureBuilder();
     this.rolc_8 = new IntrinsicProcedure(IntrinsicProcedure.RolC, true, PrimitiveType.Byte, 3);
     arch        = new Mock <IProcessorArchitecture>();
 }
예제 #24
0
 public void Setup()
 {
     m           = new ProcedureBuilder();
     this.rolc_8 = CommonOps.RolC.MakeInstance(PrimitiveType.Word32, PrimitiveType.Byte, PrimitiveType.Bool);
     arch        = new Mock <IProcessorArchitecture>();
 }
예제 #25
0
        private void RewriteRot(IntrinsicProcedure intrinsic)
        {
            var op1 = SrcOp(instr.Operands[0]);

            m.Assign(op1, m.Fn(intrinsic, op1, m.Int32(1)));
        }
예제 #26
0
        private void RewriteRotate(IntrinsicProcedure rot)
        {
            var dst = OpSrc(instr.Operands[0], arch.DataMemory);

            m.Assign(dst, m.Fn(rot, dst, m.Byte(1)));
        }