private static void EmitMull(ArmEmitterContext context, MullFlags flags) { OpCodeMul op = (OpCodeMul)context.CurrOp; Operand GetExtendedRegister32(int index) { Operand value = GetIntOrZR(context, index); if ((flags & MullFlags.Signed) != 0) { return(context.SignExtend32(value.Type, value)); } else { return(context.ZeroExtend32(value.Type, value)); } } Operand a = GetIntOrZR(context, op.Ra); Operand n = GetExtendedRegister32(op.Rn); Operand m = GetExtendedRegister32(op.Rm); Operand res = context.Multiply(n, m); res = (flags & MullFlags.Add) != 0 ? context.Add(a, res) : context.Subtract(a, res); SetIntOrZR(context, op.Rd, res); }
private static void EmitSmmul(ArmEmitterContext context, MullFlags flags) { OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; Operand n = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rn)); Operand m = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rm)); Operand res = context.Multiply(n, m); if (flags.HasFlag(MullFlags.Add) && op.Ra != 0xf) { res = context.Add(context.ShiftLeft(context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Ra)), Const(32)), res); } else if (flags.HasFlag(MullFlags.Subtract)) { res = context.Subtract(context.ShiftLeft(context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Ra)), Const(32)), res); } if (op.R) { res = context.Add(res, Const(0x80000000L)); } Operand hi = context.ConvertI64ToI32(context.ShiftRightSI(res, Const(32))); EmitGenericAluStoreA32(context, op.Rd, false, hi); }