예제 #1
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;
            var operand2 = context.Operand2;

            transformContext.SplitLongOperand(result, out Operand resultLow, out Operand resultHigh);

            var branch         = context.ConditionCode;
            var branchUnsigned = context.ConditionCode.GetUnsigned();

            var nextBlock = transformContext.Split(context);
            var newBlocks = transformContext.CreateNewBlockContexts(5, context.Label);

            TransformContext.UpdatePHIInstructionTargets(nextBlock.Block.NextBlocks, context.Block, nextBlock.Block);

            var op0Low  = transformContext.AllocateVirtualRegister32();
            var op0High = transformContext.AllocateVirtualRegister32();
            var op1Low  = transformContext.AllocateVirtualRegister32();
            var op1High = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            // Compare high
            context.AppendInstruction(IRInstruction.Branch32, ConditionCode.Equal, null, op0High, op1High, newBlocks[1].Block);
            context.AppendInstruction(IRInstruction.Jmp, newBlocks[0].Block);

            // Branch if check already gave results
            if (branch == ConditionCode.Equal)
            {
                newBlocks[0].AppendInstruction(IRInstruction.Jmp, newBlocks[3].Block);
            }
            else
            {
                newBlocks[0].AppendInstruction(IRInstruction.Branch32, branch, null, op0High, op1High, newBlocks[2].Block);
                newBlocks[0].AppendInstruction(IRInstruction.Jmp, newBlocks[3].Block);
            }

            // Compare low
            newBlocks[1].AppendInstruction(IRInstruction.Branch32, branchUnsigned, null, op0Low, op1Low, newBlocks[2].Block);
            newBlocks[1].AppendInstruction(IRInstruction.Jmp, newBlocks[3].Block);

            // Success
            newBlocks[2].AppendInstruction(IRInstruction.Jmp, newBlocks[4].Block);

            // Failed
            newBlocks[3].AppendInstruction(IRInstruction.Jmp, newBlocks[4].Block);

            // Exit
            newBlocks[4].AppendInstruction(IRInstruction.Phi64, resultLow, transformContext.CreateConstant((uint)1), transformContext.ConstantZero64);
            newBlocks[4].PhiBlocks = new List <BasicBlock>(2)
            {
                newBlocks[2].Block, newBlocks[3].Block
            };
            newBlocks[4].AppendInstruction(IRInstruction.Jmp, nextBlock.Block);
        }
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;
            var operand2 = context.Operand2;

            var op0Low  = transformContext.AllocateVirtualRegister32();
            var op0High = transformContext.AllocateVirtualRegister32();
            var op1Low  = transformContext.AllocateVirtualRegister32();
            var op1High = transformContext.AllocateVirtualRegister32();

            var v1 = transformContext.AllocateVirtualRegister32();
            var v2 = transformContext.AllocateVirtualRegister32();
            var v3 = transformContext.AllocateVirtualRegister32();
            var v4 = transformContext.AllocateVirtualRegister32();
            var v5 = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            context.AppendInstruction(IRInstruction.Compare32x32, ConditionCode.UnsignedGreater, v1, op0High, op1High);
            context.AppendInstruction(IRInstruction.Compare32x32, ConditionCode.Equal, v2, op0High, op1High);
            context.AppendInstruction(IRInstruction.Compare32x32, ConditionCode.UnsignedGreater, v3, op0Low, op1Low);

            context.AppendInstruction(IRInstruction.And32, v4, v2, v3);
            context.AppendInstruction(IRInstruction.Or32, v5, v1, v4);

            //context.AppendInstruction(IRInstruction.And32, result, v5, transformContext.CreateConstant((uint)1));
            context.AppendInstruction(IRInstruction.IfThenElse32, result, v5, transformContext.CreateConstant((uint)1), transformContext.ConstantZero32);
        }
예제 #3
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            var resultLow  = transformContext.AllocateVirtualRegister32();
            var resultHigh = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.Move32, resultLow, operand1);
            context.AppendInstruction(IRInstruction.ArithShiftRight32, resultHigh, resultLow, transformContext.CreateConstant(31));
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }
예제 #4
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            var resultLow  = transformContext.AllocateVirtualRegister32();
            var resultHigh = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, resultLow, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, resultHigh, operand1);
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }
예제 #5
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            Debug.Assert(context.ConditionCode != ConditionCode.Equal);

            var result   = context.Result;
            var operand1 = context.Operand1;
            var operand2 = context.Operand2;

            transformContext.SplitLongOperand(result, out Operand resultLow, out Operand resultHigh);

            var branch         = context.ConditionCode;
            var branchUnsigned = context.ConditionCode.GetUnsigned();

            var nextBlock = transformContext.Split(context);
            var newBlocks = transformContext.CreateNewBlockContexts(5, context.Label);

            TransformContext.UpdatePHIInstructionTargets(nextBlock.Block.NextBlocks, context.Block, nextBlock.Block);

            var op0Low  = transformContext.AllocateVirtualRegister32();
            var op0High = transformContext.AllocateVirtualRegister32();
            var op1Low  = transformContext.AllocateVirtualRegister32();
            var op1High = transformContext.AllocateVirtualRegister32();
            var tempLow = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            // Compare high
            context.AppendInstruction(IRInstruction.Branch32, ConditionCode.Equal, null, op0High, op1High, newBlocks[1].Block);
            context.AppendInstruction(IRInstruction.Jmp, newBlocks[0].Block);

            newBlocks[0].AppendInstruction(IRInstruction.Branch32, branch, null, op0High, op1High, newBlocks[2].Block);
            newBlocks[0].AppendInstruction(IRInstruction.Jmp, newBlocks[3].Block);

            // Compare low
            newBlocks[1].AppendInstruction(IRInstruction.Branch32, branchUnsigned, null, op0Low, op1Low, newBlocks[2].Block);
            newBlocks[1].AppendInstruction(IRInstruction.Jmp, newBlocks[3].Block);

            // Success
            newBlocks[2].AppendInstruction(IRInstruction.Move32, tempLow, transformContext.CreateConstant((uint)1));
            newBlocks[2].AppendInstruction(IRInstruction.Jmp, newBlocks[4].Block);

            // Failed
            newBlocks[3].AppendInstruction(IRInstruction.Move32, tempLow, transformContext.ConstantZero32);
            newBlocks[3].AppendInstruction(IRInstruction.Jmp, newBlocks[4].Block);

            // Exit
            newBlocks[4].AppendInstruction(IRInstruction.Move32, resultLow, tempLow);
            newBlocks[4].AppendInstruction(IRInstruction.Move32, resultHigh, transformContext.ConstantZero32);
            newBlocks[4].AppendInstruction(IRInstruction.Jmp, nextBlock.Block);
        }
예제 #6
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            var resultLow  = transformContext.AllocateVirtualRegister32();
            var resultHigh = transformContext.AllocateVirtualRegister32();

            transformContext.SplitLongOperand(operand1, out Operand op1Low, out Operand op1High);

            context.SetInstruction(IRInstruction.LoadParam32, resultLow, op1Low);
            context.AppendInstruction(IRInstruction.LoadParam32, resultHigh, op1High);
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }
예제 #7
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            transformContext.SplitLongOperand(operand1, out Operand op0Low, out Operand _);

            var resultLow  = transformContext.AllocateVirtualRegister32();
            var resultHigh = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.LoadParamSignExtend8x32, resultLow, op0Low);
            context.AppendInstruction(IRInstruction.ArithShiftRight32, resultHigh, resultLow, transformContext.CreateConstant(31));
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }
예제 #8
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            //Debug.Assert(context.ConditionCode != ConditionCode.Equal);

            var operand1 = context.Operand1;
            var operand2 = context.Operand2;
            var target   = context.BranchTargets[0];

            var branch         = context.ConditionCode;
            var branchUnsigned = context.ConditionCode.GetUnsigned();

            var nextBlock = transformContext.Split(context);
            var newBlocks = transformContext.CreateNewBlockContexts(4, context.Label);

            // no branch
            TransformContext.UpdatePHIInstructionTargets(nextBlock.Block.NextBlocks, context.Block, nextBlock.Block);

            // Branch
            TransformContext.UpdatePHIInstructionTarget(target, context.Block, newBlocks[3].Block);

            var op0Low  = transformContext.AllocateVirtualRegister32();
            var op0High = transformContext.AllocateVirtualRegister32();
            var op1Low  = transformContext.AllocateVirtualRegister32();
            var op1High = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            // Compare high (equal)
            context.AppendInstruction(IRInstruction.Branch32, ConditionCode.Equal, null, op0High, op1High, newBlocks[1].Block);
            context.AppendInstruction(IRInstruction.Jmp, newBlocks[0].Block);

            // Compare high
            newBlocks[0].AppendInstruction(IRInstruction.Branch32, branch, null, op0High, op1High, newBlocks[3].Block);
            newBlocks[0].AppendInstruction(IRInstruction.Jmp, newBlocks[2].Block);

            // Compare low
            newBlocks[1].AppendInstruction(IRInstruction.Branch32, branchUnsigned, null, op0Low, op1Low, newBlocks[3].Block);
            newBlocks[1].AppendInstruction(IRInstruction.Jmp, newBlocks[2].Block);

            // No branch
            newBlocks[2].AppendInstruction(IRInstruction.Jmp, nextBlock.Block);

            // Branch
            newBlocks[3].AppendInstruction(IRInstruction.Jmp, target);
        }
예제 #9
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var offset = context.Operand1;
            var value  = context.Operand2;

            var valueLow  = transformContext.AllocateVirtualRegister32();
            var valueHigh = transformContext.AllocateVirtualRegister32();

            transformContext.SplitLongOperand(offset, out Operand op1Low, out Operand op1High);

            context.SetInstruction(IRInstruction.GetLow32, valueLow, value);
            context.AppendInstruction(IRInstruction.GetHigh32, valueHigh, value);

            context.AppendInstruction(IRInstruction.StoreParam32, null, op1Low, valueLow);
            context.AppendInstruction(IRInstruction.StoreParam32, null, op1High, valueHigh);
        }
예제 #10
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result    = context.Result;
            var operand1  = context.Operand1;
            var operand2  = context.Operand2;
            var condition = context.ConditionCode;

            var op0Low  = transformContext.AllocateVirtualRegister32();
            var op0High = transformContext.AllocateVirtualRegister32();
            var op1Low  = transformContext.AllocateVirtualRegister32();
            var op1High = transformContext.AllocateVirtualRegister32();

            var v1 = transformContext.AllocateVirtualRegister32();
            var v2 = transformContext.AllocateVirtualRegister32();
            var v3 = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            context.AppendInstruction(IRInstruction.Xor32, v1, op0Low, op1Low);
            context.AppendInstruction(IRInstruction.Xor32, v2, op0High, op1High);
            context.AppendInstruction(IRInstruction.Or32, v3, v1, v2);
            context.AppendInstruction(IRInstruction.Compare32x32, condition, result, v3, transformContext.ConstantZero32);
        }
예제 #11
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            var v1 = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.ZeroExtend16x32, v1, operand1);
            context.AppendInstruction(IRInstruction.To64, result, operand1, transformContext.ConstantZero32);
        }
예제 #12
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result  = context.Result;
            var address = context.Operand1;
            var offset  = context.Operand2;

            var resultLow  = transformContext.AllocateVirtualRegister32();
            var resultHigh = transformContext.AllocateVirtualRegister32();
            var offsetLow  = transformContext.AllocateVirtualRegister32();
            var addressLow = transformContext.AllocateVirtualRegister32();
            var offset4    = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, addressLow, address);
            context.AppendInstruction(IRInstruction.GetLow32, offsetLow, offset);

            context.AppendInstruction(IRInstruction.Load32, resultLow, addressLow, offset);
            context.AppendInstruction(IRInstruction.Add32, offset4, offsetLow, transformContext.CreateConstant((uint)4));
            context.AppendInstruction(IRInstruction.Load32, resultHigh, addressLow, offset4);
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }
예제 #13
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;

            transformContext.SplitLongOperand(operand1, out Operand op0Low, out Operand _);

            var resultLow = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.LoadParamZeroExtend16x32, resultLow, op0Low);
            context.AppendInstruction(IRInstruction.To64, result, resultLow, transformContext.ConstantZero32);
        }
예제 #14
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var address = context.Operand1;
            var offset  = context.Operand2;
            var value   = context.Operand3;

            var valueLow   = transformContext.AllocateVirtualRegister32();
            var valueHigh  = transformContext.AllocateVirtualRegister32();
            var offsetLow  = transformContext.AllocateVirtualRegister32();
            var addressLow = transformContext.AllocateVirtualRegister32();
            var offset4    = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, valueLow, value);
            context.AppendInstruction(IRInstruction.GetHigh32, valueHigh, value);
            context.AppendInstruction(IRInstruction.GetLow32, addressLow, address);
            context.AppendInstruction(IRInstruction.GetLow32, offsetLow, offset);

            context.AppendInstruction(IRInstruction.Store32, null, addressLow, offset, valueLow);
            context.AppendInstruction(IRInstruction.Add32, offset4, offsetLow, transformContext.CreateConstant((uint)4));
            context.AppendInstruction(IRInstruction.Store32, null, addressLow, offset4, valueHigh);
        }
예제 #15
0
        public override void Transform(Context context, TransformContext transformContext)
        {
            var result   = context.Result;
            var operand1 = context.Operand1;
            var operand2 = context.Operand2;

            var op0Low      = transformContext.AllocateVirtualRegister32();
            var op0High     = transformContext.AllocateVirtualRegister32();
            var op1Low      = transformContext.AllocateVirtualRegister32();
            var op1High     = transformContext.AllocateVirtualRegister32();
            var resultLow   = transformContext.AllocateVirtualRegister32();
            var resultHigh  = transformContext.AllocateVirtualRegister32();
            var resultCarry = transformContext.AllocateVirtualRegister32();

            context.SetInstruction(IRInstruction.GetLow32, op0Low, operand1);
            context.AppendInstruction(IRInstruction.GetHigh32, op0High, operand1);
            context.AppendInstruction(IRInstruction.GetLow32, op1Low, operand2);
            context.AppendInstruction(IRInstruction.GetHigh32, op1High, operand2);

            context.AppendInstruction2(IRInstruction.AddCarryOut32, resultLow, resultCarry, op0Low, op1Low);
            context.AppendInstruction(IRInstruction.AddCarryIn32, resultHigh, op0High, op1High, resultCarry);
            context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh);
        }