OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [machine/] [arm/] [setjmp.S] - Diff between revs 207 and 345

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 345
/* This is a simple version of setjmp and longjmp.
/* This is a simple version of setjmp and longjmp.
   Nick Clifton, Cygnus Solutions, 13 June 1997.  */
   Nick Clifton, Cygnus Solutions, 13 June 1997.  */
/* ANSI concatenation macros.  */
/* ANSI concatenation macros.  */
#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
#ifndef __USER_LABEL_PREFIX__
#ifndef __USER_LABEL_PREFIX__
#error  __USER_LABEL_PREFIX__ not defined
#error  __USER_LABEL_PREFIX__ not defined
#endif
#endif
#define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
#define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
#ifdef __ELF__
#ifdef __ELF__
#define TYPE(x) .type SYM(x),function
#define TYPE(x) .type SYM(x),function
#define SIZE(x) .size SYM(x), . - SYM(x)
#define SIZE(x) .size SYM(x), . - SYM(x)
#else
#else
#define TYPE(x)
#define TYPE(x)
#define SIZE(x)
#define SIZE(x)
#endif
#endif
/* 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
   to return control to their parent.  Since we need this code to work
   to return control to their parent.  Since we need this code to work
   in both interworked and non-interworked environments as well as with
   in both interworked and non-interworked environments as well as with
   older processors which do not have the BX instruction we do the
   older processors which do not have the BX instruction we do the
   following:
   following:
        Test the return address.
        Test the return address.
        If the bottom bit is clear perform an "old style" function exit.
        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).
        (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.
        Otherwise use the BX instruction to perform the function exit.
   We know that we will never attempt to perform the BX instruction on
   We know that we will never attempt to perform the BX instruction on
   an older processor, because that kind of processor will never be
   an older processor, because that kind of processor will never be
   interworked, and a return address with the bottom bit set will never
   interworked, and a return address with the bottom bit set will never
   be generated.
   be generated.
   In addition, we do not actually assemble the BX instruction as this would
   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
   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
   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
   able to be linked with binaries compiled for older processors however, so
   we do not want such information stored there.
   we do not want such information stored there.
   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 does not 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
   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
   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
   function.  The function exit code will take care of the restore to
   Thumb mode.
   Thumb mode.
   For Thumb-2 do everything in Thumb mode.  */
   For Thumb-2 do everything in Thumb mode.  */
#if defined(__ARM_ARCH_6M__)
#if defined(__ARM_ARCH_6M__)
/* ARMv6-M has to be implemented in Thumb mode.  */
/* ARMv6-M has to be implemented in Thumb mode.  */
.thumb
.thumb
.thumb_func
.thumb_func
        .globl SYM (setjmp)
        .globl SYM (setjmp)
        TYPE (setjmp)
        TYPE (setjmp)
SYM (setjmp):
SYM (setjmp):
        /* Save registers in jump buffer.  */
        /* Save registers in jump buffer.  */
        stmia   r0!, {r4, r5, r6, r7}
        stmia   r0!, {r4, r5, r6, r7}
        mov     r1, r8
        mov     r1, r8
        mov     r2, r9
        mov     r2, r9
        mov     r3, r10
        mov     r3, r10
        mov     r4, fp
        mov     r4, fp
        mov     r5, sp
        mov     r5, sp
        mov     r6, lr
        mov     r6, lr
        stmia   r0!, {r1, r2, r3, r4, r5, r6}
        stmia   r0!, {r1, r2, r3, r4, r5, r6}
        sub     r0, r0, #40
        sub     r0, r0, #40
        /* Restore callee-saved low regs.  */
        /* Restore callee-saved low regs.  */
        ldmia   r0!, {r4, r5, r6, r7}
        ldmia   r0!, {r4, r5, r6, r7}
        /* Return zero.  */
        /* Return zero.  */
        mov     r0, #0
        mov     r0, #0
        bx lr
        bx lr
.thumb_func
.thumb_func
        .globl SYM (longjmp)
        .globl SYM (longjmp)
        TYPE (longjmp)
        TYPE (longjmp)
SYM (longjmp):
SYM (longjmp):
        /* Restore High regs.  */
        /* Restore High regs.  */
        add     r0, r0, #16
        add     r0, r0, #16
        ldmia   r0!, {r2, r3, r4, r5, r6}
        ldmia   r0!, {r2, r3, r4, r5, r6}
        mov     r8, r2
        mov     r8, r2
        mov     r9, r3
        mov     r9, r3
        mov     r10, r4
        mov     r10, r4
        mov     fp, r5
        mov     fp, r5
        mov     sp, r6
        mov     sp, r6
        ldmia   r0!, {r3} /* lr */
        ldmia   r0!, {r3} /* lr */
        /* Restore low regs.  */
        /* Restore low regs.  */
        sub     r0, r0, #40
        sub     r0, r0, #40
        ldmia   r0!, {r4, r5, r6, r7}
        ldmia   r0!, {r4, r5, r6, r7}
        /* Return the result argument, or 1 if it is zero.  */
        /* Return the result argument, or 1 if it is zero.  */
        mov     r0, r1
        mov     r0, r1
        bne     1f
        bne     1f
        mov     r0, #1
        mov     r0, #1
1:
1:
        bx      r3
        bx      r3
#else
#else
#ifdef __APCS_26__
#ifdef __APCS_26__
#define RET     movs            pc, lr
#define RET     movs            pc, lr
#elif defined(__thumb2__)
#elif defined(__thumb2__)
#define RET     bx lr
#define RET     bx lr
#else
#else
#define RET     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 __thumb2__
#ifdef __thumb2__
.macro COND where when
.macro COND where when
        i\where \when
        i\where \when
.endm
.endm
#else
#else
.macro COND where when
.macro COND where when
.endm
.endm
#endif
#endif
#if defined(__thumb2__)
#if defined(__thumb2__)
.syntax unified
.syntax unified
.macro MODE
.macro MODE
        .thumb
        .thumb
        .thumb_func
        .thumb_func
.endm
.endm
.macro PROLOGUE name
.macro PROLOGUE name
.endm
.endm
#elif defined(__thumb__)
#elif defined(__thumb__)
#define MODE            .thumb_func
#define MODE            .thumb_func
.macro PROLOGUE name
.macro PROLOGUE name
        .code 16
        .code 16
        bx      pc
        bx      pc
        nop
        nop
        .code 32
        .code 32
SYM (.arm_start_of.\name):
SYM (.arm_start_of.\name):
.endm
.endm
#else /* Arm */
#else /* Arm */
#define MODE            .code 32
#define MODE            .code 32
.macro PROLOGUE name
.macro PROLOGUE name
.endm
.endm
#endif
#endif
.macro FUNC_START name
.macro FUNC_START name
        .text
        .text
        .align 2
        .align 2
        MODE
        MODE
        .globl SYM (\name)
        .globl SYM (\name)
        TYPE (\name)
        TYPE (\name)
SYM (\name):
SYM (\name):
        PROLOGUE \name
        PROLOGUE \name
.endm
.endm
.macro FUNC_END name
.macro FUNC_END name
        RET
        RET
        SIZE (\name)
        SIZE (\name)
.endm
.endm
/* --------------------------------------------------------------------
/* --------------------------------------------------------------------
                 int setjmp (jmp_buf);
                 int setjmp (jmp_buf);
   -------------------------------------------------------------------- */
   -------------------------------------------------------------------- */
        FUNC_START setjmp
        FUNC_START setjmp
        /* Save all the callee-preserved registers into the jump buffer.  */
        /* Save all the callee-preserved registers into the jump buffer.  */
#ifdef __thumb2__
#ifdef __thumb2__
        mov             ip, sp
        mov             ip, sp
        stmea           a1!, { v1-v7, fp, ip, lr }
        stmea           a1!, { v1-v7, fp, ip, lr }
#else
#else
        stmea           a1!, { v1-v7, fp, ip, sp, lr }
        stmea           a1!, { v1-v7, fp, ip, sp, lr }
#endif
#endif
#if 0   /* Simulator does not cope with FP instructions yet.  */
#if 0   /* Simulator does not cope with FP instructions yet.  */
#ifndef __SOFTFP__
#ifndef __SOFTFP__
        /* Save the floating point registers.  */
        /* Save the floating point registers.  */
        sfmea           f4, 4, [a1]
        sfmea           f4, 4, [a1]
#endif
#endif
#endif
#endif
        /* When setting up the jump buffer return 0.  */
        /* When setting up the jump buffer return 0.  */
        mov             a1, #0
        mov             a1, #0
        FUNC_END setjmp
        FUNC_END setjmp
/* --------------------------------------------------------------------
/* --------------------------------------------------------------------
                volatile void longjmp (jmp_buf, int);
                volatile void longjmp (jmp_buf, int);
   -------------------------------------------------------------------- */
   -------------------------------------------------------------------- */
        FUNC_START longjmp
        FUNC_START 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.  */
#ifdef __thumb2__
#ifdef __thumb2__
        ldmfd           a1!, { v1-v7, fp, ip, lr }
        ldmfd           a1!, { v1-v7, fp, ip, lr }
        mov             sp, ip
        mov             sp, ip
#else
#else
        ldmfd           a1!, { v1-v7, fp, ip, sp, lr }
        ldmfd           a1!, { v1-v7, fp, ip, sp, lr }
#endif
#endif
#if 0   /* Simulator does not cope with FP instructions yet.  */
#if 0   /* Simulator does not cope with FP instructions yet.  */
#ifndef __SOFTFP__
#ifndef __SOFTFP__
        /* Restore floating point registers as well.  */
        /* Restore floating point registers as well.  */
        lfmfd           f4, 4, [a1]
        lfmfd           f4, 4, [a1]
#endif
#endif
#endif
#endif
        /* Put the return value into the integer result register.
        /* Put the return value into the integer result register.
           But if it is zero then return 1 instead.  */
           But if it is zero then return 1 instead.  */
        movs            a1, a2
        movs            a1, a2
#ifdef __thumb2__
#ifdef __thumb2__
        it              eq
        it              eq
#endif
#endif
        moveq           a1, #1
        moveq           a1, #1
        FUNC_END longjmp
        FUNC_END longjmp
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.