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:
parent
ff3d99fb37
commit
38a6bf987b
|
@ -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>
|
2000-08-08 Jeff Johnston <jjohnstn@redhat.com>
|
||||||
|
|
||||||
* libc/stdio/snprintf.c (snprintf, _snprintf_r): Fixed code
|
* libc/stdio/snprintf.c (snprintf, _snprintf_r): Fixed code
|
||||||
|
|
|
@ -6,63 +6,20 @@
|
||||||
#define CONCAT(a, b) CONCAT2(a, b)
|
#define CONCAT(a, b) CONCAT2(a, b)
|
||||||
#define CONCAT2(a, b) a##b
|
#define CONCAT2(a, b) a##b
|
||||||
|
|
||||||
#ifdef __USER_LABEL_PREFIX__
|
#ifndef __USER_LABEL_PREFIX__
|
||||||
#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
|
#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
|
#else
|
||||||
#error __USER_LABEL_PREFIX__ is not defined
|
#define TYPE(x)
|
||||||
|
#define SIZE(x)
|
||||||
#endif
|
#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:
|
/* Arm/Thumb interworking support:
|
||||||
|
|
||||||
The interworking scheme expects functions to use a BX instruction
|
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
|
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.
|
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
|
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__
|
#ifdef __APCS_26__
|
||||||
movs pc, lr
|
#define RET movs pc, lr
|
||||||
#else
|
#else
|
||||||
tst lr, #1
|
#define RET tst lr, #1; \
|
||||||
moveq pc, lr
|
moveq pc, lr ; \
|
||||||
.word 0xe12fff1e /* bx lr */
|
.word 0xe12fff1e /* bx lr */
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue