1 /* Subroutines needed for unwinding IA-64 standard format stack frame
2 info for exception handling.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
4 Free Software Foundation, Inc.
5 Contributed by Andrew MacLeod <amacleod@cygnus.com>
6 Andrew Haley <aph@cygnus.com>
7 David Mosberger-Tang <davidm@hpl.hp.com>
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GCC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to
23 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24 Boston, MA 02110-1301, USA. */
26 /* As a special exception, if you link this library with other files,
27 some of which are compiled with GCC, to produce an executable,
28 this library does not by itself cause the resulting executable
29 to be covered by the GNU General Public License.
30 This exception does not however invalidate any other reasons why
31 the executable file might be covered by the GNU General Public License. */
36 #include "coretypes.h"
39 #include "unwind-ia64.h"
40 #include "unwind-compat.h"
41 #include "ia64intrin.h"
43 /* This isn't thread safe, but nice for occasional tests. */
44 #undef ENABLE_MALLOC_CHECKING
46 #ifndef __USING_SJLJ_EXCEPTIONS__
48 #define UNW_VER(x) ((x) >> 48)
49 #define UNW_FLAG_MASK 0x0000ffff00000000
50 #define UNW_FLAG_OSMASK 0x0000f00000000000
51 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
52 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
53 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
55 enum unw_application_register
69 enum unw_register_index
76 UNW_REG_PSP
, /* previous memory stack pointer */
79 UNW_REG_BSP
, /* register stack pointer */
81 UNW_REG_PFS
, /* previous function state */
86 /* Special preserved registers. */
87 UNW_REG_UNAT
, UNW_REG_PR
, UNW_REG_LC
, UNW_REG_FPSR
,
89 /* Non-stacked general registers. */
91 UNW_REG_R4
= UNW_REG_R2
+ 2,
92 UNW_REG_R7
= UNW_REG_R2
+ 5,
93 UNW_REG_R31
= UNW_REG_R2
+ 29,
95 /* Non-stacked floating point registers. */
97 UNW_REG_F5
= UNW_REG_F2
+ 3,
98 UNW_REG_F16
= UNW_REG_F2
+ 14,
99 UNW_REG_F31
= UNW_REG_F2
+ 29,
101 /* Branch registers. */
102 UNW_REG_B0
, UNW_REG_B1
,
103 UNW_REG_B5
= UNW_REG_B1
+ 4,
110 UNW_WHERE_NONE
, /* register isn't saved at all */
111 UNW_WHERE_GR
, /* register is saved in a general register */
112 UNW_WHERE_FR
, /* register is saved in a floating-point register */
113 UNW_WHERE_BR
, /* register is saved in a branch register */
114 UNW_WHERE_SPREL
, /* register is saved on memstack (sp-relative) */
115 UNW_WHERE_PSPREL
, /* register is saved on memstack (psp-relative) */
117 /* At the end of each prologue these locations get resolved to
118 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
119 UNW_WHERE_SPILL_HOME
, /* register is saved in its spill home */
120 UNW_WHERE_GR_SAVE
/* register is saved in next general register */
123 #define UNW_WHEN_NEVER 0x7fffffff
127 unsigned long val
; /* save location: register number or offset */
128 enum unw_where where
; /* where the register gets saved */
129 int when
; /* when the register gets saved */
132 struct unw_reg_state
{
133 struct unw_reg_state
*next
; /* next (outer) element on state stack */
134 struct unw_reg_info reg
[UNW_NUM_REGS
]; /* register save locations */
137 struct unw_labeled_state
{
138 struct unw_labeled_state
*next
; /* next labeled state (or NULL) */
139 unsigned long label
; /* label for this state */
140 struct unw_reg_state saved_state
;
143 typedef struct unw_state_record
145 unsigned int first_region
: 1; /* is this the first region? */
146 unsigned int done
: 1; /* are we done scanning descriptors? */
147 unsigned int any_spills
: 1; /* got any register spills? */
148 unsigned int in_body
: 1; /* are we inside a body? */
149 unsigned int no_reg_stack_frame
: 1; /* Don't adjust bsp for i&l regs */
150 unsigned char *imask
; /* imask of spill_mask record or NULL */
151 unsigned long pr_val
; /* predicate values */
152 unsigned long pr_mask
; /* predicate mask */
153 long spill_offset
; /* psp-relative offset for spill base */
160 unsigned char gr_save_loc
; /* next general register to use for saving */
161 unsigned char return_link_reg
; /* branch register for return link */
162 unsigned short unwabi
;
164 struct unw_labeled_state
*labeled_states
; /* list of all labeled states */
165 struct unw_reg_state curr
; /* current state */
167 _Unwind_Personality_Fn personality
;
169 } _Unwind_FrameState
;
173 UNW_NAT_NONE
, /* NaT not represented */
174 UNW_NAT_VAL
, /* NaT represented by NaT value (fp reg) */
175 UNW_NAT_MEMSTK
, /* NaT value is in unat word at offset OFF */
176 UNW_NAT_REGSTK
/* NaT is in rnat */
185 struct _Unwind_Context
187 /* Initial frame info. */
188 unsigned long rnat
; /* rse nat collection */
189 unsigned long regstk_top
; /* lowest address of rbs stored register
190 which uses context->rnat collection */
192 /* Current frame info. */
193 unsigned long bsp
; /* backing store pointer value
194 corresponding to psp. */
195 unsigned long sp
; /* stack pointer value */
196 unsigned long psp
; /* previous sp value */
197 unsigned long rp
; /* return pointer */
198 unsigned long pr
; /* predicate collection */
200 unsigned long region_start
; /* start of unwind region */
201 unsigned long gp
; /* global pointer value */
202 void *lsda
; /* language specific data area */
204 /* Preserved state. */
205 unsigned long *bsp_loc
; /* previous bsp save location
206 Appears to be write-only? */
207 unsigned long *bspstore_loc
;
208 unsigned long *pfs_loc
; /* Save location for pfs in current
209 (corr. to sp) frame. Target
210 contains cfm for caller. */
211 unsigned long *pri_unat_loc
;
212 unsigned long *unat_loc
;
213 unsigned long *lc_loc
;
214 unsigned long *fpsr_loc
;
216 unsigned long eh_data
[4];
223 enum unw_nat_type type
: 3;
224 signed long off
: 61; /* NaT word is at loc+nat.off */
226 } ireg
[32 - 2]; /* Indexed by <register number> - 2 */
228 unsigned long *br_loc
[8];
229 void *fr_loc
[32 - 2];
231 /* ??? We initially point pri_unat_loc here. The entire NAT bit
233 unsigned long initial_unat
;
236 typedef unsigned long unw_word
;
238 /* Implicit register save order. See section 11.4.2.3 Rules for Using
239 Unwind Descriptors, rule 3. */
241 static unsigned char const save_order
[] =
243 UNW_REG_RP
, UNW_REG_PFS
, UNW_REG_PSP
, UNW_REG_PR
,
244 UNW_REG_UNAT
, UNW_REG_LC
, UNW_REG_FPSR
, UNW_REG_PRI_UNAT_GR
248 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
250 /* MASK is a bitmap describing the allocation state of emergency buffers,
251 with bit set indicating free. Return >= 0 if allocation is successful;
255 atomic_alloc (unsigned int *mask
)
257 unsigned int old
= *mask
, ret
, new;
265 new = __sync_val_compare_and_swap (mask
, old
, new);
271 return __builtin_ffs (ret
) - 1;
274 /* Similarly, free an emergency buffer. */
277 atomic_free (unsigned int *mask
, int bit
)
279 __sync_xor_and_fetch (mask
, 1 << bit
);
283 #define SIZE(X) (sizeof(X) / sizeof(*(X)))
284 #define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
285 #define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
287 static struct unw_reg_state emergency_reg_state
[32];
288 static unsigned int emergency_reg_state_free
= MASK_FOR (emergency_reg_state
);
290 static struct unw_labeled_state emergency_labeled_state
[8];
291 static unsigned int emergency_labeled_state_free
= MASK_FOR (emergency_labeled_state
);
293 #ifdef ENABLE_MALLOC_CHECKING
294 static int reg_state_alloced
;
295 static int labeled_state_alloced
;
298 /* Allocation and deallocation of structures. */
300 static struct unw_reg_state
*
301 alloc_reg_state (void)
303 struct unw_reg_state
*rs
;
305 #ifdef ENABLE_MALLOC_CHECKING
309 rs
= malloc (sizeof (struct unw_reg_state
));
312 int n
= atomic_alloc (&emergency_reg_state_free
);
314 rs
= &emergency_reg_state
[n
];
321 free_reg_state (struct unw_reg_state
*rs
)
323 #ifdef ENABLE_MALLOC_CHECKING
327 if (PTR_IN (emergency_reg_state
, rs
))
328 atomic_free (&emergency_reg_state_free
, rs
- emergency_reg_state
);
333 static struct unw_labeled_state
*
334 alloc_label_state (void)
336 struct unw_labeled_state
*ls
;
338 #ifdef ENABLE_MALLOC_CHECKING
339 labeled_state_alloced
++;
342 ls
= malloc(sizeof(struct unw_labeled_state
));
345 int n
= atomic_alloc (&emergency_labeled_state_free
);
347 ls
= &emergency_labeled_state
[n
];
354 free_label_state (struct unw_labeled_state
*ls
)
356 #ifdef ENABLE_MALLOC_CHECKING
357 labeled_state_alloced
--;
360 if (PTR_IN (emergency_labeled_state
, ls
))
361 atomic_free (&emergency_labeled_state_free
, emergency_labeled_state
- ls
);
366 /* Routines to manipulate the state stack. */
369 push (struct unw_state_record
*sr
)
371 struct unw_reg_state
*rs
= alloc_reg_state ();
372 memcpy (rs
, &sr
->curr
, sizeof (*rs
));
377 pop (struct unw_state_record
*sr
)
379 struct unw_reg_state
*rs
= sr
->curr
.next
;
383 memcpy (&sr
->curr
, rs
, sizeof(*rs
));
387 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
389 static struct unw_reg_state
*
390 dup_state_stack (struct unw_reg_state
*rs
)
392 struct unw_reg_state
*copy
, *prev
= NULL
, *first
= NULL
;
396 copy
= alloc_reg_state ();
397 memcpy (copy
, rs
, sizeof(*copy
));
409 /* Free all stacked register states (but not RS itself). */
411 free_state_stack (struct unw_reg_state
*rs
)
413 struct unw_reg_state
*p
, *next
;
415 for (p
= rs
->next
; p
!= NULL
; p
= next
)
423 /* Free all labeled states. */
426 free_label_states (struct unw_labeled_state
*ls
)
428 struct unw_labeled_state
*next
;
430 for (; ls
; ls
= next
)
434 free_state_stack (&ls
->saved_state
);
435 free_label_state (ls
);
439 /* Unwind decoder routines */
441 static enum unw_register_index
__attribute__((const))
442 decode_abreg (unsigned char abreg
, int memory
)
446 case 0x04 ... 0x07: return UNW_REG_R4
+ (abreg
- 0x04);
447 case 0x22 ... 0x25: return UNW_REG_F2
+ (abreg
- 0x22);
448 case 0x30 ... 0x3f: return UNW_REG_F16
+ (abreg
- 0x30);
449 case 0x41 ... 0x45: return UNW_REG_B1
+ (abreg
- 0x41);
450 case 0x60: return UNW_REG_PR
;
451 case 0x61: return UNW_REG_PSP
;
452 case 0x62: return memory
? UNW_REG_PRI_UNAT_MEM
: UNW_REG_PRI_UNAT_GR
;
453 case 0x63: return UNW_REG_RP
;
454 case 0x64: return UNW_REG_BSP
;
455 case 0x65: return UNW_REG_BSPSTORE
;
456 case 0x66: return UNW_REG_RNAT
;
457 case 0x67: return UNW_REG_UNAT
;
458 case 0x68: return UNW_REG_FPSR
;
459 case 0x69: return UNW_REG_PFS
;
460 case 0x6a: return UNW_REG_LC
;
467 set_reg (struct unw_reg_info
*reg
, enum unw_where where
,
468 int when
, unsigned long val
)
472 if (reg
->when
== UNW_WHEN_NEVER
)
477 alloc_spill_area (unsigned long *offp
, unsigned long regsize
,
478 struct unw_reg_info
*lo
, struct unw_reg_info
*hi
)
480 struct unw_reg_info
*reg
;
482 for (reg
= hi
; reg
>= lo
; --reg
)
484 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
486 reg
->where
= UNW_WHERE_PSPREL
;
494 spill_next_when (struct unw_reg_info
**regp
, struct unw_reg_info
*lim
,
497 struct unw_reg_info
*reg
;
499 for (reg
= *regp
; reg
<= lim
; ++reg
)
501 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
513 finish_prologue (struct unw_state_record
*sr
)
515 struct unw_reg_info
*reg
;
519 /* First, resolve implicit register save locations
520 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
522 for (i
= 0; i
< (int) sizeof (save_order
); ++i
)
524 reg
= sr
->curr
.reg
+ save_order
[i
];
525 if (reg
->where
== UNW_WHERE_GR_SAVE
)
527 reg
->where
= UNW_WHERE_GR
;
528 reg
->val
= sr
->gr_save_loc
++;
532 /* Next, compute when the fp, general, and branch registers get saved.
533 This must come before alloc_spill_area() because we need to know
534 which registers are spilled to their home locations. */
537 static unsigned char const limit
[3] = {
538 UNW_REG_F31
, UNW_REG_R7
, UNW_REG_B5
541 unsigned char kind
, mask
= 0, *cp
= sr
->imask
;
543 struct unw_reg_info
*(regs
[3]);
545 regs
[0] = sr
->curr
.reg
+ UNW_REG_F2
;
546 regs
[1] = sr
->curr
.reg
+ UNW_REG_R4
;
547 regs
[2] = sr
->curr
.reg
+ UNW_REG_B1
;
549 for (t
= 0; t
< sr
->region_len
; ++t
)
553 kind
= (mask
>> 2*(3-(t
& 3))) & 3;
555 spill_next_when (®s
[kind
- 1], sr
->curr
.reg
+ limit
[kind
- 1],
556 sr
->region_start
+ t
);
560 /* Next, lay out the memory stack spill area. */
563 off
= sr
->spill_offset
;
564 alloc_spill_area (&off
, 16, sr
->curr
.reg
+ UNW_REG_F2
,
565 sr
->curr
.reg
+ UNW_REG_F31
);
566 alloc_spill_area (&off
, 8, sr
->curr
.reg
+ UNW_REG_B1
,
567 sr
->curr
.reg
+ UNW_REG_B5
);
568 alloc_spill_area (&off
, 8, sr
->curr
.reg
+ UNW_REG_R4
,
569 sr
->curr
.reg
+ UNW_REG_R7
);
574 * Region header descriptors.
578 desc_prologue (int body
, unw_word rlen
, unsigned char mask
,
579 unsigned char grsave
, struct unw_state_record
*sr
)
583 if (!(sr
->in_body
|| sr
->first_region
))
584 finish_prologue (sr
);
585 sr
->first_region
= 0;
587 /* Check if we're done. */
588 if (sr
->when_target
< sr
->region_start
+ sr
->region_len
)
594 for (i
= 0; i
< sr
->epilogue_count
; ++i
)
597 sr
->epilogue_count
= 0;
598 sr
->epilogue_start
= UNW_WHEN_NEVER
;
603 sr
->region_start
+= sr
->region_len
;
604 sr
->region_len
= rlen
;
609 for (i
= 0; i
< 4; ++i
)
612 set_reg (sr
->curr
.reg
+ save_order
[i
], UNW_WHERE_GR
,
613 sr
->region_start
+ sr
->region_len
- 1, grsave
++);
616 sr
->gr_save_loc
= grsave
;
619 sr
->spill_offset
= 0x10; /* default to psp+16 */
624 * Prologue descriptors.
628 desc_abi (unsigned char abi
,
629 unsigned char context
,
630 struct unw_state_record
*sr
)
632 sr
->unwabi
= (abi
<< 8) | context
;
636 desc_br_gr (unsigned char brmask
, unsigned char gr
,
637 struct unw_state_record
*sr
)
641 for (i
= 0; i
< 5; ++i
)
644 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_GR
,
645 sr
->region_start
+ sr
->region_len
- 1, gr
++);
651 desc_br_mem (unsigned char brmask
, struct unw_state_record
*sr
)
655 for (i
= 0; i
< 5; ++i
)
659 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_SPILL_HOME
,
660 sr
->region_start
+ sr
->region_len
- 1, 0);
668 desc_frgr_mem (unsigned char grmask
, unw_word frmask
,
669 struct unw_state_record
*sr
)
673 for (i
= 0; i
< 4; ++i
)
675 if ((grmask
& 1) != 0)
677 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
678 sr
->region_start
+ sr
->region_len
- 1, 0);
683 for (i
= 0; i
< 20; ++i
)
685 if ((frmask
& 1) != 0)
687 enum unw_register_index base
= i
< 4 ? UNW_REG_F2
: UNW_REG_F16
- 4;
688 set_reg (sr
->curr
.reg
+ base
+ i
, UNW_WHERE_SPILL_HOME
,
689 sr
->region_start
+ sr
->region_len
- 1, 0);
697 desc_fr_mem (unsigned char frmask
, struct unw_state_record
*sr
)
701 for (i
= 0; i
< 4; ++i
)
703 if ((frmask
& 1) != 0)
705 set_reg (sr
->curr
.reg
+ UNW_REG_F2
+ i
, UNW_WHERE_SPILL_HOME
,
706 sr
->region_start
+ sr
->region_len
- 1, 0);
714 desc_gr_gr (unsigned char grmask
, unsigned char gr
,
715 struct unw_state_record
*sr
)
719 for (i
= 0; i
< 4; ++i
)
721 if ((grmask
& 1) != 0)
722 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_GR
,
723 sr
->region_start
+ sr
->region_len
- 1, gr
++);
729 desc_gr_mem (unsigned char grmask
, struct unw_state_record
*sr
)
733 for (i
= 0; i
< 4; ++i
)
735 if ((grmask
& 1) != 0)
737 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
738 sr
->region_start
+ sr
->region_len
- 1, 0);
746 desc_mem_stack_f (unw_word t
, unw_word size
, struct unw_state_record
*sr
)
748 set_reg (sr
->curr
.reg
+ UNW_REG_PSP
, UNW_WHERE_NONE
,
749 sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1), 16*size
);
753 desc_mem_stack_v (unw_word t
, struct unw_state_record
*sr
)
755 sr
->curr
.reg
[UNW_REG_PSP
].when
756 = sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
760 desc_reg_gr (unsigned char reg
, unsigned char dst
, struct unw_state_record
*sr
)
762 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_GR
,
763 sr
->region_start
+ sr
->region_len
- 1, dst
);
767 desc_reg_psprel (unsigned char reg
, unw_word pspoff
,
768 struct unw_state_record
*sr
)
770 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_PSPREL
,
771 sr
->region_start
+ sr
->region_len
- 1,
776 desc_reg_sprel (unsigned char reg
, unw_word spoff
, struct unw_state_record
*sr
)
778 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_SPREL
,
779 sr
->region_start
+ sr
->region_len
- 1,
784 desc_rp_br (unsigned char dst
, struct unw_state_record
*sr
)
786 sr
->return_link_reg
= dst
;
790 desc_reg_when (unsigned char regnum
, unw_word t
, struct unw_state_record
*sr
)
792 struct unw_reg_info
*reg
= sr
->curr
.reg
+ regnum
;
794 if (reg
->where
== UNW_WHERE_NONE
)
795 reg
->where
= UNW_WHERE_GR_SAVE
;
796 reg
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
800 desc_spill_base (unw_word pspoff
, struct unw_state_record
*sr
)
802 sr
->spill_offset
= 0x10 - 4*pspoff
;
805 static inline unsigned char *
806 desc_spill_mask (unsigned char *imaskp
, struct unw_state_record
*sr
)
809 return imaskp
+ (2*sr
->region_len
+ 7)/8;
816 desc_epilogue (unw_word t
, unw_word ecount
, struct unw_state_record
*sr
)
818 sr
->epilogue_start
= sr
->region_start
+ sr
->region_len
- 1 - t
;
819 sr
->epilogue_count
= ecount
+ 1;
823 desc_copy_state (unw_word label
, struct unw_state_record
*sr
)
825 struct unw_labeled_state
*ls
;
827 for (ls
= sr
->labeled_states
; ls
; ls
= ls
->next
)
829 if (ls
->label
== label
)
831 free_state_stack (&sr
->curr
);
832 memcpy (&sr
->curr
, &ls
->saved_state
, sizeof (sr
->curr
));
833 sr
->curr
.next
= dup_state_stack (ls
->saved_state
.next
);
841 desc_label_state (unw_word label
, struct unw_state_record
*sr
)
843 struct unw_labeled_state
*ls
= alloc_label_state ();
846 memcpy (&ls
->saved_state
, &sr
->curr
, sizeof (ls
->saved_state
));
847 ls
->saved_state
.next
= dup_state_stack (sr
->curr
.next
);
849 /* Insert into list of labeled states. */
850 ls
->next
= sr
->labeled_states
;
851 sr
->labeled_states
= ls
;
855 * General descriptors.
859 desc_is_active (unsigned char qp
, unw_word t
, struct unw_state_record
*sr
)
861 if (sr
->when_target
<= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1))
865 if ((sr
->pr_val
& (1UL << qp
)) == 0)
867 sr
->pr_mask
|= (1UL << qp
);
873 desc_restore_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
874 struct unw_state_record
*sr
)
876 struct unw_reg_info
*r
;
878 if (! desc_is_active (qp
, t
, sr
))
881 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
882 r
->where
= UNW_WHERE_NONE
;
883 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
888 desc_spill_reg_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
889 unsigned char x
, unsigned char ytreg
,
890 struct unw_state_record
*sr
)
892 enum unw_where where
= UNW_WHERE_GR
;
893 struct unw_reg_info
*r
;
895 if (! desc_is_active (qp
, t
, sr
))
899 where
= UNW_WHERE_BR
;
900 else if (ytreg
& 0x80)
901 where
= UNW_WHERE_FR
;
903 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
905 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
906 r
->val
= ytreg
& 0x7f;
910 desc_spill_psprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
911 unw_word pspoff
, struct unw_state_record
*sr
)
913 struct unw_reg_info
*r
;
915 if (! desc_is_active (qp
, t
, sr
))
918 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
919 r
->where
= UNW_WHERE_PSPREL
;
920 r
->when
= sr
->region_start
+ MIN((int)t
, sr
->region_len
- 1);
921 r
->val
= 0x10 - 4*pspoff
;
925 desc_spill_sprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
926 unw_word spoff
, struct unw_state_record
*sr
)
928 struct unw_reg_info
*r
;
930 if (! desc_is_active (qp
, t
, sr
))
933 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
934 r
->where
= UNW_WHERE_SPREL
;
935 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
940 #define UNW_DEC_BAD_CODE(code) abort ();
942 /* Region headers. */
943 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
944 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
946 /* Prologue descriptors. */
947 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
948 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
949 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
950 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
951 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
952 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
953 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
954 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
955 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
956 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
957 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
958 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
959 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
960 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
961 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
962 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
963 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
964 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
965 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
966 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
967 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
969 /* Body descriptors. */
970 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
971 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
972 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
974 /* General unwind descriptors. */
975 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
976 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
977 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
978 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
979 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
980 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
981 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
982 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
986 * Generic IA-64 unwind info decoder.
988 * This file is used both by the Linux kernel and objdump. Please keep
989 * the copies of this file in sync.
991 * You need to customize the decoder by defining the following
992 * macros/constants before including this file:
995 * unw_word Unsigned integer type with at least 64 bits
1009 * Decoder action macros:
1010 * UNW_DEC_BAD_CODE(code)
1011 * UNW_DEC_ABI(fmt,abi,context,arg)
1012 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
1013 * UNW_DEC_BR_MEM(fmt,brmask,arg)
1014 * UNW_DEC_COPY_STATE(fmt,label,arg)
1015 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
1016 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
1017 * UNW_DEC_FR_MEM(fmt,frmask,arg)
1018 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
1019 * UNW_DEC_GR_MEM(fmt,grmask,arg)
1020 * UNW_DEC_LABEL_STATE(fmt,label,arg)
1021 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
1022 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
1023 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
1024 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
1025 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
1026 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
1027 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
1028 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
1029 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
1030 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
1031 * UNW_DEC_REG_REG(fmt,src,dst,arg)
1032 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
1033 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
1034 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
1035 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
1036 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
1037 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
1038 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
1039 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
1040 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
1041 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
1042 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
1043 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
1047 unw_decode_uleb128 (unsigned char **dpp
)
1050 unw_word byte
, result
= 0;
1051 unsigned char *bp
= *dpp
;
1056 result
|= (byte
& 0x7f) << shift
;
1057 if ((byte
& 0x80) == 0)
1065 static unsigned char *
1066 unw_decode_x1 (unsigned char *dp
,
1067 unsigned char code
__attribute__((unused
)),
1070 unsigned char byte1
, abreg
;
1074 t
= unw_decode_uleb128 (&dp
);
1075 off
= unw_decode_uleb128 (&dp
);
1076 abreg
= (byte1
& 0x7f);
1078 UNW_DEC_SPILL_SPREL(X1
, t
, abreg
, off
, arg
);
1080 UNW_DEC_SPILL_PSPREL(X1
, t
, abreg
, off
, arg
);
1084 static unsigned char *
1085 unw_decode_x2 (unsigned char *dp
,
1086 unsigned char code
__attribute__((unused
)),
1089 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
1092 byte1
= *dp
++; byte2
= *dp
++;
1093 t
= unw_decode_uleb128 (&dp
);
1094 abreg
= (byte1
& 0x7f);
1096 x
= (byte1
>> 7) & 1;
1097 if ((byte1
& 0x80) == 0 && ytreg
== 0)
1098 UNW_DEC_RESTORE(X2
, t
, abreg
, arg
);
1100 UNW_DEC_SPILL_REG(X2
, t
, abreg
, x
, ytreg
, arg
);
1104 static unsigned char *
1105 unw_decode_x3 (unsigned char *dp
,
1106 unsigned char code
__attribute__((unused
)),
1109 unsigned char byte1
, byte2
, abreg
, qp
;
1112 byte1
= *dp
++; byte2
= *dp
++;
1113 t
= unw_decode_uleb128 (&dp
);
1114 off
= unw_decode_uleb128 (&dp
);
1116 qp
= (byte1
& 0x3f);
1117 abreg
= (byte2
& 0x7f);
1120 UNW_DEC_SPILL_SPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
1122 UNW_DEC_SPILL_PSPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
1126 static unsigned char *
1127 unw_decode_x4 (unsigned char *dp
,
1128 unsigned char code
__attribute__((unused
)),
1131 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
1134 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
1135 t
= unw_decode_uleb128 (&dp
);
1137 qp
= (byte1
& 0x3f);
1138 abreg
= (byte2
& 0x7f);
1139 x
= (byte2
>> 7) & 1;
1142 if ((byte2
& 0x80) == 0 && byte3
== 0)
1143 UNW_DEC_RESTORE_P(X4
, qp
, t
, abreg
, arg
);
1145 UNW_DEC_SPILL_REG_P(X4
, qp
, t
, abreg
, x
, ytreg
, arg
);
1149 static unsigned char *
1150 unw_decode_r1 (unsigned char *dp
, unsigned char code
, void *arg
)
1152 int body
= (code
& 0x20) != 0;
1155 rlen
= (code
& 0x1f);
1156 UNW_DEC_PROLOGUE(R1
, body
, rlen
, arg
);
1160 static unsigned char *
1161 unw_decode_r2 (unsigned char *dp
, unsigned char code
, void *arg
)
1163 unsigned char byte1
, mask
, grsave
;
1168 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
1169 grsave
= (byte1
& 0x7f);
1170 rlen
= unw_decode_uleb128 (&dp
);
1171 UNW_DEC_PROLOGUE_GR(R2
, rlen
, mask
, grsave
, arg
);
1175 static unsigned char *
1176 unw_decode_r3 (unsigned char *dp
, unsigned char code
, void *arg
)
1180 rlen
= unw_decode_uleb128 (&dp
);
1181 UNW_DEC_PROLOGUE(R3
, ((code
& 0x3) == 1), rlen
, arg
);
1185 static unsigned char *
1186 unw_decode_p1 (unsigned char *dp
, unsigned char code
, void *arg
)
1188 unsigned char brmask
= (code
& 0x1f);
1190 UNW_DEC_BR_MEM(P1
, brmask
, arg
);
1194 static unsigned char *
1195 unw_decode_p2_p5 (unsigned char *dp
, unsigned char code
, void *arg
)
1197 if ((code
& 0x10) == 0)
1199 unsigned char byte1
= *dp
++;
1201 UNW_DEC_BR_GR(P2
, ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
1202 (byte1
& 0x7f), arg
);
1204 else if ((code
& 0x08) == 0)
1206 unsigned char byte1
= *dp
++, r
, dst
;
1208 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
1209 dst
= (byte1
& 0x7f);
1212 case 0: UNW_DEC_REG_GR(P3
, UNW_REG_PSP
, dst
, arg
); break;
1213 case 1: UNW_DEC_REG_GR(P3
, UNW_REG_RP
, dst
, arg
); break;
1214 case 2: UNW_DEC_REG_GR(P3
, UNW_REG_PFS
, dst
, arg
); break;
1215 case 3: UNW_DEC_REG_GR(P3
, UNW_REG_PR
, dst
, arg
); break;
1216 case 4: UNW_DEC_REG_GR(P3
, UNW_REG_UNAT
, dst
, arg
); break;
1217 case 5: UNW_DEC_REG_GR(P3
, UNW_REG_LC
, dst
, arg
); break;
1218 case 6: UNW_DEC_RP_BR(P3
, dst
, arg
); break;
1219 case 7: UNW_DEC_REG_GR(P3
, UNW_REG_RNAT
, dst
, arg
); break;
1220 case 8: UNW_DEC_REG_GR(P3
, UNW_REG_BSP
, dst
, arg
); break;
1221 case 9: UNW_DEC_REG_GR(P3
, UNW_REG_BSPSTORE
, dst
, arg
); break;
1222 case 10: UNW_DEC_REG_GR(P3
, UNW_REG_FPSR
, dst
, arg
); break;
1223 case 11: UNW_DEC_PRIUNAT_GR(P3
, dst
, arg
); break;
1224 default: UNW_DEC_BAD_CODE(r
); break;
1227 else if ((code
& 0x7) == 0)
1228 UNW_DEC_SPILL_MASK(P4
, dp
, arg
);
1229 else if ((code
& 0x7) == 1)
1231 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
1233 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
1234 grmask
= ((byte1
>> 4) & 0xf);
1235 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
1236 UNW_DEC_FRGR_MEM(P5
, grmask
, frmask
, arg
);
1239 UNW_DEC_BAD_CODE(code
);
1243 static unsigned char *
1244 unw_decode_p6 (unsigned char *dp
, unsigned char code
, void *arg
)
1246 int gregs
= (code
& 0x10) != 0;
1247 unsigned char mask
= (code
& 0x0f);
1250 UNW_DEC_GR_MEM(P6
, mask
, arg
);
1252 UNW_DEC_FR_MEM(P6
, mask
, arg
);
1256 static unsigned char *
1257 unw_decode_p7_p10 (unsigned char *dp
, unsigned char code
, void *arg
)
1259 unsigned char r
, byte1
, byte2
;
1262 if ((code
& 0x10) == 0)
1265 t
= unw_decode_uleb128 (&dp
);
1269 size
= unw_decode_uleb128 (&dp
);
1270 UNW_DEC_MEM_STACK_F(P7
, t
, size
, arg
);
1273 case 1: UNW_DEC_MEM_STACK_V(P7
, t
, arg
); break;
1274 case 2: UNW_DEC_SPILL_BASE(P7
, t
, arg
); break;
1275 case 3: UNW_DEC_REG_SPREL(P7
, UNW_REG_PSP
, t
, arg
); break;
1276 case 4: UNW_DEC_REG_WHEN(P7
, UNW_REG_RP
, t
, arg
); break;
1277 case 5: UNW_DEC_REG_PSPREL(P7
, UNW_REG_RP
, t
, arg
); break;
1278 case 6: UNW_DEC_REG_WHEN(P7
, UNW_REG_PFS
, t
, arg
); break;
1279 case 7: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PFS
, t
, arg
); break;
1280 case 8: UNW_DEC_REG_WHEN(P7
, UNW_REG_PR
, t
, arg
); break;
1281 case 9: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PR
, t
, arg
); break;
1282 case 10: UNW_DEC_REG_WHEN(P7
, UNW_REG_LC
, t
, arg
); break;
1283 case 11: UNW_DEC_REG_PSPREL(P7
, UNW_REG_LC
, t
, arg
); break;
1284 case 12: UNW_DEC_REG_WHEN(P7
, UNW_REG_UNAT
, t
, arg
); break;
1285 case 13: UNW_DEC_REG_PSPREL(P7
, UNW_REG_UNAT
, t
, arg
); break;
1286 case 14: UNW_DEC_REG_WHEN(P7
, UNW_REG_FPSR
, t
, arg
); break;
1287 case 15: UNW_DEC_REG_PSPREL(P7
, UNW_REG_FPSR
, t
, arg
); break;
1288 default: UNW_DEC_BAD_CODE(r
); break;
1298 t
= unw_decode_uleb128 (&dp
);
1301 case 1: UNW_DEC_REG_SPREL(P8
, UNW_REG_RP
, t
, arg
); break;
1302 case 2: UNW_DEC_REG_SPREL(P8
, UNW_REG_PFS
, t
, arg
); break;
1303 case 3: UNW_DEC_REG_SPREL(P8
, UNW_REG_PR
, t
, arg
); break;
1304 case 4: UNW_DEC_REG_SPREL(P8
, UNW_REG_LC
, t
, arg
); break;
1305 case 5: UNW_DEC_REG_SPREL(P8
, UNW_REG_UNAT
, t
, arg
); break;
1306 case 6: UNW_DEC_REG_SPREL(P8
, UNW_REG_FPSR
, t
, arg
); break;
1307 case 7: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSP
, t
, arg
); break;
1308 case 8: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1309 case 9: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1310 case 10: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1311 case 11: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1312 case 12: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1313 case 13: UNW_DEC_REG_WHEN(P8
, UNW_REG_RNAT
, t
, arg
); break;
1314 case 14: UNW_DEC_REG_PSPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1315 case 15: UNW_DEC_REG_SPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1316 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8
, t
, arg
); break;
1317 case 17: UNW_DEC_PRIUNAT_PSPREL(P8
, t
, arg
); break;
1318 case 18: UNW_DEC_PRIUNAT_SPREL(P8
, t
, arg
); break;
1319 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8
, t
, arg
); break;
1320 default: UNW_DEC_BAD_CODE(r
); break;
1326 byte1
= *dp
++; byte2
= *dp
++;
1327 UNW_DEC_GR_GR(P9
, (byte1
& 0xf), (byte2
& 0x7f), arg
);
1331 byte1
= *dp
++; byte2
= *dp
++;
1332 UNW_DEC_ABI(P10
, byte1
, byte2
, arg
);
1336 return unw_decode_x1 (dp
, code
, arg
);
1339 return unw_decode_x2 (dp
, code
, arg
);
1342 return unw_decode_x3 (dp
, code
, arg
);
1345 return unw_decode_x4 (dp
, code
, arg
);
1348 UNW_DEC_BAD_CODE(code
);
1355 static unsigned char *
1356 unw_decode_b1 (unsigned char *dp
, unsigned char code
, void *arg
)
1358 unw_word label
= (code
& 0x1f);
1360 if ((code
& 0x20) != 0)
1361 UNW_DEC_COPY_STATE(B1
, label
, arg
);
1363 UNW_DEC_LABEL_STATE(B1
, label
, arg
);
1367 static unsigned char *
1368 unw_decode_b2 (unsigned char *dp
, unsigned char code
, void *arg
)
1372 t
= unw_decode_uleb128 (&dp
);
1373 UNW_DEC_EPILOGUE(B2
, t
, (code
& 0x1f), arg
);
1377 static unsigned char *
1378 unw_decode_b3_x4 (unsigned char *dp
, unsigned char code
, void *arg
)
1380 unw_word t
, ecount
, label
;
1382 if ((code
& 0x10) == 0)
1384 t
= unw_decode_uleb128 (&dp
);
1385 ecount
= unw_decode_uleb128 (&dp
);
1386 UNW_DEC_EPILOGUE(B3
, t
, ecount
, arg
);
1388 else if ((code
& 0x07) == 0)
1390 label
= unw_decode_uleb128 (&dp
);
1391 if ((code
& 0x08) != 0)
1392 UNW_DEC_COPY_STATE(B4
, label
, arg
);
1394 UNW_DEC_LABEL_STATE(B4
, label
, arg
);
1399 case 1: return unw_decode_x1 (dp
, code
, arg
);
1400 case 2: return unw_decode_x2 (dp
, code
, arg
);
1401 case 3: return unw_decode_x3 (dp
, code
, arg
);
1402 case 4: return unw_decode_x4 (dp
, code
, arg
);
1403 default: UNW_DEC_BAD_CODE(code
); break;
1408 typedef unsigned char *(*unw_decoder
) (unsigned char *, unsigned char, void *);
1410 static const unw_decoder unw_decode_table
[2][8] =
1412 /* prologue table: */
1414 unw_decode_r1
, /* 0 */
1418 unw_decode_p1
, /* 4 */
1424 unw_decode_r1
, /* 0 */
1428 unw_decode_b1
, /* 4 */
1436 * Decode one descriptor and return address of next descriptor.
1438 static inline unsigned char *
1439 unw_decode (unsigned char *dp
, int inside_body
, void *arg
)
1441 unw_decoder decoder
;
1445 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1446 dp
= (*decoder
) (dp
, code
, arg
);
1451 /* RSE helper functions. */
1453 static inline unsigned long
1454 ia64_rse_slot_num (unsigned long *addr
)
1456 return (((unsigned long) addr
) >> 3) & 0x3f;
1459 /* Return TRUE if ADDR is the address of an RNAT slot. */
1460 static inline unsigned long
1461 ia64_rse_is_rnat_slot (unsigned long *addr
)
1463 return ia64_rse_slot_num (addr
) == 0x3f;
1466 /* Returns the address of the RNAT slot that covers the slot at
1467 address SLOT_ADDR. */
1468 static inline unsigned long *
1469 ia64_rse_rnat_addr (unsigned long *slot_addr
)
1471 return (unsigned long *) ((unsigned long) slot_addr
| (0x3f << 3));
1474 /* Calculate the number of registers in the dirty partition starting at
1475 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1476 divided by eight because the 64th slot is used to store ar.rnat. */
1477 static inline unsigned long
1478 ia64_rse_num_regs (unsigned long *bspstore
, unsigned long *bsp
)
1480 unsigned long slots
= (bsp
- bspstore
);
1482 return slots
- (ia64_rse_slot_num (bspstore
) + slots
)/0x40;
1485 /* The inverse of the above: given bspstore and the number of
1486 registers, calculate ar.bsp. */
1487 static inline unsigned long *
1488 ia64_rse_skip_regs (unsigned long *addr
, long num_regs
)
1490 long delta
= ia64_rse_slot_num (addr
) + num_regs
;
1494 return addr
+ num_regs
+ delta
/0x3f;
1498 /* Copy register backing store from SRC to DST, LEN words
1499 (which include both saved registers and nat collections).
1500 DST_RNAT is a partial nat collection for DST. SRC and DST
1501 don't have to be equal modulo 64 slots, so it cannot be
1502 done with a simple memcpy as the nat collections will be
1503 at different relative offsets and need to be combined together. */
1505 ia64_copy_rbs (struct _Unwind_Context
*info
, unsigned long dst
,
1506 unsigned long src
, long len
, unsigned long dst_rnat
)
1509 unsigned long src_rnat
;
1510 unsigned long shift1
, shift2
;
1513 dst_rnat
&= (1UL << ((dst
>> 3) & 0x3f)) - 1;
1514 src_rnat
= src
>= info
->regstk_top
1515 ? info
->rnat
: *(unsigned long *) (src
| 0x1f8);
1516 src_rnat
&= ~((1UL << ((src
>> 3) & 0x3f)) - 1);
1517 /* Just to make sure. */
1518 src_rnat
&= ~(1UL << 63);
1519 shift1
= ((dst
- src
) >> 3) & 0x3f;
1520 if ((dst
& 0x1f8) < (src
& 0x1f8))
1522 shift2
= 0x3f - shift1
;
1523 if ((dst
& 0x1f8) >= (src
& 0x1f8))
1525 count
= ~dst
& 0x1f8;
1528 count
= ~src
& 0x1f8;
1532 src_rnat
= src
>= info
->regstk_top
1533 ? info
->rnat
: *(unsigned long *) (src
| 0x1f8);
1534 /* Just to make sure. */
1535 src_rnat
&= ~(1UL << 63);
1536 count
= shift2
<< 3;
1540 memcpy ((char *) dst
, (char *) src
, count
);
1544 dst_rnat
|= (src_rnat
<< shift1
) & ~(1UL << 63);
1547 *(long *) dst
= dst_rnat
;
1550 count
= shift1
<< 3;
1554 memcpy ((char *) dst
, (char *) src
, count
);
1558 dst_rnat
|= (src_rnat
>> shift2
);
1560 if ((dst
& 0x1f8) == 0x1f8)
1562 *(long *) dst
= dst_rnat
;
1566 /* Set info->regstk_top to lowest rbs address which will use
1567 info->rnat collection. */
1568 info
->regstk_top
= dst
& ~0x1ffUL
;
1569 info
->rnat
= dst_rnat
;
1572 /* Unwind accessors. */
1575 unw_access_gr (struct _Unwind_Context
*info
, int regnum
,
1576 unsigned long *val
, char *nat
, int write
)
1578 unsigned long *addr
, *nat_addr
= 0, nat_mask
= 0, dummy_nat
;
1579 struct unw_ireg
*ireg
;
1581 if ((unsigned) regnum
- 1 >= 127)
1586 nat_addr
= addr
= &dummy_nat
;
1589 else if (regnum
< 32)
1591 /* Access a non-stacked register. */
1592 ireg
= &info
->ireg
[regnum
- 2];
1596 nat_addr
= addr
+ ireg
->nat
.off
;
1597 switch (ireg
->nat
.type
)
1600 /* Simulate getf.sig/setf.sig. */
1605 /* Write NaTVal and be done with it. */
1612 else if (addr
[0] == 0 && addr
[1] == 0x1ffe)
1614 /* Return NaT and be done with it. */
1623 nat_addr
= &dummy_nat
;
1626 case UNW_NAT_MEMSTK
:
1627 nat_mask
= 1UL << ((long) addr
& 0x1f8)/8;
1630 case UNW_NAT_REGSTK
:
1631 if ((unsigned long) addr
>= info
->regstk_top
)
1632 nat_addr
= &info
->rnat
;
1634 nat_addr
= ia64_rse_rnat_addr (addr
);
1635 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1642 /* Access a stacked register. */
1643 addr
= ia64_rse_skip_regs ((unsigned long *) info
->bsp
, regnum
- 32);
1644 if ((unsigned long) addr
>= info
->regstk_top
)
1645 nat_addr
= &info
->rnat
;
1647 nat_addr
= ia64_rse_rnat_addr (addr
);
1648 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1655 *nat_addr
|= nat_mask
;
1657 *nat_addr
&= ~nat_mask
;
1662 *nat
= (*nat_addr
& nat_mask
) != 0;
1666 /* Get the value of register REG as saved in CONTEXT. */
1669 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
1676 else if (index
>= 15 && index
<= 18)
1677 return context
->eh_data
[index
- 15];
1679 unw_access_gr (context
, index
, &ret
, &nat
, 0);
1684 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1687 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
1693 else if (index
>= 15 && index
<= 18)
1694 context
->eh_data
[index
- 15] = val
;
1696 unw_access_gr (context
, index
, &val
, &nat
, 1);
1699 /* Retrieve the return address for CONTEXT. */
1702 _Unwind_GetIP (struct _Unwind_Context
*context
)
1707 /* Overwrite the return address for CONTEXT with VAL. */
1710 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
1716 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
1718 return context
->lsda
;
1722 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
1724 return context
->region_start
;
1728 _Unwind_FindEnclosingFunction (void *pc
)
1730 struct unw_table_entry
*ent
;
1731 unsigned long segment_base
, gp
;
1733 ent
= _Unwind_FindTableEntry (pc
, &segment_base
, &gp
);
1737 return (void *)(segment_base
+ ent
->start_offset
);
1740 /* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance,
1741 the CFA is the value of the stack pointer on entry; In IA-64 unwind
1742 parlance, this is the PSP. */
1745 _Unwind_GetCFA (struct _Unwind_Context
*context
)
1747 return (_Unwind_Ptr
) context
->psp
;
1750 /* Get the value of the Backing Store Pointer as saved in CONTEXT. */
1753 _Unwind_GetBSP (struct _Unwind_Context
*context
)
1755 return (_Unwind_Ptr
) context
->bsp
;
1758 #ifdef MD_UNWIND_SUPPORT
1759 #include MD_UNWIND_SUPPORT
1762 static _Unwind_Reason_Code
1763 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1765 struct unw_table_entry
*ent
;
1766 unsigned long *unw
, header
, length
;
1767 unsigned char *insn
, *insn_end
;
1768 unsigned long segment_base
;
1769 struct unw_reg_info
*r
;
1771 memset (fs
, 0, sizeof (*fs
));
1772 for (r
= fs
->curr
.reg
; r
< fs
->curr
.reg
+ UNW_NUM_REGS
; ++r
)
1773 r
->when
= UNW_WHEN_NEVER
;
1776 ent
= _Unwind_FindTableEntry ((void *) context
->rp
,
1777 &segment_base
, &context
->gp
);
1780 /* Couldn't find unwind info for this function. Try an
1781 os-specific fallback mechanism. This will necessarily
1782 not provide a personality routine or LSDA. */
1783 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1784 if (MD_FALLBACK_FRAME_STATE_FOR (context
, fs
) == _URC_NO_REASON
)
1785 return _URC_NO_REASON
;
1787 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1788 handlers, and which keeps the return value in B0 does not need
1789 an unwind table entry.
1791 This can only happen in the frame after unwinding through a signal
1792 handler. Avoid infinite looping by requiring that B0 != RP.
1793 RP == 0 terminates the chain. */
1794 if (context
->br_loc
[0] && *context
->br_loc
[0] != context
->rp
1795 && context
->rp
!= 0)
1797 fs
->curr
.reg
[UNW_REG_RP
].where
= UNW_WHERE_BR
;
1798 fs
->curr
.reg
[UNW_REG_RP
].when
= -1;
1799 fs
->curr
.reg
[UNW_REG_RP
].val
= 0;
1800 return _URC_NO_REASON
;
1803 return _URC_END_OF_STACK
;
1806 context
->region_start
= ent
->start_offset
+ segment_base
;
1807 fs
->when_target
= ((context
->rp
& -16) - context
->region_start
) / 16 * 3
1808 + (context
->rp
& 15);
1810 unw
= (unsigned long *) (ent
->info_offset
+ segment_base
);
1812 length
= UNW_LENGTH (header
);
1814 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */
1816 if (UNW_FLAG_EHANDLER (header
) | UNW_FLAG_UHANDLER (header
))
1819 *(_Unwind_Personality_Fn
*) (unw
[length
+ 1] + context
->gp
);
1820 context
->lsda
= unw
+ length
+ 2;
1823 insn
= (unsigned char *) (unw
+ 1);
1824 insn_end
= (unsigned char *) (unw
+ 1 + length
);
1825 while (!fs
->done
&& insn
< insn_end
)
1826 insn
= unw_decode (insn
, fs
->in_body
, fs
);
1828 free_label_states (fs
->labeled_states
);
1829 free_state_stack (&fs
->curr
);
1831 #ifdef ENABLE_MALLOC_CHECKING
1832 if (reg_state_alloced
|| labeled_state_alloced
)
1836 /* If we're in the epilogue, sp has been restored and all values
1837 on the memory stack below psp also have been restored. */
1838 if (fs
->when_target
> fs
->epilogue_start
)
1840 struct unw_reg_info
*r
;
1842 fs
->curr
.reg
[UNW_REG_PSP
].where
= UNW_WHERE_NONE
;
1843 fs
->curr
.reg
[UNW_REG_PSP
].val
= 0;
1844 for (r
= fs
->curr
.reg
; r
< fs
->curr
.reg
+ UNW_NUM_REGS
; ++r
)
1845 if ((r
->where
== UNW_WHERE_PSPREL
&& r
->val
<= 0x10)
1846 || r
->where
== UNW_WHERE_SPREL
)
1847 r
->where
= UNW_WHERE_NONE
;
1850 /* If RP did't get saved, generate entry for the return link register. */
1851 if (fs
->curr
.reg
[UNW_REG_RP
].when
>= fs
->when_target
)
1853 fs
->curr
.reg
[UNW_REG_RP
].where
= UNW_WHERE_BR
;
1854 fs
->curr
.reg
[UNW_REG_RP
].when
= -1;
1855 fs
->curr
.reg
[UNW_REG_RP
].val
= fs
->return_link_reg
;
1858 return _URC_NO_REASON
;
1862 uw_update_reg_address (struct _Unwind_Context
*context
,
1863 _Unwind_FrameState
*fs
,
1864 enum unw_register_index regno
)
1866 struct unw_reg_info
*r
= fs
->curr
.reg
+ regno
;
1870 if (r
->where
== UNW_WHERE_NONE
|| r
->when
>= fs
->when_target
)
1878 addr
= ia64_rse_skip_regs ((unsigned long *) context
->bsp
, rval
- 32);
1880 addr
= context
->ireg
[rval
- 2].loc
;
1883 static const unsigned long dummy
;
1884 addr
= (void *) &dummy
;
1891 if (rval
>= 2 && rval
< 32)
1892 addr
= context
->fr_loc
[rval
- 2];
1898 /* Note that while RVAL can only be 1-5 from normal descriptors,
1899 we can want to look at B0, B6 and B7 due to having manually unwound a
1902 addr
= context
->br_loc
[rval
];
1907 case UNW_WHERE_SPREL
:
1908 addr
= (void *)(context
->sp
+ rval
);
1911 case UNW_WHERE_PSPREL
:
1912 addr
= (void *)(context
->psp
+ rval
);
1921 case UNW_REG_R2
... UNW_REG_R31
:
1922 context
->ireg
[regno
- UNW_REG_R2
].loc
= addr
;
1928 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_MEMSTK
;
1929 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
1930 = context
->pri_unat_loc
- (unsigned long *) addr
;
1934 context
->ireg
[regno
- UNW_REG_R2
].nat
1935 = context
->ireg
[rval
- 2].nat
;
1939 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_NONE
;
1940 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
= 0;
1947 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_VAL
;
1948 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
= 0;
1952 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_NONE
;
1953 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
= 0;
1956 case UNW_WHERE_PSPREL
:
1957 case UNW_WHERE_SPREL
:
1958 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_MEMSTK
;
1959 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
1960 = context
->pri_unat_loc
- (unsigned long *) addr
;
1968 case UNW_REG_F2
... UNW_REG_F31
:
1969 context
->fr_loc
[regno
- UNW_REG_F2
] = addr
;
1972 case UNW_REG_B1
... UNW_REG_B5
:
1973 context
->br_loc
[regno
- UNW_REG_B0
] = addr
;
1977 context
->bsp_loc
= addr
;
1979 case UNW_REG_BSPSTORE
:
1980 context
->bspstore_loc
= addr
;
1983 context
->pfs_loc
= addr
;
1986 context
->rp
= *(unsigned long *)addr
;
1989 context
->unat_loc
= addr
;
1992 context
->pr
= *(unsigned long *) addr
;
1995 context
->lc_loc
= addr
;
1998 context
->fpsr_loc
= addr
;
2002 context
->psp
= *(unsigned long *)addr
;
2011 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
2015 #ifdef MD_HANDLE_UNWABI
2016 MD_HANDLE_UNWABI (context
, fs
);
2019 context
->sp
= context
->psp
;
2021 /* First, set PSP. Subsequent instructions may depend on this value. */
2022 if (fs
->when_target
> fs
->curr
.reg
[UNW_REG_PSP
].when
)
2024 if (fs
->curr
.reg
[UNW_REG_PSP
].where
== UNW_WHERE_NONE
)
2025 context
->psp
= context
->psp
+ fs
->curr
.reg
[UNW_REG_PSP
].val
;
2027 uw_update_reg_address (context
, fs
, UNW_REG_PSP
);
2030 /* Determine the location of the primary UNaT. */
2033 if (fs
->when_target
< fs
->curr
.reg
[UNW_REG_PRI_UNAT_GR
].when
)
2034 i
= UNW_REG_PRI_UNAT_MEM
;
2035 else if (fs
->when_target
< fs
->curr
.reg
[UNW_REG_PRI_UNAT_MEM
].when
)
2036 i
= UNW_REG_PRI_UNAT_GR
;
2037 else if (fs
->curr
.reg
[UNW_REG_PRI_UNAT_MEM
].when
2038 > fs
->curr
.reg
[UNW_REG_PRI_UNAT_GR
].when
)
2039 i
= UNW_REG_PRI_UNAT_MEM
;
2041 i
= UNW_REG_PRI_UNAT_GR
;
2042 uw_update_reg_address (context
, fs
, i
);
2045 /* Compute the addresses of all registers saved in this frame. */
2046 for (i
= UNW_REG_BSP
; i
< UNW_NUM_REGS
; ++i
)
2047 uw_update_reg_address (context
, fs
, i
);
2049 /* Unwind BSP for the local registers allocated this frame. */
2050 /* ??? What to do with stored BSP or BSPSTORE registers. */
2051 /* We assert that we are either at a call site, or we have
2052 just unwound through a signal frame. In either case
2053 pfs_loc is valid. */
2054 if (!(fs
-> no_reg_stack_frame
))
2056 unsigned long pfs
= *context
->pfs_loc
;
2057 unsigned long sol
= (pfs
>> 7) & 0x7f;
2058 context
->bsp
= (unsigned long)
2059 ia64_rse_skip_regs ((unsigned long *) context
->bsp
, -sol
);
2063 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
2064 level will be the return address and the CFA. Note that CFA = SP+16. */
2066 #define uw_init_context(CONTEXT) \
2068 /* ??? There is a whole lot o code in uw_install_context that \
2069 tries to avoid spilling the entire machine state here. We \
2070 should try to make that work again. */ \
2071 __builtin_unwind_init(); \
2072 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
2076 uw_init_context_1 (struct _Unwind_Context
*context
, void *bsp
)
2078 void *rp
= __builtin_extract_return_addr (__builtin_return_address (0));
2079 /* Set psp to the caller's stack pointer. */
2080 void *psp
= __builtin_dwarf_cfa () - 16;
2081 _Unwind_FrameState fs
;
2082 unsigned long rnat
, tmp1
, tmp2
;
2084 /* Flush the register stack to memory so that we can access it.
2085 Get rse nat collection for the last incomplete rbs chunk of
2086 registers at the same time. For this RSE needs to be turned
2087 into the mandatory only mode. */
2088 asm ("mov.m %1 = ar.rsc;;\n\t"
2089 "and %2 = 0x1c, %1;;\n\t"
2090 "mov.m ar.rsc = %2;;\n\t"
2092 "mov.m %0 = ar.rnat;;\n\t"
2093 "mov.m ar.rsc = %1\n\t"
2094 : "=r" (rnat
), "=r" (tmp1
), "=r" (tmp2
));
2096 memset (context
, 0, sizeof (struct _Unwind_Context
));
2097 context
->bsp
= (unsigned long) bsp
;
2098 /* Set context->regstk_top to lowest rbs address which will use
2099 context->rnat collection. */
2100 context
->regstk_top
= context
->bsp
& ~0x1ffULL
;
2101 context
->rnat
= rnat
;
2102 context
->psp
= (unsigned long) psp
;
2103 context
->rp
= (unsigned long) rp
;
2104 asm ("mov %0 = sp" : "=r" (context
->sp
));
2105 asm ("mov %0 = pr" : "=r" (context
->pr
));
2106 context
->pri_unat_loc
= &context
->initial_unat
; /* ??? */
2108 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
2111 uw_update_context (context
, &fs
);
2114 /* Install (i.e. longjmp to) the contents of TARGET. */
2116 static void __attribute__((noreturn
))
2117 uw_install_context (struct _Unwind_Context
*current
__attribute__((unused
)),
2118 struct _Unwind_Context
*target
)
2120 unsigned long ireg_buf
[4], ireg_nat
= 0, ireg_pr
= 0;
2123 /* Copy integer register data from the target context to a
2124 temporary buffer. Do this so that we can frob AR.UNAT
2125 to get the NaT bits for these registers set properly. */
2126 for (i
= 4; i
<= 7; ++i
)
2129 void *t
= target
->ireg
[i
- 2].loc
;
2132 unw_access_gr (target
, i
, &ireg_buf
[i
- 4], &nat
, 0);
2133 ireg_nat
|= (long)nat
<< (((size_t)&ireg_buf
[i
- 4] >> 3) & 0x3f);
2139 /* The value in uc_bsp that we've computed is that for the
2140 target function. The value that we install below will be
2141 adjusted by the BR.RET instruction based on the contents
2142 of AR.PFS. So we must unadjust that here. */
2143 target
->bsp
= (unsigned long)
2144 ia64_rse_skip_regs ((unsigned long *)target
->bsp
,
2145 (*target
->pfs_loc
>> 7) & 0x7f);
2147 if (target
->bsp
< target
->regstk_top
)
2148 target
->rnat
= *ia64_rse_rnat_addr ((unsigned long *) target
->bsp
);
2150 /* Provide assembly with the offsets into the _Unwind_Context. */
2151 asm volatile ("uc_rnat = %0"
2152 : : "i"(offsetof (struct _Unwind_Context
, rnat
)));
2153 asm volatile ("uc_bsp = %0"
2154 : : "i"(offsetof (struct _Unwind_Context
, bsp
)));
2155 asm volatile ("uc_psp = %0"
2156 : : "i"(offsetof (struct _Unwind_Context
, psp
)));
2157 asm volatile ("uc_rp = %0"
2158 : : "i"(offsetof (struct _Unwind_Context
, rp
)));
2159 asm volatile ("uc_pr = %0"
2160 : : "i"(offsetof (struct _Unwind_Context
, pr
)));
2161 asm volatile ("uc_gp = %0"
2162 : : "i"(offsetof (struct _Unwind_Context
, gp
)));
2163 asm volatile ("uc_pfs_loc = %0"
2164 : : "i"(offsetof (struct _Unwind_Context
, pfs_loc
)));
2165 asm volatile ("uc_unat_loc = %0"
2166 : : "i"(offsetof (struct _Unwind_Context
, unat_loc
)));
2167 asm volatile ("uc_lc_loc = %0"
2168 : : "i"(offsetof (struct _Unwind_Context
, lc_loc
)));
2169 asm volatile ("uc_fpsr_loc = %0"
2170 : : "i"(offsetof (struct _Unwind_Context
, fpsr_loc
)));
2171 asm volatile ("uc_eh_data = %0"
2172 : : "i"(offsetof (struct _Unwind_Context
, eh_data
)));
2173 asm volatile ("uc_br_loc = %0"
2174 : : "i"(offsetof (struct _Unwind_Context
, br_loc
)));
2175 asm volatile ("uc_fr_loc = %0"
2176 : : "i"(offsetof (struct _Unwind_Context
, fr_loc
)));
2179 /* Load up call-saved non-window integer registers from ireg_buf. */
2180 "add r20 = 8, %1 \n\t"
2181 "mov ar.unat = %2 \n\t"
2182 "mov pr = %3, 0x3c0 \n\t"
2184 "(p6) ld8.fill r4 = [%1] \n\t"
2185 "(p7) ld8.fill r5 = [r20] \n\t"
2186 "add r21 = uc_br_loc + 16, %0 \n\t"
2187 "adds %1 = 16, %1 \n\t"
2188 "adds r20 = 16, r20 \n\t"
2190 "(p8) ld8.fill r6 = [%1] \n\t"
2191 "(p9) ld8.fill r7 = [r20] \n\t"
2192 "add r20 = uc_br_loc + 8, %0 \n\t"
2194 /* Load up call-saved branch registers. */
2195 "ld8 r22 = [r20], 16 \n\t"
2196 "ld8 r23 = [r21], 16 \n\t"
2198 "ld8 r24 = [r20], 16 \n\t"
2199 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
2201 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
2202 "ld8 r27 = [r21], 24 \n\t"
2203 "cmp.ne p6, p0 = r0, r22 \n\t"
2205 "ld8 r28 = [r20], 8 \n\t"
2206 "(p6) ld8 r22 = [r22] \n\t"
2207 "cmp.ne p7, p0 = r0, r23 \n\t"
2209 "(p7) ld8 r23 = [r23] \n\t"
2210 "cmp.ne p8, p0 = r0, r24 \n\t"
2212 "(p8) ld8 r24 = [r24] \n\t"
2213 "(p6) mov b1 = r22 \n\t"
2214 "cmp.ne p9, p0 = r0, r25 \n\t"
2216 "(p9) ld8 r25 = [r25] \n\t"
2217 "(p7) mov b2 = r23 \n\t"
2218 "cmp.ne p6, p0 = r0, r26 \n\t"
2220 "(p6) ld8 r26 = [r26] \n\t"
2221 "(p8) mov b3 = r24 \n\t"
2222 "cmp.ne p7, p0 = r0, r27 \n\t"
2224 /* Load up call-saved fp registers. */
2225 "(p7) ldf.fill f2 = [r27] \n\t"
2226 "(p9) mov b4 = r25 \n\t"
2227 "cmp.ne p8, p0 = r0, r28 \n\t"
2229 "(p8) ldf.fill f3 = [r28] \n\t"
2230 "(p6) mov b5 = r26 \n\t"
2232 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
2233 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
2235 "ld8 r22 = [r20], 16 \n\t"
2236 "ld8 r23 = [r21], 16 \n\t"
2238 "ld8 r24 = [r20], 16 \n\t"
2239 "ld8 r25 = [r21] \n\t"
2240 "cmp.ne p6, p0 = r0, r29 \n\t"
2242 "ld8 r26 = [r20], 8 \n\t"
2243 "(p6) ldf.fill f4 = [r29] \n\t"
2244 "cmp.ne p7, p0 = r0, r30 \n\t"
2246 "ld8 r27 = [r20], 8 \n\t"
2247 "(p7) ldf.fill f5 = [r30] \n\t"
2248 "cmp.ne p6, p0 = r0, r22 \n\t"
2250 "ld8 r28 = [r20], 8 \n\t"
2251 "(p6) ldf.fill f16 = [r22] \n\t"
2252 "cmp.ne p7, p0 = r0, r23 \n\t"
2254 "ld8 r29 = [r20], 8 \n\t"
2255 "(p7) ldf.fill f17 = [r23] \n\t"
2256 "cmp.ne p6, p0 = r0, r24 \n\t"
2258 "ld8 r22 = [r20], 8 \n\t"
2259 "(p6) ldf.fill f18 = [r24] \n\t"
2260 "cmp.ne p7, p0 = r0, r25 \n\t"
2262 "ld8 r23 = [r20], 8 \n\t"
2263 "(p7) ldf.fill f19 = [r25] \n\t"
2264 "cmp.ne p6, p0 = r0, r26 \n\t"
2266 "ld8 r24 = [r20], 8 \n\t"
2267 "(p6) ldf.fill f20 = [r26] \n\t"
2268 "cmp.ne p7, p0 = r0, r27 \n\t"
2270 "ld8 r25 = [r20], 8 \n\t"
2271 "(p7) ldf.fill f21 = [r27] \n\t"
2272 "cmp.ne p6, p0 = r0, r28 \n\t"
2274 "ld8 r26 = [r20], 8 \n\t"
2275 "(p6) ldf.fill f22 = [r28] \n\t"
2276 "cmp.ne p7, p0 = r0, r29 \n\t"
2278 "ld8 r27 = [r20], 8 \n\t"
2280 "ld8 r28 = [r20], 8 \n\t"
2281 "(p7) ldf.fill f23 = [r29] \n\t"
2282 "cmp.ne p6, p0 = r0, r22 \n\t"
2284 "ld8 r29 = [r20], 8 \n\t"
2285 "(p6) ldf.fill f24 = [r22] \n\t"
2286 "cmp.ne p7, p0 = r0, r23 \n\t"
2288 "(p7) ldf.fill f25 = [r23] \n\t"
2289 "cmp.ne p6, p0 = r0, r24 \n\t"
2290 "cmp.ne p7, p0 = r0, r25 \n\t"
2292 "(p6) ldf.fill f26 = [r24] \n\t"
2293 "(p7) ldf.fill f27 = [r25] \n\t"
2294 "cmp.ne p6, p0 = r0, r26 \n\t"
2296 "(p6) ldf.fill f28 = [r26] \n\t"
2297 "cmp.ne p7, p0 = r0, r27 \n\t"
2298 "cmp.ne p6, p0 = r0, r28 \n\t"
2300 "(p7) ldf.fill f29 = [r27] \n\t"
2301 "(p6) ldf.fill f30 = [r28] \n\t"
2302 "cmp.ne p7, p0 = r0, r29 \n\t"
2304 "(p7) ldf.fill f31 = [r29] \n\t"
2305 "add r20 = uc_rnat, %0 \n\t"
2306 "add r21 = uc_bsp, %0 \n\t"
2308 /* Load the balance of the thread state from the context. */
2309 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
2310 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
2312 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
2313 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
2315 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2316 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
2318 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2319 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
2321 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2322 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2324 /* Load data for the exception handler. */
2325 "ld8 r15 = [r20], 16 \n\t"
2326 "ld8 r16 = [r21], 16 \n\t"
2328 "ld8 r17 = [r20] \n\t"
2329 "ld8 r18 = [r21] \n\t"
2331 /* Install the balance of the thread state loaded above. */
2332 "cmp.ne p6, p0 = r0, r25 \n\t"
2333 "cmp.ne p7, p0 = r0, r27 \n\t"
2335 "(p6) ld8 r25 = [r25] \n\t"
2336 "(p7) ld8 r27 = [r27] \n\t"
2338 "(p7) mov.m ar.unat = r27 \n\t"
2339 "(p6) mov.i ar.pfs = r25 \n\t"
2340 "cmp.ne p9, p0 = r0, r29 \n\t"
2342 "(p9) ld8 r29 = [r29] \n\t"
2343 "cmp.ne p6, p0 = r0, r30 \n\t"
2345 "(p6) ld8 r30 = [r30] \n\t"
2346 /* Don't clobber p6-p9, which are in use at present. */
2347 "mov pr = r28, ~0x3c0 \n\t"
2348 "(p9) mov.i ar.lc = r29 \n\t"
2350 "mov.m r25 = ar.rsc \n\t"
2351 "(p6) mov.m ar.fpsr = r30 \n\t"
2353 "and r29 = 0x1c, r25 \n\t"
2356 "mov.m ar.rsc = r29 \n\t"
2358 /* This must be done before setting AR.BSPSTORE, otherwise
2359 AR.BSP will be initialized with a random displacement
2360 below the value we want, based on the current number of
2361 dirty stacked registers. */
2365 "mov.m ar.bspstore = r23 \n\t"
2367 "mov.m ar.rnat = r22 \n\t"
2369 "mov.m ar.rsc = r25 \n\t"
2371 "br.ret.sptk.few b0"
2372 : : "r"(target
), "r"(ireg_buf
), "r"(ireg_nat
), "r"(ireg_pr
)
2373 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2374 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2380 static inline _Unwind_Ptr
2381 uw_identify_context (struct _Unwind_Context
*context
)
2383 return _Unwind_GetIP (context
);
2386 #include "unwind.inc"
2388 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
2389 alias (_Unwind_Backtrace
);
2390 alias (_Unwind_DeleteException
);
2391 alias (_Unwind_FindEnclosingFunction
);
2392 alias (_Unwind_ForcedUnwind
);
2393 alias (_Unwind_GetBSP
);
2394 alias (_Unwind_GetCFA
);
2395 alias (_Unwind_GetGR
);
2396 alias (_Unwind_GetIP
);
2397 alias (_Unwind_GetLanguageSpecificData
);
2398 alias (_Unwind_GetRegionStart
);
2399 alias (_Unwind_RaiseException
);
2400 alias (_Unwind_Resume
);
2401 alias (_Unwind_Resume_or_Rethrow
);
2402 alias (_Unwind_SetGR
);
2403 alias (_Unwind_SetIP
);