Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }