Пример #1
0
        protected Operand MoveConstantToRegisterOrImmediate(Context context, Operand operand, bool allowImmediate)
        {
            if (operand.IsVirtualRegister || operand.IsCPURegister)
            {
                return(operand);
            }

            if (operand.IsResolvedConstant)
            {
                if (ARMHelper.CalculateRotatedImmediateValue(operand.ConstantUnsigned32, out uint immediate, out byte _, out byte _))
                {
                    var constant = CreateConstant32(immediate);

                    if (allowImmediate)
                    {
                        return(constant);
                    }

                    var before = context.InsertBefore();
                    var v1     = AllocateVirtualRegister32();
                    before.SetInstruction(ARMv8A32.Mov, v1, constant);

                    return(v1);
                }

                if (ARMHelper.CalculateRotatedImmediateValue(~operand.ConstantUnsigned32, out uint immediate2, out byte _, out byte _))
                {
                    var constant = CreateConstant32(immediate);

                    var before = context.InsertBefore();
                    var v1     = AllocateVirtualRegister32();
                    before.SetInstruction(ARMv8A32.Mov, v1, constant);

                    return(v1);
                }

                {
                    var before = context.InsertBefore();

                    var v1 = AllocateVirtualRegister32();
                    before.SetInstruction(ARMv8A32.Movw, v1, CreateConstant32(operand.ConstantUnsigned32 & 0xFFFF));
                    before.AppendInstruction(ARMv8A32.Movt, v1, v1, CreateConstant32(operand.ConstantUnsigned32 >> 16));

                    return(v1);
                }
            }
            else if (operand.IsUnresolvedConstant)
            {
                var before = context.InsertBefore();
                var v1     = AllocateVirtualRegister32();
                before.SetInstruction(ARMv8A32.Movw, v1, operand);
                before.AppendInstruction(ARMv8A32.Movt, v1, v1, operand);

                return(v1);
            }

            throw new CompilerException("Error at {context} in {Method}");
        }
Пример #2
0
        protected Operand MoveConstantToRegister(Context context, Operand operand)
        {
            if (operand.IsVirtualRegister || operand.IsCPURegister)
            {
                return(operand);
            }

            if (operand.IsResolvedConstant)
            {
                var v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);

                var before = context.InsertBefore();

                if (operand.ConstantUnsignedInteger <= 0xFFFF)
                {
                    before.SetInstruction(ARMv8A32.MovImm, v1, operand);

                    return(v1);
                }

                if (ARMHelper.CalculateRotatedImmediateValue(operand.ConstantUnsignedInteger, out uint immediate, out _, out _))
                {
                    before.SetInstruction(ARMv8A32.MovImmShift, v1, CreateConstant(immediate));

                    return(v1);
                }

                if (ARMHelper.CalculateRotatedImmediateValue(~operand.ConstantUnsignedInteger, out uint immediate2, out _, out _))
                {
                    before.SetInstruction(ARMv8A32.MvnImmShift, v1, CreateConstant(immediate2));

                    return(v1);
                }

                before.SetInstruction(ARMv8A32.MovImm, v1, CreateConstant(operand.ConstantUnsignedInteger & 0xFFFF));
                before.AppendInstruction(ARMv8A32.MovtImm, v1, CreateConstant(operand.ConstantUnsignedInteger >> 16));

                return(v1);
            }
            else if (operand.IsUnresolvedConstant)
            {
                var v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);

                var before = context.InsertBefore();

                before.SetInstruction(ARMv8A32.MovImm, v1, operand);
                before.AppendInstruction(ARMv8A32.MovtImm, v1, v1, operand);

                return(v1);
            }

            throw new CompilerException("Error at {context} in {Method}");
        }
Пример #3
0
        protected Operand CreateRotatedImmediateOperand(Context context, Operand operand)
        {
            if (operand.IsVirtualRegister || operand.IsCPURegister)
            {
                return(operand);
            }

            if (operand.IsResolvedConstant)
            {
                if (ARMHelper.CalculateRotatedImmediateValue(operand.ConstantUnsignedInteger, out uint immediate, out _, out _))
                {
                    if (operand.ConstantUnsignedLongInteger == immediate)
                    {
                        return(operand);
                    }

                    return(CreateConstant(immediate));
                }
            }

            return(MoveConstantToRegister(context, operand));
        }