From 46507d29b4bc0f4fe491aadae8d3a474be7cec39 Mon Sep 17 00:00:00 2001 From: Andree Buschmann Date: Sun, 15 May 2011 16:08:50 +0000 Subject: FS#12113: Optimize IRAM configuration for SPC. Performance increases by 5-6% on PP5022, PP5024 and S5L870x. No change of performance on Coldfire, PP5002 and PP5020. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29887 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libspc/spc_codec.h | 64 +++++++++++++++++++++++++++--------------- apps/codecs/libspc/spc_cpu.c | 2 +- apps/codecs/libspc/spc_dsp.c | 11 ++++---- apps/codecs/libspc/spc_emu.c | 2 +- apps/codecs/spc.c | 2 +- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/apps/codecs/libspc/spc_codec.h b/apps/codecs/libspc/spc_codec.h index f4f69dd758..391540cb19 100644 --- a/apps/codecs/libspc/spc_codec.h +++ b/apps/codecs/libspc/spc_codec.h @@ -89,20 +89,41 @@ #define SPC_NOECHO 1 #endif -#ifdef CPU_ARM +#if (CONFIG_CPU == MCF5250) +#define IBSS_ATTR_SPC IBSS_ATTR +#define ICODE_ATTR_SPC ICODE_ATTR +#define ICONST_ATTR_SPC ICONST_ATTR +/* Not enough IRAM available to move further data to it. */ +#define IBSS_ATTR_SPC_LARGE_IRAM + +#elif (CONFIG_CPU == PP5020) +/* spc is slower on PP5020 when moving data to IRAM. */ +#define IBSS_ATTR_SPC +#define ICODE_ATTR_SPC +#define ICONST_ATTR_SPC +/* Not enough IRAM available to move further data to it. */ +#define IBSS_ATTR_SPC_LARGE_IRAM + +#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) +#define IBSS_ATTR_SPC IBSS_ATTR +#define ICODE_ATTR_SPC ICODE_ATTR +#define ICONST_ATTR_SPC ICONST_ATTR +/* Not enough IRAM available to move further data to it. */ +#define IBSS_ATTR_SPC_LARGE_IRAM + +#elif defined(CPU_S5L870X) +#define IBSS_ATTR_SPC IBSS_ATTR +#define ICODE_ATTR_SPC ICODE_ATTR +#define ICONST_ATTR_SPC ICONST_ATTR +/* Very large IRAM. Move even more data to it. */ +#define IBSS_ATTR_SPC_LARGE_IRAM IBSS_ATTR -#if CONFIG_CPU != PP5002 - #undef ICODE_ATTR - #define ICODE_ATTR - - #undef IDATA_ATTR - #define IDATA_ATTR - - #undef ICONST_ATTR - #define ICONST_ATTR - - #undef IBSS_ATTR - #define IBSS_ATTR +#else +#define IBSS_ATTR_SPC IBSS_ATTR +#define ICODE_ATTR_SPC ICODE_ATTR +#define ICONST_ATTR_SPC ICONST_ATTR +/* Not enough IRAM available to move further data to it. */ +#define IBSS_ATTR_SPC_LARGE_IRAM #endif #if SPC_DUAL_CORE @@ -111,7 +132,6 @@ #undef SHAREDDATA_ATTR #define SHAREDDATA_ATTR __attribute__((section(".idata"))) #endif -#endif /* Samples per channel per iteration */ #if defined(CPU_PP) && NUM_CORES == 1 @@ -192,7 +212,7 @@ struct cpu_ram_t #define RAM ram.ram extern struct cpu_ram_t ram; -long CPU_run( THIS, long start_time ) ICODE_ATTR; +long CPU_run( THIS, long start_time ) ICODE_ATTR_SPC; void CPU_Init( THIS ); /* The DSP portion (awe!) */ @@ -375,7 +395,7 @@ struct Spc_Dsp #endif }; -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_SPC; void DSP_reset( struct Spc_Dsp* this ); static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out ) @@ -412,7 +432,7 @@ struct Timer int counter; }; -void Timer_run_( struct Timer* t, long time ) ICODE_ATTR; +void Timer_run_( struct Timer* t, long time ) ICODE_ATTR_SPC; static inline void Timer_run( struct Timer* t, long time ) { @@ -461,7 +481,7 @@ void SPC_Init( THIS ); int SPC_load_spc( THIS, const void* data, long size ); /**************** DSP interaction ****************/ -void DSP_write( struct Spc_Dsp* this, int i, int data ) ICODE_ATTR; +void DSP_write( struct Spc_Dsp* this, int i, int data ) ICODE_ATTR_SPC; static inline int DSP_read( struct Spc_Dsp* this, int i ) { @@ -469,7 +489,7 @@ static inline int DSP_read( struct Spc_Dsp* this, int i ) return this->r.reg [i]; } -void SPC_run_dsp_( THIS, long time ) ICODE_ATTR; +void SPC_run_dsp_( THIS, long time ) ICODE_ATTR_SPC; static inline void SPC_run_dsp( THIS, long time ) { @@ -477,10 +497,10 @@ static inline void SPC_run_dsp( THIS, long time ) SPC_run_dsp_( this, time ); } -int SPC_read( THIS, unsigned addr, long const time ) ICODE_ATTR; -void SPC_write( THIS, unsigned addr, int data, long const time ) ICODE_ATTR; +int SPC_read( THIS, unsigned addr, long const time ) ICODE_ATTR_SPC; +void SPC_write( THIS, unsigned addr, int data, long const time ) ICODE_ATTR_SPC; /**************** Sample generation ****************/ -int SPC_play( THIS, long count, int32_t* out ) ICODE_ATTR; +int SPC_play( THIS, long count, int32_t* out ) ICODE_ATTR_SPC; #endif /* _SPC_CODEC_H_ */ diff --git a/apps/codecs/libspc/spc_cpu.c b/apps/codecs/libspc/spc_cpu.c index d308e6e27c..23dcc257de 100644 --- a/apps/codecs/libspc/spc_cpu.c +++ b/apps/codecs/libspc/spc_cpu.c @@ -65,7 +65,7 @@ static unsigned char const cycle_table [0x100] = { #define MEM_BIT() CPU_mem_bit( this, pc, spc_time_ ) static unsigned CPU_mem_bit( THIS, uint8_t const* pc, long const spc_time_ ) - ICODE_ATTR; + ICODE_ATTR_SPC; static unsigned CPU_mem_bit( THIS, uint8_t const* pc, long const spc_time_ ) { diff --git a/apps/codecs/libspc/spc_dsp.c b/apps/codecs/libspc/spc_dsp.c index b4fc57158b..4b289caeda 100644 --- a/apps/codecs/libspc/spc_dsp.c +++ b/apps/codecs/libspc/spc_dsp.c @@ -28,8 +28,7 @@ #include "spc_profiler.h" #if defined(CPU_COLDFIRE) || defined (CPU_ARM) -int32_t fir_buf[FIR_BUF_CNT] - __attribute__ ((aligned (FIR_BUF_ALIGN*1))) IBSS_ATTR; +int32_t fir_buf[FIR_BUF_CNT] IBSS_ATTR_SPC MEM_ALIGN_ATTR; #endif #if SPC_BRRCACHE /* a little extra for samples that go past end */ @@ -80,7 +79,7 @@ void DSP_write( struct Spc_Dsp* this, int i, int data ) #if SPC_BRRCACHE static void decode_brr( struct Spc_Dsp* this, unsigned start_addr, struct voice_t* voice, - struct raw_voice_t const* const raw_voice ) ICODE_ATTR; + struct raw_voice_t const* const raw_voice ) ICODE_ATTR_SPC; static void decode_brr( struct Spc_Dsp* this, unsigned start_addr, struct voice_t* voice, struct raw_voice_t const* const raw_voice ) @@ -248,7 +247,7 @@ wave_in_cache:; static void key_on(struct Spc_Dsp* const this, struct voice_t* const voice, struct src_dir const* const sd, struct raw_voice_t const* const raw_voice, - const int key_on_delay, const int vbit) ICODE_ATTR; + const int key_on_delay, const int vbit) ICODE_ATTR_SPC; static void key_on(struct Spc_Dsp* const this, struct voice_t* const voice, struct src_dir const* const sd, struct raw_voice_t const* const raw_voice, @@ -385,7 +384,7 @@ void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) /* each rate divides exactly into 0x7800 without remainder */ int const env_rate_init = 0x7800; - static unsigned short const env_rates [0x20] ICONST_ATTR = + static unsigned short const env_rates [0x20] ICONST_ATTR_SPC = { 0x0000, 0x000F, 0x0014, 0x0018, 0x001E, 0x0028, 0x0030, 0x003C, 0x0050, 0x0060, 0x0078, 0x00A0, 0x00C0, 0x00F0, 0x0140, 0x0180, @@ -767,7 +766,7 @@ void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) #if !SPC_NOINTERP /* Interleved gauss table (to improve cache coherency). */ /* gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i] */ - static short const gauss [512] = + static short const gauss [512] ICONST_ATTR_SPC = { 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303, 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299, diff --git a/apps/codecs/libspc/spc_emu.c b/apps/codecs/libspc/spc_emu.c index 1bebc86d9a..0ad1329a6b 100644 --- a/apps/codecs/libspc/spc_emu.c +++ b/apps/codecs/libspc/spc_emu.c @@ -28,7 +28,7 @@ /* DSP Based on Brad Martin's OpenSPC DSP emulator */ /* tag reading from sexyspc by John Brawn (John_Brawn@yahoo.com) and others */ -struct cpu_ram_t ram CACHEALIGN_ATTR; +struct cpu_ram_t ram IBSS_ATTR_SPC_LARGE_IRAM CACHEALIGN_ATTR; /**************** Timers ****************/ diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 1b49761810..80c28abbc1 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c @@ -190,7 +190,7 @@ static int LoadID666(unsigned char *buf) { /**************** Codec ****************/ enum {SAMPLE_RATE = 32000}; -static struct Spc_Emu spc_emu IDATA_ATTR CACHEALIGN_ATTR; +static struct Spc_Emu spc_emu IBSS_ATTR_SPC CACHEALIGN_ATTR; #if SPC_DUAL_CORE /** Implementations for pipelined dual-core operation **/ -- cgit v1.2.3