Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

ByteSwap.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file ByteSwap.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032 
00033         @version        Initial version, October 2004      
00034         @author         Kris
00035 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.base.ByteSwap;
00040 
00041 /*******************************************************************************
00042 
00043         Reverse byte order for specific datum sizes. Note that the
00044         byte-swap approach avoids alignment issues, so is probably
00045         faster overall than a traditional 'shift' implementation.
00046 
00047 *******************************************************************************/
00048 
00049 struct ByteSwap
00050 {       
00051         version (DigitalMars) version (X86) version (D_InlineAsm)
00052         {
00053         /***********************************************************************
00054         
00055         ***********************************************************************/
00056 
00057         final static void swap16 (void *dst, uint count)
00058         {
00059                 asm {
00060                     mov  ESI, dword ptr [dst];
00061                     mov  ECX, dword ptr [count];
00062                     test ECX, ECX;
00063                     jmp  test;
00064         loop:
00065                     mov  AL, byte ptr [ESI+0];
00066                     xchg AL, byte ptr [ESI+1];
00067                     mov  byte ptr [ESI+0], AL;
00068                     add  ESI, 2;
00069                     sub  ECX, 2;
00070         test:
00071                     jne  loop;
00072                     }
00073         }
00074 
00075         /***********************************************************************
00076         
00077         ***********************************************************************/
00078 
00079         final static void swap32 (void *dst, uint count)
00080         {
00081                 asm {
00082                     mov  ESI, dword ptr [dst];
00083                     mov  ECX, dword ptr [count];
00084                     test ECX, ECX;
00085                     jmp  test;
00086         loop:
00087                     mov  AL, byte ptr [ESI+0];
00088                     xchg AL, byte ptr [ESI+3];
00089                     mov  byte ptr [ESI+0], AL;
00090                     mov  AL, byte ptr [ESI+1];
00091                     xchg AL, byte ptr [ESI+2];
00092                     mov  byte ptr [ESI+1], AL;
00093                     add  ESI, 4;
00094                     sub  ECX, 4;
00095         test:
00096                     jne  loop;
00097                     }
00098         }
00099 
00100         /***********************************************************************
00101         
00102         ***********************************************************************/
00103 
00104         final static void swap64 (void *dst, uint count)
00105         {
00106                 asm {
00107                     mov  ESI, dword ptr [dst];
00108                     mov  ECX, dword ptr [count];
00109                     test ECX, ECX;
00110                     jmp  test;
00111         loop:
00112                     mov  AL, byte ptr [ESI+0];
00113                     xchg AL, byte ptr [ESI+7];
00114                     mov  byte ptr [ESI+0], AL;
00115                     mov  AL, byte ptr [ESI+1];
00116                     xchg AL, byte ptr [ESI+6];
00117                     mov  byte ptr [ESI+1], AL;
00118                     mov  AL, byte ptr [ESI+2];
00119                     xchg AL, byte ptr [ESI+5];
00120                     mov  byte ptr [ESI+2], AL;
00121                     mov  AL, byte ptr [ESI+3];
00122                     xchg AL, byte ptr [ESI+4];
00123                     mov  byte ptr [ESI+3], AL;
00124                     add  ESI, 8;
00125                     sub  ECX, 8;
00126         test:
00127                     jne  loop;
00128                     }
00129         }
00130 
00131         /***********************************************************************
00132         
00133         ***********************************************************************/
00134 
00135         final static void swap80 (void *dst, uint count)
00136         {
00137                 asm {
00138                     mov  ESI, dword ptr [dst];
00139                     mov  ECX, dword ptr [count];
00140                     test ECX, ECX;
00141                     jmp  test;
00142         loop:
00143                     mov  AL, byte ptr [ESI+0];
00144                     xchg AL, byte ptr [ESI+9];
00145                     mov  byte ptr [ESI+0], AL;
00146                     mov  AL, byte ptr [ESI+1];
00147                     xchg AL, byte ptr [ESI+8];
00148                     mov  byte ptr [ESI+1], AL;
00149                     mov  AL, byte ptr [ESI+2];
00150                     xchg AL, byte ptr [ESI+7];
00151                     mov  byte ptr [ESI+2], AL;
00152                     mov  AL, byte ptr [ESI+3];
00153                     xchg AL, byte ptr [ESI+6];
00154                     mov  byte ptr [ESI+3], AL;
00155                     mov  AL, byte ptr [ESI+4];
00156                     xchg AL, byte ptr [ESI+5];
00157                     mov  byte ptr [ESI+4], AL;
00158                     add  ESI, 10;
00159                     sub  ECX, 10;
00160         test:
00161                     jne  loop;
00162                     }
00163         }
00164         }
00165 
00166      else
00167 
00168         {
00169         /***********************************************************************
00170         
00171         ***********************************************************************/
00172 
00173         final static void swap16 (void *dst, uint count)
00174         {
00175                 ubyte* p = cast(ubyte*) dst;
00176                 while (count)
00177                       {
00178                       byte b = p[0];
00179                       p[0] = p[1];
00180                       p[1] = b;
00181 
00182                       p += short.sizeof;
00183                       count -= short.sizeof;
00184                       }
00185         }
00186 
00187         /***********************************************************************
00188         
00189         ***********************************************************************/
00190 
00191         final static void swap32 (void *dst, uint count)
00192         {
00193                 ubyte* p = cast(ubyte*) dst;
00194                 while (count)
00195                       {
00196                       ubyte b = p[0];
00197                       p[0] = p[3];
00198                       p[3] = b;
00199 
00200                       b = p[1];
00201                       p[1] = p[2];
00202                       p[2] = b;
00203 
00204                       p += int.sizeof;
00205                       count -= int.sizeof;
00206                       }
00207         }
00208 
00209         /***********************************************************************
00210         
00211         ***********************************************************************/
00212 
00213         final static void swap64 (void *dst, uint count)
00214         {
00215                 ubyte* p = cast(ubyte*) dst;
00216                 while (count)
00217                       {
00218                       ubyte b = p[0];
00219                       p[0] = p[7];
00220                       p[7] = b;
00221 
00222                       b = p[1];
00223                       p[1] = p[6];
00224                       p[6] = b;
00225         
00226                       b = p[2];
00227                       p[2] = p[5];
00228                       p[5] = b;
00229         
00230                       b = p[3];
00231                       p[3] = p[4];
00232                       p[3] = b;
00233 
00234                       p += long.sizeof;
00235                       count -= long.sizeof;
00236                       }
00237         }
00238 
00239         /***********************************************************************
00240         
00241         ***********************************************************************/
00242 
00243         final static void swap80 (void *dst, uint count)
00244         {
00245                 ubyte* p = cast(ubyte*) dst;
00246                 while (count)
00247                       {
00248                       ubyte b = p[0];
00249                       p[0] = p[9];
00250                       p[9] = b;
00251 
00252                       b = p[1];
00253                       p[1] = p[8];
00254                       p[8] = b;
00255 
00256                       b = p[2];
00257                       p[2] = p[7];
00258                       p[7] = b;
00259         
00260                       b = p[3];
00261                       p[3] = p[6];
00262                       p[6] = b;
00263         
00264                       b = p[4];
00265                       p[4] = p[5];
00266                       p[5] = b;
00267 
00268                       p += real.sizeof;
00269                       count -= real.sizeof;
00270                       }
00271         }
00272 
00273         }
00274 }

Generated on Tue Jan 25 21:18:20 2005 for Mango by doxygen 1.3.6