~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to libc/stdlib/setjmp.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-04-04 17:05:32 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080404170532-tiwwl2e2qln7ri0w
Tags: 1:1.6.2-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
27
  POSSIBILITY OF SUCH DAMAGE. */
28
28
 
29
 
/* $Id: setjmp.S,v 1.2.2.1 2007/06/09 04:10:53 arcanum Exp $ */
 
29
/* $Id: setjmp.S,v 1.3.2.2 2008/03/24 11:29:54 dmix Exp $ */
30
30
 
31
31
/*
32
32
   setjmp.S
42
42
        16       2      frame pointer (r29:r28)
43
43
        18       2      stack pointer (SPH:SPL)
44
44
        20       1      status register (SREG)
45
 
        21       3      return address (PC) (2 bytes used for <=128K flash)
46
 
        24 = total size
 
45
        21       2/3    return address (PC) (2 bytes used for <=128Kw flash)
 
46
        23/24 = total size
 
47
   All multibytes are stored as little-endian.
47
48
 
48
 
int setjmp(jmp_buf __jmpb);
49
 
void longjmp(jmp_buf __jmpb, int __val) __attribute__((noreturn));
 
49
   int setjmp(jmp_buf __jmpb);
 
50
   void longjmp(jmp_buf __jmpb, int __val) __attribute__((noreturn));
50
51
 */
51
52
 
 
53
#ifndef __DOXYGEN__
 
54
 
 
55
#include <avr/io.h>
52
56
#include "macros.inc"
53
 
#include "ctoasm.inc"
54
57
 
55
 
/* the same library is used for 2313 and 8515 for now -
56
 
   I hope writing 0 to non-existent SPH doesn't hurt... */
57
 
#ifndef SPH
58
 
#define SPH (SPL+1)
 
58
/* ???: What was a reason to use aliases for common registers?
 
59
   Check the address: is it a port number (value for IN/OUT)?   */
 
60
#if     AVR_STACK_POINTER_LO_ADDR != 0x3D       \
 
61
     || AVR_STATUS_ADDR != 0x3F
 
62
# error  "Strange address of common registers SPL, SREG"
59
63
#endif
60
64
 
61
 
#define jmpb_hi rP0
62
 
#define jmpb_lo rP1
63
 
#define val_hi  rP2
64
 
#define val_lo  rP3
 
65
#define jmpb_hi r25
 
66
#define jmpb_lo r24
 
67
#define val_hi  r23
 
68
#define val_lo  r22
65
69
 
66
 
#define ret_lo rP1  /* r24 */
67
 
#define ret_hi rP0  /* r25 */
 
70
#define ret_lo  r24
 
71
#define ret_hi  r25
68
72
 
69
73
        .section .text
70
74
 
71
75
        .global _U(setjmp)
72
 
        .global _U(longjmp)
 
76
        .type   _U(setjmp), @function
73
77
 
74
78
_U(setjmp):
75
 
        X_movw  ZL, jmpb_lo
76
 
        in      r26, AVR_STACK_POINTER_LO_ADDR
 
79
        X_movw  XL, jmpb_lo
 
80
  ; save call-saved registers and frame pointer
 
81
        .irp    .L_regno, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,28,29
 
82
        st      X+, r\.L_regno
 
83
        .endr
 
84
  ; get return address
 
85
#if  defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__
 
86
        pop     __tmp_reg__             ; used below
 
87
#endif
 
88
        pop     ZH
 
89
        pop     ZL
 
90
  ; save stack pointer (after poping)
 
91
        in      ret_lo, AVR_STACK_POINTER_LO_ADDR
 
92
        st      X+, ret_lo
77
93
#ifdef _HAVE_AVR_STACK_POINTER_HI    
78
 
        in      r27, AVR_STACK_POINTER_HI_ADDR
 
94
        in      ret_lo, AVR_STACK_POINTER_HI_ADDR
 
95
        st      X+, ret_lo
79
96
#else
80
 
    clr r27
81
 
#endif
82
 
        /* save program counter (return address) */
83
 
        /* return address on stack (pushed by "call") is big endian! */
84
 
        /* SP is post-decremented by "call" */
85
 
        adiw    r26, 1
86
 
#ifdef AVR_EXTENDED_INDIRECT_REG  /* devices with >128K bytes of flash */
87
 
        ld      __tmp_reg__, X+
88
 
        std     Z+23, __tmp_reg__
89
 
#endif
90
 
        ld      __tmp_reg__, X+
91
 
        std     Z+22, __tmp_reg__
92
 
        ld      __tmp_reg__, X
93
 
        std     Z+21, __tmp_reg__
94
 
        /* save stack pointer (SP value before calling this function) */
95
 
        std     Z+18,r26
96
 
        std     Z+19,r27
97
 
        /* save status register (I flag) */
98
 
        in      __tmp_reg__, AVR_STATUS_ADDR
99
 
        std     Z+20, __tmp_reg__
100
 
        /* save call-saved registers */
101
 
        st      Z, r2
102
 
        std     Z+1, r3
103
 
        std     Z+2, r4
104
 
        std     Z+3, r5
105
 
        std     Z+4, r6
106
 
        std     Z+5, r7
107
 
        std     Z+6, r8
108
 
        std     Z+7, r9
109
 
        std     Z+8, r10
110
 
        std     Z+9, r11
111
 
        std     Z+10, r12
112
 
        std     Z+11, r13
113
 
        std     Z+12, r14
114
 
        std     Z+13, r15
115
 
        std     Z+14, r16
116
 
        std     Z+15, r17
117
 
        /* save frame pointer */
118
 
        std     Z+16,r28
119
 
        std     Z+17,r29
120
 
        /* return zero */
 
97
        st      X+, __zero_reg__
 
98
#endif
 
99
  ; save status register (I flag)
 
100
        in      ret_lo, AVR_STATUS_ADDR
 
101
        st      X+, ret_lo
 
102
  ; save return address
 
103
        st      X+, ZL
 
104
        st      X+, ZH
 
105
  ; return zero
121
106
        clr     ret_lo
122
107
        clr     ret_hi
123
 
        ret
 
108
#if  defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__
 
109
        st      X+, __tmp_reg__
 
110
        rjmp    .L_eijmp
 
111
#else
 
112
        ijmp
 
113
#endif
 
114
        .size   _U(setjmp), . - _U(setjmp)
 
115
 
 
116
        .global _U(longjmp)
 
117
        .type   _U(longjmp), @function
124
118
 
125
119
_U(longjmp):
126
120
        X_movw  XL, jmpb_lo
127
 
        /* return value */
 
121
  ; return value
128
122
        X_movw  ret_lo, val_lo
129
 
        /* if zero, change to 1 */
 
123
  ; if zero, change to 1
130
124
        cpi     ret_lo, 1
131
125
        cpc     ret_hi, __zero_reg__
132
126
        adc     ret_lo, __zero_reg__
133
 
        /* restore call-saved registers */
134
 
        ld      r2, X+
135
 
        ld      r3, X+
136
 
        ld      r4, X+
137
 
        ld      r5, X+
138
 
        ld      r6, X+
139
 
        ld      r7, X+
140
 
        ld      r8, X+
141
 
        ld      r9, X+
142
 
        ld      r10, X+
143
 
        ld      r11, X+
144
 
        ld      r12, X+
145
 
        ld      r13, X+
146
 
        ld      r14, X+
147
 
        ld      r15, X+
148
 
        ld      r16, X+
149
 
        ld      r17, X+
150
 
        /* restore frame pointer */
151
 
        ld      YL, X+
152
 
        ld      YH, X+
153
 
        /* restore stack pointer (SP value before the setjmp() call) */
154
 
        ld      r30,X+
155
 
        ld      r31,X+
 
127
  ; restore call-saved registers and frame pointer
 
128
        .irp    .L_regno, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,28,29
 
129
        ld      r\.L_regno, X+
 
130
        .endr
 
131
  ; restore stack pointer (SP value before the setjmp() call) and SREG
 
132
        ld      ZL, X+
 
133
        ld      ZH, X+
156
134
        ld      __tmp_reg__, X+
 
135
#ifdef _HAVE_AVR_STACK_POINTER_HI
157
136
        /* interrupts disabled for shortest possible time (3 cycles) */
158
137
        cli
159
 
#ifdef _HAVE_AVR_STACK_POINTER_HI    
160
 
        out     AVR_STACK_POINTER_HI_ADDR, r31
 
138
        out     AVR_STACK_POINTER_HI_ADDR, ZH
161
139
#endif
162
140
        /* Restore status register (including the interrupt enable flag).
163
141
           Interrupts are re-enabled only after the next instruction.  */
164
142
        out     AVR_STATUS_ADDR, __tmp_reg__
165
 
        out     AVR_STACK_POINTER_LO_ADDR, r30
166
 
        /* restore return address */
167
 
        ld      r30,X+
168
 
        ld      r31,X+
169
 
#ifdef AVR_EXTENDED_INDIRECT_REG
170
 
        ld      __tmp_reg__, X
 
143
        out     AVR_STACK_POINTER_LO_ADDR, ZL
 
144
  ; get return address and jump
 
145
        ld      ZL, X+
 
146
        ld      ZH, X+
 
147
#if  defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__
 
148
        ld      __tmp_reg__, X+
 
149
.L_eijmp:
171
150
        out     AVR_EXTENDED_INDIRECT_ADDR, __tmp_reg__
172
151
        eijmp
173
152
#else
174
153
        ijmp
175
154
#endif
 
155
        .size   _U(longjmp), . - _U(longjmp)
176
156
 
 
157
#endif  /* !__DOXYGEN__ */