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