Exemplo n.º 1
0
        private static void EmitHsub8(ArmEmitterContext context, bool unsigned)
        {
            OpCode32AluReg op = (OpCode32AluReg)context.CurrOp;

            Operand m = GetIntA32(context, op.Rm);
            Operand n = GetIntA32(context, op.Rn);
            Operand left, right, carry, res;

            // This relies on the equality x-y == (x^y) - (((x^y)&y) << 1).
            // Note that x^y always contains the LSB of the result.
            // Since we want to calculate (x+y)/2, we can instead calculate ((x^y)>>1) - ((x^y)&y).

            carry = context.BitwiseExclusiveOr(m, n);
            left  = context.ShiftRightUI(carry, Const(1));
            right = context.BitwiseAnd(carry, m);

            // We must now perform a partitioned subtraction.
            // We can do this because minuend contains 7 bit fields.
            // We use the extra bit in minuend as a bit to borrow from; we set this bit.
            // We invert this bit at the end as this tells us if that bit was borrowed from.

            res = context.BitwiseOr(left, Const(0x80808080));
            res = context.Subtract(res, right);
            res = context.BitwiseExclusiveOr(res, Const(0x80808080));

            if (!unsigned)
            {
                // We then sign extend the result into this bit.
                carry = context.BitwiseAnd(carry, Const(0x80808080));
                res   = context.BitwiseExclusiveOr(res, carry);
            }

            SetIntA32(context, op.Rd, res);
        }
Exemplo n.º 2
0
        private static void EmitHadd8(ArmEmitterContext context, bool unsigned)
        {
            OpCode32AluReg op = (OpCode32AluReg)context.CurrOp;

            Operand m = GetIntA32(context, op.Rm);
            Operand n = GetIntA32(context, op.Rn);

            Operand xor, res, carry;

            // This relies on the equality x+y == ((x&y) << 1) + (x^y).
            // Note that x^y always contains the LSB of the result.
            // Since we want to calculate (x+y)/2, we can instead calculate (x&y) + ((x^y)>>1).
            // We mask by 0x7F to remove the LSB so that it doesn't leak into the field below.

            res   = context.BitwiseAnd(m, n);
            carry = context.BitwiseExclusiveOr(m, n);
            xor   = context.ShiftRightUI(carry, Const(1));
            xor   = context.BitwiseAnd(xor, Const(0x7F7F7F7Fu));
            res   = context.Add(res, xor);

            if (!unsigned)
            {
                // Propagates the sign bit from (x^y)>>1 upwards by one.
                carry = context.BitwiseAnd(carry, Const(0x80808080u));
                res   = context.BitwiseExclusiveOr(res, carry);
            }

            SetIntA32(context, op.Rd, res);
        }
Exemplo n.º 3
0
        public static void Uhadd8(ArmEmitterContext context)
        {
            OpCode32AluReg op = (OpCode32AluReg)context.CurrOp;

            Operand m = GetIntA32(context, op.Rm);
            Operand n = GetIntA32(context, op.Rn);

            Operand xor, res;

            res = context.BitwiseAnd(m, n);
            xor = context.BitwiseExclusiveOr(m, n);
            xor = context.ShiftRightUI(xor, Const(1));
            xor = context.BitwiseAnd(xor, Const(0x7F7F7F7Fu));
            res = context.Add(res, xor);

            SetIntA32(context, op.Rd, res);
        }