1
0
Fork 0
forked from len0rd/rockbox

Enable strict aliasing optimizations for codecs on gcc versions >= 4.0, fix alising violations that this uncovered, gives small speedups for most codecs, FS#10801

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23784 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Nils Wallménius 2009-11-29 18:11:49 +00:00
parent 685ca2672e
commit 13f08d70fd
5 changed files with 38 additions and 33 deletions

View file

@ -41,8 +41,8 @@ include $(APPSDIR)/codecs/librm/librm.make
include $(APPSDIR)/codecs/libatrac/libatrac.make include $(APPSDIR)/codecs/libatrac/libatrac.make
# compile flags for codecs # compile flags for codecs
CODECFLAGS = $(CFLAGS) -I$(APPSDIR)/codecs -I$(APPSDIR)/codecs/lib \ CODECFLAGS = $(filter-out -fno-strict-aliasing,$(CFLAGS)) -fstrict-aliasing \
-DCODEC -I$(APPSDIR)/codecs -I$(APPSDIR)/codecs/lib -DCODEC
ifndef SIMVER ifndef SIMVER
CODEC_LDS := $(APPSDIR)/plugins/plugin.lds # codecs and plugins use same file CODEC_LDS := $(APPSDIR)/plugins/plugin.lds # codecs and plugins use same file

View file

@ -137,16 +137,15 @@ static inline void set_le16( void* p, unsigned n )
} }
#define GET_LE16( addr ) get_le16( addr ) #define GET_LE16( addr ) get_le16( addr )
#define GET_LE16A( addr ) get_le16( addr )
#define SET_LE16( addr, data ) set_le16( addr, data ) #define SET_LE16( addr, data ) set_le16( addr, data )
#define INT16A( addr ) (*(uint16_t*) (addr)) #define INT16A( addr ) (*(uint16_t*) (addr))
#define INT16SA( addr ) (*(int16_t*) (addr)) #define INT16SA( addr ) (*(int16_t*) (addr))
#ifdef ROCKBOX_LITTLE_ENDIAN #ifdef ROCKBOX_LITTLE_ENDIAN
#define GET_LE16A( addr ) (*(uint16_t*) (addr))
#define GET_LE16SA( addr ) (*( int16_t*) (addr)) #define GET_LE16SA( addr ) (*( int16_t*) (addr))
#define SET_LE16A( addr, data ) (void) (*(uint16_t*) (addr) = (data)) #define SET_LE16A( addr, data ) (void) (*(uint16_t*) (addr) = (data))
#else #else
#define GET_LE16A( addr ) get_le16 ( addr )
#define GET_LE16SA( addr ) get_le16s( addr ) #define GET_LE16SA( addr ) get_le16s( addr )
#define SET_LE16A( addr, data ) set_le16 ( addr, data ) #define SET_LE16A( addr, data ) set_le16 ( addr, data )
#endif #endif
@ -166,13 +165,22 @@ struct cpu_regs_t
uint8_t sp; uint8_t sp;
}; };
struct src_dir
{
uint16_t start;
uint16_t loop;
};
struct cpu_ram_t struct cpu_ram_t
{ {
union { union {
uint8_t padding1 [0x100]; uint8_t padding1 [0x100];
uint16_t align; uint16_t align;
} padding1 [1]; } padding1 [1];
union {
uint8_t ram [0x10000]; uint8_t ram [0x10000];
struct src_dir sd [0x10000/sizeof(struct src_dir)];
};
uint8_t padding2 [0x100]; uint8_t padding2 [0x100];
}; };
@ -339,12 +347,6 @@ struct Spc_Dsp
#endif #endif
}; };
struct src_dir
{
char start [2];
char loop [2];
};
void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) ICODE_ATTR; void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) ICODE_ATTR;
void DSP_reset( struct Spc_Dsp* this ); void DSP_reset( struct Spc_Dsp* this );

View file

@ -77,8 +77,9 @@ static void decode_brr( struct Spc_Dsp* this, unsigned start_addr,
/* setup same variables as where decode_brr() is called from */ /* setup same variables as where decode_brr() is called from */
#undef RAM #undef RAM
#define RAM ram.ram #define RAM ram.ram
struct src_dir const* const sd = struct src_dir const* const sd =
(struct src_dir*) &RAM [this->r.g.wave_page * 0x100]; &ram.sd[this->r.g.wave_page * 0x100/sizeof(struct src_dir)];
struct cache_entry_t* const wave_entry = struct cache_entry_t* const wave_entry =
&this->wave_entry [raw_voice->waveform]; &this->wave_entry [raw_voice->waveform];
@ -106,7 +107,7 @@ static void decode_brr( struct Spc_Dsp* this, unsigned start_addr,
wave_entry->start_addr = start_addr; wave_entry->start_addr = start_addr;
uint8_t const* const loop_ptr = uint8_t const* const loop_ptr =
RAM + GET_LE16A( sd [raw_voice->waveform].loop ); RAM + letoh16(sd[raw_voice->waveform].loop);
short* loop_start = 0; short* loop_start = 0;
short* out = BRRcache + start_addr * 2; short* out = BRRcache + start_addr * 2;
@ -251,7 +252,7 @@ static void key_on(struct Spc_Dsp* const this, struct voice_t* const voice,
voice->envx = 0; voice->envx = 0;
voice->env_mode = state_attack; voice->env_mode = state_attack;
voice->env_timer = env_rate_init; /* TODO: inaccurate? */ voice->env_timer = env_rate_init; /* TODO: inaccurate? */
unsigned start_addr = GET_LE16A(sd [raw_voice->waveform].start); unsigned start_addr = letoh16(sd[raw_voice->waveform].start);
#if !SPC_BRRCACHE #if !SPC_BRRCACHE
{ {
voice->addr = RAM + start_addr; voice->addr = RAM + start_addr;
@ -333,7 +334,7 @@ void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
} }
struct src_dir const* const sd = struct src_dir const* const sd =
(struct src_dir*) &RAM [this->r.g.wave_page * 0x100]; &ram.sd[this->r.g.wave_page * 0x100/sizeof(struct src_dir)];
#ifdef ROCKBOX_BIG_ENDIAN #ifdef ROCKBOX_BIG_ENDIAN
/* Convert endiannesses before entering loops - these /* Convert endiannesses before entering loops - these
@ -358,7 +359,7 @@ void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
const int echo_start = this->r.g.echo_page * 0x100; const int echo_start = this->r.g.echo_page * 0x100;
#endif /* CPU_COLDFIRE */ #endif /* CPU_COLDFIRE */
#else #else
#define VOICE_RATE(x) (INT16A(raw_voice->rate) & 0x3FFF) #define VOICE_RATE(x) (GET_LE16(raw_voice->rate) & 0x3FFF)
#define IF_RBE(...) #define IF_RBE(...)
#endif /* ROCKBOX_BIG_ENDIAN */ #endif /* ROCKBOX_BIG_ENDIAN */
@ -590,7 +591,7 @@ void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
/* action based on previous block's header */ /* action based on previous block's header */
if ( voice->block_header & 1 ) if ( voice->block_header & 1 )
{ {
addr = RAM + GET_LE16A( sd [raw_voice->waveform].loop ); addr = RAM + letoh16(sd[raw_voice->waveform].loop);
this->r.g.wave_ended |= vbit; this->r.g.wave_ended |= vbit;
if ( !(voice->block_header & 2) ) /* 1% of the time */ if ( !(voice->block_header & 2) ) /* 1% of the time */
{ {

View file

@ -1097,16 +1097,16 @@ static inline int clip(int i)
else return(i); else return(i);
} }
STATICIRAM void synthrender(void *renderbuffer, int samplecount) ICODE_ATTR; STATICIRAM void synthrender(int32_t *renderbuffer, int samplecount) ICODE_ATTR;
void synthrender(void *renderbuffer, int samplecount) void synthrender(int32_t *renderbuffer, int samplecount)
{ {
/* 125bpm equals to 50Hz (= 0.02s) /* 125bpm equals to 50Hz (= 0.02s)
* => one tick = mixingrate/50, * => one tick = mixingrate/50,
* samples passing in one tick: * samples passing in one tick:
* mixingrate/(bpm/2.5) = 2.5*mixingrate/bpm */ * mixingrate/(bpm/2.5) = 2.5*mixingrate/bpm */
int *p_left = (int *) renderbuffer; /* int in rockbox */ int32_t *p_left = renderbuffer; /* int in rockbox */
int *p_right = p_left+1; int32_t *p_right = p_left+1;
signed short s; signed short s;
int qf_distance, qf_distance2; int qf_distance, qf_distance2;

View file

@ -2090,33 +2090,35 @@ STATICIRAM void to_mono_mm(void)
/* |llllllllllllllll|rrrrrrrrrrrrrrrr| => /* |llllllllllllllll|rrrrrrrrrrrrrrrr| =>
* |mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm| * |mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm|
*/ */
uint32_t *samp = (uint32_t *)&mfbuf[2*512]; uint16_t *samp = &mfbuf[2*512];
uint32_t *samp_end = samp + samp_per_frame; uint16_t *samp_end = samp + 2*samp_per_frame;
inline void to_mono(uint32_t **samp) inline void to_mono(uint16_t **samp)
{ {
int32_t lr = **samp; int16_t l = **samp;
int16_t r = **(samp+1);
int32_t m; int32_t m;
switch(cfg.rec_mono_mode) switch(cfg.rec_mono_mode)
{ {
case 1: case 1:
/* mono = L */ /* mono = L */
m = lr >> 16; m = l;
break; break;
case 2: case 2:
/* mono = R */ /* mono = R */
m = (int16_t)lr; m = r;
break; break;
case 0: case 0:
default: default:
/* mono = (L+R)/2 */ /* mono = (L+R)/2 */
m = (int16_t)lr + (lr >> 16) + err; m = r + r + err;
err = m & 1; err = m & 1;
m >>= 1; m >>= 1;
break; break;
} }
*(*samp)++ = (m << 16) | (uint16_t)m; *(*samp)++ = (uint16_t)m;
*(*samp)++ = (uint16_t)m;
} /* to_mono */ } /* to_mono */
do do