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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }