OSDN Git Service

Recode to clean up function prologues and epilogue and to allow the functions
authornickc <nickc>
Wed, 9 Aug 2000 21:55:54 +0000 (21:55 +0000)
committernickc <nickc>
Wed, 9 Aug 2000 21:55:54 +0000 (21:55 +0000)
 to be used in a Thumb based toolchain.

newlib/ChangeLog
newlib/libc/sys/arm/setjmp.S

index caee23f..3b71567 100644 (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
index eab8e21..5620154 100644 (file)
    Nick Clifton, Cygnus Solutions, 13 June 1997.  */
 
 /* ANSI concatenation macros.  */
-#define CONCAT(a, b) CONCAT2(a, b)
-#define CONCAT2(a, b) a ## b
+#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
+
+/* 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.  */
 
-       .text
+#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
+       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); 
+   -------------------------------------------------------------------- */
        
-/* int setjmp (jmp_buf);  */
-       .globl  FUNCTION(setjmp)
-FUNCTION(setjmp):
+       FUNC_START setjmp
 
-       /* Save all the callee-preserved registers into the jump buffer. */
+       /* 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.... */
+#if 0  /* Simulator does not cope with FP instructions yet.  */
 #ifndef __SOFTFP__
-       /* Save the floating point registers */
+       /* Save the floating point registers */
        sfmea           f4, 4, [a1]
 #endif
 #endif         
-       /* When setting up the jump buffer return 0. */
+       /* 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
+       FUNC_END setjmp
        
+/* --------------------------------------------------------------------
+               volatile void longjmp (jmp_buf, int);
+   -------------------------------------------------------------------- */
+       
+       FUNC_START longjmp
 
-/* volatile void longjmp (jmp_buf, int);  */
-       .globl  FUNCTION(longjmp)
-FUNCTION(longjmp):
-
-       /* If we have stack extension code it ought to be handled here. */
+       /* If we have stack extension code it ought to be handled here.  */
        
-       /* Restore the registers, retrieving the state when setjmp() was called. */
+       /* 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.... */
+#if 0  /* Simulator does not cope with FP instructions yet.  */
 #ifndef __SOFTFP__
-       /* Restore floating point registers as well */
+       /* Restore floating point registers as well */
        lfmfd           f4, 4, [a1]
 #endif
 #endif 
@@ -63,40 +132,5 @@ FUNCTION(longjmp):
        movs            a1, a2
        moveq           a1, #1
 
-       /* 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 doe snot support APCS-26
-       */
-
-#ifdef __APCS_26__
-       movs            pc, lr
-#else
-       tst             lr, #1
-       moveq           pc, lr
-.word   0xe12fff1e     /* bx lr */
-#endif
+       FUNC_END longjmp