Recode to clean up function prologues and epilogue and to allow the functions

to be used in a Thumb based toolchain.
This commit is contained in:
Nick Clifton 2000-08-09 21:55:54 +00:00
parent ff3d99fb37
commit 38a6bf987b
2 changed files with 108 additions and 68 deletions

View File

@ -1,3 +1,9 @@
2000-08-09 Nick Clifton <nickc@cygnus.com>
* libc/sys/arm/setjmp.S: Recode to clean up function prologues and
epilogue and to allow the functions to be used in a Thumb based
toolchain.
2000-08-08 Jeff Johnston <jjohnstn@redhat.com>
* libc/stdio/snprintf.c (snprintf, _snprintf_r): Fixed code

View File

@ -6,63 +6,20 @@
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a##b
#ifdef __USER_LABEL_PREFIX__
#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
#ifndef __USER_LABEL_PREFIX__
#error __USER_LABEL_PREFIX__ not defined
#endif
#define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
#ifdef __ELF__
#define TYPE(x) .type SYM(x),function
#define SIZE(x) .size SYM(x), . - SYM(x)
#else
#error __USER_LABEL_PREFIX__ is not defined
#define TYPE(x)
#define SIZE(x)
#endif
.text
.code 32
.align 2
/* int setjmp (jmp_buf); */
.globl FUNCTION(setjmp)
FUNCTION(setjmp):
/* Save all the callee-preserved registers into the jump buffer. */
stmea a1!, { v1-v7, fp, ip, sp, lr }
#if 0 /* Simulator does not cope with FP instructions yet.... */
#ifndef __SOFTFP__
/* Save the floating point registers */
sfmea f4, 4, [a1]
#endif
#endif
/* When setting up the jump buffer return 0. */
mov a1, #0
/* Return to caller, see comment in longjmp below */
#ifdef __APCS_26__
movs pc, lr
#else
tst lr, #1
moveq pc, lr
.word 0xe12fff1e /* bx lr */
#endif
/* volatile void longjmp (jmp_buf, int); */
.globl FUNCTION(longjmp)
FUNCTION(longjmp):
/* If we have stack extension code it ought to be handled here. */
/* Restore the registers, retrieving the state when setjmp() was called. */
ldmfd a1!, { v1-v7, fp, ip, sp, lr }
#if 0 /* Simulator does not cope with FP instructions yet.... */
#ifndef __SOFTFP__
/* Restore floating point registers as well */
lfmfd f4, 4, [a1]
#endif
#endif
/* Put the return value into the integer result register.
But if it is zero then return 1 instead. */
movs a1, a2
moveq a1, #1
/* Arm/Thumb interworking support:
The interworking scheme expects functions to use a BX instruction
@ -89,14 +46,91 @@ FUNCTION(longjmp):
If we are running using the APCS-26 convention however, then we never
test the bottom bit, because this is part of the processor status.
Instead we just do a normal return, since we know that we cannot be
returning to a Thumb caller - the Thumb doe snot support APCS-26
*/
returning to a Thumb caller - the Thumb does not support APCS-26.
Function entry is much simpler. If we are compiling for the Thumb we
just switch into ARM mode and then drop through into the rest of the
function. The function exit code will take care of the restore to
Thumb mode. */
#ifdef __APCS_26__
movs pc, lr
#define RET movs pc, lr
#else
tst lr, #1
moveq pc, lr
#define RET tst lr, #1; \
moveq pc, lr ; \
.word 0xe12fff1e /* bx lr */
#endif
#ifdef __thumb__
#define MODE .thumb_func
.macro PROLOGUE name
bx pc
nop
.code 32
SYM (.arm_start_of.\name):
.endm
#else
#define MODE .code 32
.macro PROLOGUE name
.endm
#endif
.macro FUNC_START name
.text
.align 2
MODE
.globl SYM (\name)
TYPE (\name)
SYM (\name):
PROLOGUE \name
.endm
.macro FUNC_END name
RET
SIZE (\name)
.endm
/* --------------------------------------------------------------------
int setjmp (jmp_buf);
-------------------------------------------------------------------- */
FUNC_START setjmp
/* Save all the callee-preserved registers into the jump buffer. */
stmea a1!, { v1-v7, fp, ip, sp, lr }
#if 0 /* Simulator does not cope with FP instructions yet. */
#ifndef __SOFTFP__
/* Save the floating point registers. */
sfmea f4, 4, [a1]
#endif
#endif
/* When setting up the jump buffer return 0. */
mov a1, #0
FUNC_END setjmp
/* --------------------------------------------------------------------
volatile void longjmp (jmp_buf, int);
-------------------------------------------------------------------- */
FUNC_START longjmp
/* If we have stack extension code it ought to be handled here. */
/* Restore the registers, retrieving the state when setjmp() was called. */
ldmfd a1!, { v1-v7, fp, ip, sp, lr }
#if 0 /* Simulator does not cope with FP instructions yet. */
#ifndef __SOFTFP__
/* Restore floating point registers as well. */
lfmfd f4, 4, [a1]
#endif
#endif
/* Put the return value into the integer result register.
But if it is zero then return 1 instead. */
movs a1, a2
moveq a1, #1
FUNC_END longjmp