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