Hi Sébastien,
Am 26.02.2010 10:02, schrieb Sébastien Lorquet:
> probably off topic, sorry, but what I miss in the 8051 port is a 16
> bit-stack pointer in xdata mode :(
Would swapping out contents of the 8051 hardware stack to
xdata memory help?
Appending untested sample code that tries to implement this.
(expect some bugs in that code)
You'd have to call _stackadjust at strategic places in your code.
(eventually you can patch the function genCall in sdcc/sdcc/src/mcs51/gen.c
to additionally emit an lcall __stackadjust (well, probably not a good idea))
Compile with: sdcc --std-sdcc99 -c stackadjust.c
Occasionally swapping in and out is probably cheaper than
always emulating a 16 bit-stack pointer in xdata mode.
Greetings,
Frieder
/*-----8<--------------stackadjust.c----------------------------------*/
/* GPL+LE */
#include <8052.h>
#define STACK_SWAP_WATERMARK 0x18
#define STACK_SWAP_SIZE 0x10
#define STACK_SWAP_HYSTERESIS 0x08
unsigned char __xdata stack_swap_area[0x200];
unsigned char __xdata * __data stack_swap_ptr = stack_swap_area;
/* defined in crtstart.asm */
extern __idata unsigned char* _start__stack;
/* inlineable helper functions *similar* to memcpy */
static void inline memcpy_xi (__xdata unsigned char* dst, __idata unsigned
char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ix (__idata unsigned char* dst, __xdata unsigned
char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ii (__idata unsigned char* dst, __idata unsigned
char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ii_topdown (__idata unsigned char* dst, __idata
unsigned char* src, unsigned char size)
{
src += size;
dst += size;
do
{
*--dst = *--src;
} while( --size );
}
/* Untested! Just something that could be used as a start for an implementation
in assembler
* Checks whether the 8051 hardware stack is above or below a watermark
* and then eventually swaps content to/from xdata memory
*/
void _stackadjust (void)
{
if (SP >= (unsigned char)((unsigned char)&_start__stack +
STACK_SWAP_WATERMARK + STACK_SWAP_HYSTERESIS/2))
{
/* 8051 hardware stack was too large */
__critical
{
// copying to external memory
memcpy_xi (stack_swap_ptr, (unsigned char __idata *)&_start__stack,
STACK_SWAP_SIZE );
stack_swap_ptr += STACK_SWAP_SIZE;
// moving contents of stack
memcpy_ii ( (unsigned char __idata *)&_start__stack,
(unsigned char __idata *)&_start__stack + STACK_SWAP_SIZE,
(unsigned char)(SP - (unsigned char)&_start__stack -
STACK_SWAP_SIZE));
SP -= STACK_SWAP_SIZE;
}
} else if ( SP <= (unsigned char)((unsigned char)&_start__stack +
STACK_SWAP_WATERMARK - STACK_SWAP_HYSTERESIS/2) &&
stack_swap_ptr != stack_swap_area )
{
__critical
{
SP += STACK_SWAP_SIZE;
// copying contents
memcpy_ii_topdown ( (unsigned char __idata *)&_start__stack +
STACK_SWAP_SIZE,
(unsigned char __idata *)&_start__stack,
(SP - (unsigned char)&_start__stack -
STACK_SWAP_SIZE));
// copying from external memory
memcpy_ix ((unsigned char __idata *)&_start__stack, stack_swap_ptr,
STACK_SWAP_SIZE );
stack_swap_ptr -= STACK_SWAP_SIZE;
}
}
}
/* GPL+LE */
#include <8052.h>
#define STACK_SWAP_WATERMARK 0x18
#define STACK_SWAP_SIZE 0x10
#define STACK_SWAP_HYSTERESIS 0x08
unsigned char __xdata stack_swap_area[0x200];
unsigned char __xdata * __data stack_swap_ptr = stack_swap_area;
/* defined in crtstart.asm */
extern __idata unsigned char* _start__stack;
/* inlineable helper functions *similar* to memcpy */
static void inline memcpy_xi (__xdata unsigned char* dst, __idata unsigned char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ix (__idata unsigned char* dst, __xdata unsigned char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ii (__idata unsigned char* dst, __idata unsigned char* src, unsigned char size)
{
do
{
*dst++ = *src++;
} while( --size );
}
static void inline memcpy_ii_topdown (__idata unsigned char* dst, __idata unsigned char* src, unsigned char size)
{
src += size;
dst += size;
do
{
*--dst = *--src;
} while( --size );
}
/* Untested! Just something that could be used as a start for an implementation in assembler
* Checks whether the 8051 hardware stack is above or below a watermark
* and then eventually swaps content to/from xdata memory
*/
void _stackadjust (void)
{
if (SP >= (unsigned char)((unsigned char)&_start__stack + STACK_SWAP_WATERMARK + STACK_SWAP_HYSTERESIS/2))
{
/* 8051 hardware stack was too large */
__critical
{
// copying to external memory
memcpy_xi (stack_swap_ptr, (unsigned char __idata *)&_start__stack, STACK_SWAP_SIZE );
stack_swap_ptr += STACK_SWAP_SIZE;
// moving contents of stack
memcpy_ii ( (unsigned char __idata *)&_start__stack,
(unsigned char __idata *)&_start__stack + STACK_SWAP_SIZE,
(unsigned char)(SP - (unsigned char)&_start__stack - STACK_SWAP_SIZE));
SP -= STACK_SWAP_SIZE;
}
} else if ( SP <= (unsigned char)((unsigned char)&_start__stack + STACK_SWAP_WATERMARK - STACK_SWAP_HYSTERESIS/2) &&
stack_swap_ptr != stack_swap_area )
{
__critical
{
SP += STACK_SWAP_SIZE;
// copying contents
memcpy_ii_topdown ( (unsigned char __idata *)&_start__stack + STACK_SWAP_SIZE,
(unsigned char __idata *)&_start__stack,
(SP - (unsigned char)&_start__stack - STACK_SWAP_SIZE));
// copying from external memory
memcpy_ix ((unsigned char __idata *)&_start__stack, stack_swap_ptr, STACK_SWAP_SIZE );
stack_swap_ptr -= STACK_SWAP_SIZE;
}
}
}
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user