1 /** 2 * This module contains a collection of bit-level operations. 3 * 4 * Copyright: 5 * Public Domain 6 * Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH. 7 * All rights reserved. 8 * 9 * License: 10 * Tango Dual License: 3-Clause BSD License / Academic Free License v3.0. 11 * See LICENSE_TANGO.txt for details. 12 * 13 * Authors: Sean Kelly 14 * 15 */ 16 module ocean.core.BitManip; 17 18 public import core.bitop; 19 20 version (unittest) import ocean.core.Test; 21 22 /** 23 * Reverses the order of bits in a 64-bit integer. 24 */ 25 ulong bitswap ( ulong x ) 26 { 27 version( D_InlineAsm_X86_64 ) 28 { 29 asm 30 { 31 // Author: Tiago Gasiba. 32 mov RAX, x; 33 mov RDX, RAX; 34 shr RAX, 1; 35 mov RCX, 0x5555_5555_5555_5555L; 36 and RDX, RCX; 37 and RAX, RCX; 38 shl RDX, 1; 39 or RAX, RDX; 40 41 mov RDX, RAX; 42 shr RAX, 2; 43 mov RCX, 0x3333_3333_3333_3333L; 44 and RDX, RCX; 45 and RAX, RCX; 46 shl RDX, 2; 47 or RAX, RDX; 48 49 mov RDX, RAX; 50 shr RAX, 4; 51 mov RCX, 0x0f0f_0f0f_0f0f_0f0fL; 52 and RDX, RCX; 53 and RAX, RCX; 54 shl RDX, 4; 55 or RAX, RDX; 56 bswap RAX; 57 } 58 } 59 else 60 { 61 // swap odd and even bits 62 x = ((x >> 1) & 0x5555_5555_5555_5555L) | ((x & 0x5555_5555_5555_5555L) << 1); 63 // swap consecutive pairs 64 x = ((x >> 2) & 0x3333_3333_3333_3333L) | ((x & 0x3333_3333_3333_3333L) << 2); 65 // swap nibbles 66 x = ((x >> 4) & 0x0f0f_0f0f_0f0f_0f0fL) | ((x & 0x0f0f_0f0f_0f0f_0f0fL) << 4); 67 // swap bytes 68 x = ((x >> 8) & 0x00FF_00FF_00FF_00FFL) | ((x & 0x00FF_00FF_00FF_00FFL) << 8); 69 // swap shorts 70 x = ((x >> 16) & 0x0000_FFFF_0000_FFFFL) | ((x & 0x0000_FFFF_0000_FFFFL) << 16); 71 // swap ints 72 x = ( x >> 32 ) | ( x << 32); 73 return x; 74 } 75 } 76 77 unittest 78 { 79 test( bitswap( 0b1000000000000000000000010000000000000000100000000000000000000001 ) 80 == 0b1000000000000000000000010000000000000000100000000000000000000001 ); 81 test( bitswap( 0b1110000000000000000000010000000000000000100000000000000000000001 ) 82 == 0b1000000000000000000000010000000000000000100000000000000000000111 ); 83 }