diff --git a/newlib/ChangeLog b/newlib/ChangeLog index d81a5475e..22a132145 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,10 @@ +2004-09-21 Ian Lance Taylor + + * libc/machine/xscale/setjmp.S: New file, copied from + libc/machine/arm/setjmp.S. + * libc/machine/xscale/Makefile.am (lib_a_SOURCES): Add setjmp.S. + * libc/machine/xscale/Makefile.in: Regenerate. + 2004-09-16 Antony King * libc/include/sys/lock.h: Replaced empty {} with (0) to conform diff --git a/newlib/libc/machine/xscale/Makefile.am b/newlib/libc/machine/xscale/Makefile.am index eaa413a88..9b6248250 100644 --- a/newlib/libc/machine/xscale/Makefile.am +++ b/newlib/libc/machine/xscale/Makefile.am @@ -8,7 +8,7 @@ noinst_LIBRARIES = lib.a lib_a_SOURCES = \ memchr.c memcmp.c memcpy.c memmove.c memset.c \ - strchr.c strcmp.c strcpy.c strlen.c + strchr.c strcmp.c strcpy.c strlen.c setjmp.S ACLOCAL_AMFLAGS = -I ../../.. CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/machine/xscale/Makefile.in b/newlib/libc/machine/xscale/Makefile.in index 3d3fce334..1f5171268 100644 --- a/newlib/libc/machine/xscale/Makefile.in +++ b/newlib/libc/machine/xscale/Makefile.in @@ -89,7 +89,9 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) noinst_LIBRARIES = lib.a -lib_a_SOURCES = memchr.c memcmp.c memcpy.c memmove.c memset.c strchr.c strcmp.c strcpy.c strlen.c +lib_a_SOURCES = \ + memchr.c memcmp.c memcpy.c memmove.c memset.c \ + strchr.c strcmp.c strcpy.c strlen.c setjmp.S ACLOCAL_AMFLAGS = -I ../../.. @@ -105,7 +107,7 @@ CPPFLAGS = @CPPFLAGS@ LIBS = @LIBS@ lib_a_LIBADD = lib_a_OBJECTS = memchr.o memcmp.o memcpy.o memmove.o memset.o strchr.o \ -strcmp.o strcpy.o strlen.o +strcmp.o strcpy.o strlen.o setjmp.o CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) diff --git a/newlib/libc/machine/xscale/setjmp.S b/newlib/libc/machine/xscale/setjmp.S new file mode 100644 index 000000000..d37486090 --- /dev/null +++ b/newlib/libc/machine/xscale/setjmp.S @@ -0,0 +1,137 @@ +/* This is a simple version of setjmp and longjmp. + + Nick Clifton, Cygnus Solutions, 13 June 1997. */ + +/* ANSI concatenation macros. */ +#define CONCAT(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a##b + +#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 +#define TYPE(x) +#define SIZE(x) +#endif + +/* Arm/Thumb interworking support: + + The interworking scheme expects functions to use a BX instruction + to return control to their parent. Since we need this code to work + in both interworked and non-interworked environments as well as with + older processors which do not have the BX instruction we do the + following: + Test the return address. + If the bottom bit is clear perform an "old style" function exit. + (We know that we are in ARM mode and returning to an ARM mode caller). + Otherwise use the BX instruction to perform the function exit. + + We know that we will never attempt to perform the BX instruction on + an older processor, because that kind of processor will never be + interworked, and a return address with the bottom bit set will never + be generated. + + In addition, we do not actually assemble the BX instruction as this would + require us to tell the assembler that the processor is an ARM7TDMI and + it would store this information in the binary. We want this binary to be + able to be linked with binaries compiled for older processors however, so + we do not want such information stored there. + + 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 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__ +#define RET movs pc, lr +#else +#define RET tst lr, #1; \ + moveq pc, lr ; \ +.word 0xe12fff1e /* bx lr */ +#endif + +#ifdef __thumb__ +#define MODE .thumb_func +.macro PROLOGUE name + .code 16 + 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 +