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 16static void swap_float(void *buffer, size_t bytecount); 17static void swap_int32(void *buffer, size_t bytecount); 18static void swap_int16(void *buffer, size_t bytecount); 19static void do_nothing(void *buffer, size_t bytecount); 20 21 22ByteSwap::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 41ByteSwap::~ByteSwap() 42{ 43} 44 45 46void 47do_nothing(void *buffer, size_t bytecount) 48{ 49} 50 51 52#if __i386__ 53// #pragma mark - optimized for IA32 platform 54 55 56void 57swap_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 64void 65swap_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 72void 73swap_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 // !__i386__ 126// #pragma mark - generic versions 127 128 129void 130swap_float(void *buffer, size_t bytecount) 131{ 132 swap_data(B_FLOAT_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 133} 134 135 136void 137swap_int32(void *buffer, size_t bytecount) 138{ 139 swap_data(B_INT32_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 140} 141 142 143void 144swap_int16(void *buffer, size_t bytecount) 145{ 146 swap_data(B_INT16_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 147} 148 149 150#endif 151