1 /* 2 * Copyright 2003-2007 Marcus Overhagen 3 * Copyright 2007 Haiku Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 #include "ByteSwap.h" 7 #include "MixerDebug.h" 8 9 #include <ByteOrder.h> 10 #include <MediaDefs.h> 11 12 static void swap_float(void *buffer, size_t bytecount); 13 static void swap_int32(void *buffer, size_t bytecount); 14 static void swap_int16(void *buffer, size_t bytecount); 15 static void do_nothing(void *buffer, size_t bytecount); 16 17 ByteSwap::ByteSwap(uint32 format) 18 { 19 switch (format) { 20 case media_raw_audio_format::B_AUDIO_FLOAT: 21 fFunc = &swap_float; 22 break; 23 case media_raw_audio_format::B_AUDIO_INT: 24 fFunc = &swap_int32; 25 break; 26 case media_raw_audio_format::B_AUDIO_SHORT: 27 fFunc = &swap_int16; 28 break; 29 default: 30 fFunc = &do_nothing; 31 break; 32 } 33 } 34 35 ByteSwap::~ByteSwap() 36 { 37 } 38 39 void 40 do_nothing(void *buffer, size_t bytecount) 41 { 42 } 43 44 #if __INTEL__ 45 46 // optimized for IA32 platform 47 48 void 49 swap_float(void *buffer, size_t bytecount) 50 { 51 // XXX Should be optimized 52 swap_data(B_FLOAT_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 53 } 54 55 void 56 swap_int32(void *buffer, size_t bytecount) 57 { 58 // XXX Should be optimized 59 swap_data(B_INT32_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 60 } 61 62 void 63 swap_int16(void *buffer, size_t bytecount) 64 { 65 // GCC FAQ: To write an asm which modifies an input operand but does 66 // not output anything usable, specify that operand as an 67 // output operand outputting to an unused dummy variable. 68 uint32 dummy1; 69 uint32 dummy2; 70 // GCC is way too smart and will remove the complete asm statement 71 // if we do not specify it as __volatile__. Don't remove that! 72 __asm__ __volatile__ ( 73 "pushl %%ebx \n\t" 74 "movl %%eax, %%ebx \n\t" 75 "movl %%edx, %%eax \n\t" 76 "andl $0xFFFFFFE0,%%eax \n\t" 77 "pushl %%eax \n\t" 78 ".L_swap_loop: \n\t" 79 "rolw $8,-32(%%ebx,%%eax) \n\t" 80 "rolw $8,-30(%%ebx,%%eax) \n\t" 81 "rolw $8,-28(%%ebx,%%eax) \n\t" 82 "rolw $8,-26(%%ebx,%%eax) \n\t" 83 "rolw $8,-24(%%ebx,%%eax) \n\t" 84 "rolw $8,-22(%%ebx,%%eax) \n\t" 85 "rolw $8,-20(%%ebx,%%eax) \n\t" 86 "rolw $8,-18(%%ebx,%%eax) \n\t" 87 "rolw $8,-16(%%ebx,%%eax) \n\t" 88 "rolw $8,-14(%%ebx,%%eax) \n\t" 89 "rolw $8,-12(%%ebx,%%eax) \n\t" 90 "rolw $8,-10(%%ebx,%%eax) \n\t" 91 "rolw $8,-8(%%ebx,%%eax) \n\t" 92 "rolw $8,-6(%%ebx,%%eax) \n\t" 93 "rolw $8,-4(%%ebx,%%eax) \n\t" 94 "rolw $8,-2(%%ebx,%%eax) \n\t" 95 "subl $32,%%eax \n\t" 96 "jnz .L_swap_loop \n\t" 97 "popl %%eax \n\t" 98 "addl %%eax,%%ebx \n\t" 99 "andl $0x1F,%%edx \n\t" 100 "jz .L_swap_end \n\t" 101 "addl %%ebx, %%edx \n\t" 102 ".L_swap_loop_2: \n\t" 103 "rolw $8,(%%ebx) \n\t" 104 "addl $2,%%ebx \n\t" 105 "cmpl %%edx,%%ebx \n\t" 106 "jne .L_swap_loop_2 \n\t" 107 ".L_swap_end: \n\t" 108 "popl %%ebx \n\t" 109 : "=a" (dummy1), "=d" (dummy2) 110 : "d" (bytecount), "a" (buffer) 111 : "cc", "memory"); 112 } 113 114 #else 115 116 // non optimized default versions, do not remove 117 118 void 119 swap_float(void *buffer, size_t bytecount) 120 { 121 swap_data(B_FLOAT_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 122 } 123 124 void 125 swap_int32(void *buffer, size_t bytecount) 126 { 127 swap_data(B_INT32_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 128 } 129 130 void 131 swap_int16(void *buffer, size_t bytecount) 132 { 133 swap_data(B_INT16_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 134 } 135 #endif 136