Example #1
0
 public static Span <long> Fwt(BitOp op, Span <long> values, bool inverses)
 {
     return(op switch {
         BitOp.Or => FwtOr(values, inverses),
         BitOp.And => FwtAnd(values, inverses),
         BitOp.Xor => FwtXor(values, inverses),
         _ => null,
     });
Example #2
0
        /// <summary>
        /// A framework for calling bitwise operation instructions.
        /// </summary>
        /// <param name="op">The op.</param>
        /// <param name="memory">The memory.</param>
        /// <param name="operation">The operation.</param>
        /// <exception cref="ArgumentNullException"><paramref name="operation"/> is null</exception>
        internal static int BitOpFunc(Opcode op, GbMemory memory, BitOp operation)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            if (op.Src != 6)
            {
                memory.R.SetR8(op.Src, operation(memory, memory.R.GetR8(op.Src)));
                return(1);
            }

            memory.WriteCycleHl(operation(memory, memory.ReadCycleHl()));
            return(3);
        }
        public override void Visit(BitOp node)
        {
            ulong left  = thread.Pop().Read().GetAsInt().Value;
            ulong right = 0;

            if (node.Operator != BitOp.Op.Not)
            {
                right = thread.Pop().Read().GetAsInt().Value;
            }

            switch (node.Operator)
            {
            case BitOp.Op.And:
                PushInteger(left & right);
                break;

            case BitOp.Op.Or:
                PushInteger(left | right);
                break;

            case BitOp.Op.NAnd:
                PushInteger(~(left & right));
                break;

            case BitOp.Op.NOr:
                PushInteger(~(left | right));
                break;

            case BitOp.Op.Not:
                PushInteger(~left);
                break;

            case BitOp.Op.XOr:
                PushInteger(left ^ right);
                break;
            }
        }
 public void GetBitsForThree()
 {
     Assert.AreEqual("0011", BitOp.GetBits(3, 4));
 }
 public void GetBitForNegThreeAtPositionThree()
 {
     Assert.AreEqual(true, BitOp.GetBitAt(2, -3)); // ...100, bit 2 is false
 }
 public void SubtractTwoPositives()
 {
     Assert.AreEqual(-9, BitOp.Subtract(2, 11));
 }
 public void GetBitForThreeAtPositionZero()
 {
     Assert.AreEqual(true, BitOp.GetBitAt(0, 3)); // 011, bit 0 is true
 }
 public void GetBitsForFifteen()
 {
     Assert.AreEqual("01111", BitOp.GetBits(15, 5));
 }
 public void GetBitsForNegEleven()
 {
     Assert.AreEqual("10100", BitOp.GetBits(-11, 5));
 }
 public void MultiplyNegativeAndAPositive()
 {
     Assert.AreEqual(-7, BitOp.Multiply(7, -1));
 }
 public void DividePositives()
 {
     Assert.AreEqual(4, BitOp.Divide(8, 2));
 }
 public void MultiplyNegatives()
 {
     Assert.AreEqual(15, BitOp.Multiply(-5, -3));
 }
 public void GetBitForThreeAtPositionOne()
 {
     Assert.AreEqual(true, BitOp.GetBitAt(1, 3)); // 011, bit 1 is true
 }
 public void MultiplyPositives()
 {
     Assert.AreEqual(32, BitOp.Multiply(4, 8));
 }
 public void SubtractPositiveLeftNegativeRight()
 {
     Assert.AreEqual(8, BitOp.Subtract(7, -1));
 }
 public void SubtractNegLeftPositiveRight()
 {
     Assert.AreEqual(-13, BitOp.Subtract(-5, 8));
 }
 public void GetBitsForBigNumber()
 {
     Assert.AreEqual("00001010000010110000110000001101", BitOp.GetBits(168496141, 32));
 }
 public void DivideNegatives()
 {
     Assert.AreEqual(5, BitOp.Divide(-15, -3));
 }
 public void GetBitsForEleven()
 {
     Assert.AreEqual("01011", BitOp.GetBits(11, 5));
 }
 public void DivideNegativeAndAPositive()
 {
     Assert.AreEqual(-7, BitOp.Divide(7, -1));
 }
 public void GetBitsForNegFive()
 {
     Assert.AreEqual("11010", BitOp.GetBits(-5, 5));
 }
 public void DivideHasRemainder()
 {
     Assert.AreEqual(3, BitOp.Divide(15, 4));
 }
 public void AddTwoPositivies()
 {
     Assert.AreEqual(14, BitOp.Add(2, 12));
 }
Example #24
0
        public static object BitOperation(object x, object y, BitOp op)
        {
            Debug.Assert(!(x is PhpReference) && !(y is PhpReference));

            PhpBytes bx, by;

            if ((bx = PhpVariable.AsBytes(x)) == null || (by = PhpVariable.AsBytes(y)) == null)
            {
                // at least one of the operands is not string of characters nor string of bytes:
                long lx = Convert.ObjectToLongInteger(x);
                long ly = Convert.ObjectToLongInteger(y);
                long result;

                switch (op)
                {
                    case BitOp.And: result = lx & ly; break;
                    case BitOp.Or: result = lx | ly; break;
                    case BitOp.Xor: result = lx ^ ly; break;
                    default:
                        throw new ArgumentOutOfRangeException("op");
                }

                // int to long overflow check
                int il = unchecked((int)result);
                if (il == result)
                    return il;

                // we need long
                return result;
            }
            else
            {
                byte[] result;
                int length = (op == BitOp.Or) ? Math.Max(bx.Length, by.Length) : Math.Min(bx.Length, by.Length);

                // chooses the resulting array allocating a new one only if necessary;
                // if x or y has been converted from string to bytes and has the max. length it can be used for
                // storing a resulting array:
                if (!ReferenceEquals(bx, x) && bx.Length == length)
                    result = bx.Data;// bx is temporary PhpBytes instance, its internal data can be reused
                else if (!ReferenceEquals(by, y) && by.Data.Length == length)
                    result = by.Data;// by is temporary PhpBytes instance, its internal data can be reused
                else
                    result = new byte[length];

                return new PhpBytes(BitOperation(result, bx.ReadonlyData, by.ReadonlyData, op));
            }
        }
 public void AddLeftNegRightPos()
 {
     Assert.AreEqual(9, BitOp.Add(-3, 12));
 }
 public void AddRightPosLeftNeg()
 {
     Assert.AreEqual(-4, BitOp.Add(4, -8));
 }
 public void GetBitForThreeAtPositionThree()
 {
     Assert.AreEqual(false, BitOp.GetBitAt(3, 3)); // 011, bit 3 is false
 }
 public void AddTwoNegatives()
 {
     Assert.AreEqual(-16, BitOp.Add(-9, -7));
 }
Example #29
0
        /// <summary>
        /// Performs specified binary operation on arrays of bytes.
        /// </summary>
        /// <param name="result">An array where to store the result. Data previously stored here will be overwritten.</param>
        /// <param name="x">The first operand.</param>
        /// <param name="y">The second operand</param>
        /// <param name="op">The operation to perform.</param>
        /// <returns>The reference to the the <paramref name="result"/> array.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="op"/> has invalid value.</exception>
        private static byte[] BitOperation(byte[]/*!*/ result, byte[]/*!*/ x, byte[]/*!*/ y, BitOp op)
        {
            int min_length = Math.Min(x.Length, y.Length);

            Debug.Assert(result != null && x != null && y != null && result.Length >= min_length);

            switch (op)
            {
                case BitOp.And:

                    for (int i = 0; i < min_length; i++)
                        result[i] = unchecked((byte)(x[i] & y[i]));

                    // remaining bytes are ignored //          
                    break;

                case BitOp.Or:

                    for (int i = 0; i < min_length; i++)
                        result[i] = unchecked((byte)(x[i] | y[i]));

                    // copies remaining bytes from longer array:
                    if (x.Length > min_length)
                    {
                        if (x != result) Buffer.BlockCopy(x, min_length, result, min_length, result.Length - min_length);
                    }
                    else
                    {
                        if (y != result) Buffer.BlockCopy(y, min_length, result, min_length, result.Length - min_length);
                    }
                    break;

                case BitOp.Xor:

                    for (int i = 0; i < min_length; i++)
                        result[i] = unchecked((byte)(x[i] ^ y[i]));

                    // remaining bytes are ignored //
                    break;

                default:
                    throw new ArgumentOutOfRangeException("op");
            }
            return result;
        }
 public void GetBitForNegThreeAtPositionOne()
 {
     Assert.AreEqual(false, BitOp.GetBitAt(1, -3)); // ...100, bit 1 is false
 }