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
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, 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, 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__
47 #define UNW_VER(x) ((x) >> 48)
48 #define UNW_FLAG_MASK 0x0000ffff00000000
49 #define UNW_FLAG_OSMASK 0x0000f00000000000
50 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
51 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
52 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
54 enum unw_application_register
68 enum unw_register_index
75 UNW_REG_PSP
, /* previous memory stack pointer */
78 UNW_REG_BSP
, /* register stack pointer */
80 UNW_REG_PFS
, /* previous function state */
85 /* Special preserved registers. */
86 UNW_REG_UNAT
, UNW_REG_PR
, UNW_REG_LC
, UNW_REG_FPSR
,
88 /* Non-stacked general registers. */
90 UNW_REG_R4
= UNW_REG_R2
+ 2,
91 UNW_REG_R7
= UNW_REG_R2
+ 5,
92 UNW_REG_R31
= UNW_REG_R2
+ 29,
94 /* Non-stacked floating point registers. */
96 UNW_REG_F5
= UNW_REG_F2
+ 3,
97 UNW_REG_F16
= UNW_REG_F2
+ 14,
98 UNW_REG_F31
= UNW_REG_F2
+ 29,
100 /* Branch registers. */
101 UNW_REG_B0
, UNW_REG_B1
,
102 UNW_REG_B5
= UNW_REG_B1
+ 4,
109 UNW_WHERE_NONE
, /* register isn't saved at all */
110 UNW_WHERE_GR
, /* register is saved in a general register */
111 UNW_WHERE_FR
, /* register is saved in a floating-point register */
112 UNW_WHERE_BR
, /* register is saved in a branch register */
113 UNW_WHERE_SPREL
, /* register is saved on memstack (sp-relative) */
114 UNW_WHERE_PSPREL
, /* register is saved on memstack (psp-relative) */
116 /* At the end of each prologue these locations get resolved to
117 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
118 UNW_WHERE_SPILL_HOME
, /* register is saved in its spill home */
119 UNW_WHERE_GR_SAVE
/* register is saved in next general register */
122 #define UNW_WHEN_NEVER 0x7fffffff
126 unsigned long val
; /* save location: register number or offset */
127 enum unw_where where
; /* where the register gets saved */
128 int when
; /* when the register gets saved */
131 struct unw_reg_state
{
132 struct unw_reg_state
*next
; /* next (outer) element on state stack */
133 struct unw_reg_info reg
[UNW_NUM_REGS
]; /* register save locations */
136 struct unw_labeled_state
{
137 struct unw_labeled_state
*next
; /* next labeled state (or NULL) */
138 unsigned long label
; /* label for this state */
139 struct unw_reg_state saved_state
;
142 typedef struct unw_state_record
144 unsigned int first_region
: 1; /* is this the first region? */
145 unsigned int done
: 1; /* are we done scanning descriptors? */
146 unsigned int any_spills
: 1; /* got any register spills? */
147 unsigned int in_body
: 1; /* are we inside a body? */
148 unsigned int no_reg_stack_frame
: 1; /* Don't adjust bsp for i&l regs */
149 unsigned char *imask
; /* imask of spill_mask record or NULL */
150 unsigned long pr_val
; /* predicate values */
151 unsigned long pr_mask
; /* predicate mask */
152 long spill_offset
; /* psp-relative offset for spill base */
159 unsigned char gr_save_loc
; /* next general register to use for saving */
160 unsigned char return_link_reg
; /* branch register for return link */
161 unsigned short unwabi
;
163 struct unw_labeled_state
*labeled_states
; /* list of all labeled states */
164 struct unw_reg_state curr
; /* current state */
166 _Unwind_Personality_Fn personality
;
168 } _Unwind_FrameState
;
172 UNW_NAT_NONE
, /* NaT not represented */
173 UNW_NAT_VAL
, /* NaT represented by NaT value (fp reg) */
174 UNW_NAT_MEMSTK
, /* NaT value is in unat word at offset OFF */
175 UNW_NAT_REGSTK
/* NaT is in rnat */
184 struct _Unwind_Context
186 /* Initial frame info. */
187 unsigned long rnat
; /* rse nat collection */
188 unsigned long regstk_top
; /* lowest address of rbs stored register
189 which uses context->rnat collection */
191 /* Current frame info. */
192 unsigned long bsp
; /* backing store pointer value
193 corresponding to psp. */
194 unsigned long sp
; /* stack pointer value */
195 unsigned long psp
; /* previous sp value */
196 unsigned long rp
; /* return pointer */
197 unsigned long pr
; /* predicate collection */
199 unsigned long region_start
; /* start of unwind region */
200 unsigned long gp
; /* global pointer value */
201 void *lsda
; /* language specific data area */
203 /* Preserved state. */
204 unsigned long *bsp_loc
; /* previous bsp save location
205 Appears to be write-only? */
206 unsigned long *bspstore_loc
;
207 unsigned long *pfs_loc
; /* Save location for pfs in current
208 (corr. to sp) frame. Target
209 contains cfm for caller. */
210 unsigned long *pri_unat_loc
;
211 unsigned long *unat_loc
;
212 unsigned long *lc_loc
;
213 unsigned long *fpsr_loc
;
215 unsigned long eh_data
[4];
222 enum unw_nat_type type
: 3;
223 signed long off
: 61; /* NaT word is at loc+nat.off */
225 } ireg
[32 - 2]; /* Indexed by <register number> - 2 */
227 unsigned long *br_loc
[8];
228 void *fr_loc
[32 - 2];
230 /* ??? We initially point pri_unat_loc here. The entire NAT bit
232 unsigned long initial_unat
;
235 typedef unsigned long unw_word
;
237 /* Implicit register save order. See section 11.4.2.3 Rules for Using
238 Unwind Descriptors, rule 3. */
240 static unsigned char const save_order
[] =
242 UNW_REG_RP
, UNW_REG_PFS
, UNW_REG_PSP
, UNW_REG_PR
,
243 UNW_REG_UNAT
, UNW_REG_LC
, UNW_REG_FPSR
, UNW_REG_PRI_UNAT_GR
247 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
249 /* MASK is a bitmap describing the allocation state of emergency buffers,
250 with bit set indicating free. Return >= 0 if allocation is successful;
254 atomic_alloc (unsigned int *mask
)
256 unsigned int old
= *mask
, ret
, new;
264 new = __sync_val_compare_and_swap (mask
, old
, new);
270 return __builtin_ffs (ret
) - 1;
273 /* Similarly, free an emergency buffer. */
276 atomic_free (unsigned int *mask
, int bit
)
278 __sync_xor_and_fetch (mask
, 1 << bit
);
282 #define SIZE(X) (sizeof(X) / sizeof(*(X)))
283 #define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
284 #define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
286 static struct unw_reg_state emergency_reg_state
[32];
287 static int emergency_reg_state_free
= MASK_FOR (emergency_reg_state
);
289 static struct unw_labeled_state emergency_labeled_state
[8];
290 static int emergency_labeled_state_free
= MASK_FOR (emergency_labeled_state
);
292 #ifdef ENABLE_MALLOC_CHECKING
293 static int reg_state_alloced
;
294 static int labeled_state_alloced
;
297 /* Allocation and deallocation of structures. */
299 static struct unw_reg_state
*
300 alloc_reg_state (void)
302 struct unw_reg_state
*rs
;
304 #ifdef ENABLE_MALLOC_CHECKING
308 rs
= malloc (sizeof (struct unw_reg_state
));
311 int n
= atomic_alloc (&emergency_reg_state_free
);
313 rs
= &emergency_reg_state
[n
];
320 free_reg_state (struct unw_reg_state
*rs
)
322 #ifdef ENABLE_MALLOC_CHECKING
326 if (PTR_IN (emergency_reg_state
, rs
))
327 atomic_free (&emergency_reg_state_free
, rs
- emergency_reg_state
);
332 static struct unw_labeled_state
*
333 alloc_label_state (void)
335 struct unw_labeled_state
*ls
;
337 #ifdef ENABLE_MALLOC_CHECKING
338 labeled_state_alloced
++;
341 ls
= malloc(sizeof(struct unw_labeled_state
));
344 int n
= atomic_alloc (&emergency_labeled_state_free
);
346 ls
= &emergency_labeled_state
[n
];
353 free_label_state (struct unw_labeled_state
*ls
)
355 #ifdef ENABLE_MALLOC_CHECKING
356 labeled_state_alloced
--;
359 if (PTR_IN (emergency_labeled_state
, ls
))
360 atomic_free (&emergency_labeled_state_free
, emergency_labeled_state
- ls
);
365 /* Routines to manipulate the state stack. */
368 push (struct unw_state_record
*sr
)
370 struct unw_reg_state
*rs
= alloc_reg_state ();
371 memcpy (rs
, &sr
->curr
, sizeof (*rs
));
376 pop (struct unw_state_record
*sr
)
378 struct unw_reg_state
*rs
= sr
->curr
.next
;
382 memcpy (&sr
->curr
, rs
, sizeof(*rs
));
386 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
388 static struct unw_reg_state
*
389 dup_state_stack (struct unw_reg_state
*rs
)
391 struct unw_reg_state
*copy
, *prev
= NULL
, *first
= NULL
;
395 copy
= alloc_reg_state ();
396 memcpy (copy
, rs
, sizeof(*copy
));
408 /* Free all stacked register states (but not RS itself). */
410 free_state_stack (struct unw_reg_state
*rs
)
412 struct unw_reg_state
*p
, *next
;
414 for (p
= rs
->next
; p
!= NULL
; p
= next
)
422 /* Free all labeled states. */
425 free_label_states (struct unw_labeled_state
*ls
)
427 struct unw_labeled_state
*next
;
429 for (; ls
; ls
= next
)
433 free_state_stack (&ls
->saved_state
);
434 free_label_state (ls
);
438 /* Unwind decoder routines */
440 static enum unw_register_index
__attribute__((const))
441 decode_abreg (unsigned char abreg
, int memory
)
445 case 0x04 ... 0x07: return UNW_REG_R4
+ (abreg
- 0x04);
446 case 0x22 ... 0x25: return UNW_REG_F2
+ (abreg
- 0x22);
447 case 0x30 ... 0x3f: return UNW_REG_F16
+ (abreg
- 0x30);
448 case 0x41 ... 0x45: return UNW_REG_B1
+ (abreg
- 0x41);
449 case 0x60: return UNW_REG_PR
;
450 case 0x61: return UNW_REG_PSP
;
451 case 0x62: return memory
? UNW_REG_PRI_UNAT_MEM
: UNW_REG_PRI_UNAT_GR
;
452 case 0x63: return UNW_REG_RP
;
453 case 0x64: return UNW_REG_BSP
;
454 case 0x65: return UNW_REG_BSPSTORE
;
455 case 0x66: return UNW_REG_RNAT
;
456 case 0x67: return UNW_REG_UNAT
;
457 case 0x68: return UNW_REG_FPSR
;
458 case 0x69: return UNW_REG_PFS
;
459 case 0x6a: return UNW_REG_LC
;
466 set_reg (struct unw_reg_info
*reg
, enum unw_where where
,
467 int when
, unsigned long val
)
471 if (reg
->when
== UNW_WHEN_NEVER
)
476 alloc_spill_area (unsigned long *offp
, unsigned long regsize
,
477 struct unw_reg_info
*lo
, struct unw_reg_info
*hi
)
479 struct unw_reg_info
*reg
;
481 for (reg
= hi
; reg
>= lo
; --reg
)
483 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
485 reg
->where
= UNW_WHERE_PSPREL
;
493 spill_next_when (struct unw_reg_info
**regp
, struct unw_reg_info
*lim
,
496 struct unw_reg_info
*reg
;
498 for (reg
= *regp
; reg
<= lim
; ++reg
)
500 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
512 finish_prologue (struct unw_state_record
*sr
)
514 struct unw_reg_info
*reg
;
518 /* First, resolve implicit register save locations
519 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
521 for (i
= 0; i
< (int) sizeof (save_order
); ++i
)
523 reg
= sr
->curr
.reg
+ save_order
[i
];
524 if (reg
->where
== UNW_WHERE_GR_SAVE
)
526 reg
->where
= UNW_WHERE_GR
;
527 reg
->val
= sr
->gr_save_loc
++;
531 /* Next, compute when the fp, general, and branch registers get saved.
532 This must come before alloc_spill_area() because we need to know
533 which registers are spilled to their home locations. */
536 static unsigned char const limit
[3] = {
537 UNW_REG_F31
, UNW_REG_R7
, UNW_REG_B5
540 unsigned char kind
, mask
= 0, *cp
= sr
->imask
;
542 struct unw_reg_info
*(regs
[3]);
544 regs
[0] = sr
->curr
.reg
+ UNW_REG_F2
;
545 regs
[1] = sr
->curr
.reg
+ UNW_REG_R4
;
546 regs
[2] = sr
->curr
.reg
+ UNW_REG_B1
;
548 for (t
= 0; t
< sr
->region_len
; ++t
)
552 kind
= (mask
>> 2*(3-(t
& 3))) & 3;
554 spill_next_when (®s
[kind
- 1], sr
->curr
.reg
+ limit
[kind
- 1],
555 sr
->region_start
+ t
);
559 /* Next, lay out the memory stack spill area. */
562 off
= sr
->spill_offset
;
563 alloc_spill_area (&off
, 16, sr
->curr
.reg
+ UNW_REG_F2
,
564 sr
->curr
.reg
+ UNW_REG_F31
);
565 alloc_spill_area (&off
, 8, sr
->curr
.reg
+ UNW_REG_B1
,
566 sr
->curr
.reg
+ UNW_REG_B5
);
567 alloc_spill_area (&off
, 8, sr
->curr
.reg
+ UNW_REG_R4
,
568 sr
->curr
.reg
+ UNW_REG_R7
);
573 * Region header descriptors.
577 desc_prologue (int body
, unw_word rlen
, unsigned char mask
,
578 unsigned char grsave
, struct unw_state_record
*sr
)
582 if (!(sr
->in_body
|| sr
->first_region
))
583 finish_prologue (sr
);
584 sr
->first_region
= 0;
586 /* Check if we're done. */
587 if (sr
->when_target
< sr
->region_start
+ sr
->region_len
)
593 for (i
= 0; i
< sr
->epilogue_count
; ++i
)
596 sr
->epilogue_count
= 0;
597 sr
->epilogue_start
= UNW_WHEN_NEVER
;
602 sr
->region_start
+= sr
->region_len
;
603 sr
->region_len
= rlen
;
608 for (i
= 0; i
< 4; ++i
)
611 set_reg (sr
->curr
.reg
+ save_order
[i
], UNW_WHERE_GR
,
612 sr
->region_start
+ sr
->region_len
- 1, grsave
++);
615 sr
->gr_save_loc
= grsave
;
618 sr
->spill_offset
= 0x10; /* default to psp+16 */
623 * Prologue descriptors.
627 desc_abi (unsigned char abi
,
628 unsigned char context
,
629 struct unw_state_record
*sr
)
631 sr
->unwabi
= (abi
<< 8) | context
;
635 desc_br_gr (unsigned char brmask
, unsigned char gr
,
636 struct unw_state_record
*sr
)
640 for (i
= 0; i
< 5; ++i
)
643 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_GR
,
644 sr
->region_start
+ sr
->region_len
- 1, gr
++);
650 desc_br_mem (unsigned char brmask
, struct unw_state_record
*sr
)
654 for (i
= 0; i
< 5; ++i
)
658 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_SPILL_HOME
,
659 sr
->region_start
+ sr
->region_len
- 1, 0);
667 desc_frgr_mem (unsigned char grmask
, unw_word frmask
,
668 struct unw_state_record
*sr
)
672 for (i
= 0; i
< 4; ++i
)
674 if ((grmask
& 1) != 0)
676 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
677 sr
->region_start
+ sr
->region_len
- 1, 0);
682 for (i
= 0; i
< 20; ++i
)
684 if ((frmask
& 1) != 0)
686 enum unw_register_index base
= i
< 4 ? UNW_REG_F2
: UNW_REG_F16
- 4;
687 set_reg (sr
->curr
.reg
+ base
+ i
, UNW_WHERE_SPILL_HOME
,
688 sr
->region_start
+ sr
->region_len
- 1, 0);
696 desc_fr_mem (unsigned char frmask
, struct unw_state_record
*sr
)
700 for (i
= 0; i
< 4; ++i
)
702 if ((frmask
& 1) != 0)
704 set_reg (sr
->curr
.reg
+ UNW_REG_F2
+ i
, UNW_WHERE_SPILL_HOME
,
705 sr
->region_start
+ sr
->region_len
- 1, 0);
713 desc_gr_gr (unsigned char grmask
, unsigned char gr
,
714 struct unw_state_record
*sr
)
718 for (i
= 0; i
< 4; ++i
)
720 if ((grmask
& 1) != 0)
721 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_GR
,
722 sr
->region_start
+ sr
->region_len
- 1, gr
++);
728 desc_gr_mem (unsigned char grmask
, struct unw_state_record
*sr
)
732 for (i
= 0; i
< 4; ++i
)
734 if ((grmask
& 1) != 0)
736 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
737 sr
->region_start
+ sr
->region_len
- 1, 0);
745 desc_mem_stack_f (unw_word t
, unw_word size
, struct unw_state_record
*sr
)
747 set_reg (sr
->curr
.reg
+ UNW_REG_PSP
, UNW_WHERE_NONE
,
748 sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1), 16*size
);
752 desc_mem_stack_v (unw_word t
, struct unw_state_record
*sr
)
754 sr
->curr
.reg
[UNW_REG_PSP
].when
755 = sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
759 desc_reg_gr (unsigned char reg
, unsigned char dst
, struct unw_state_record
*sr
)
761 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_GR
,
762 sr
->region_start
+ sr
->region_len
- 1, dst
);
766 desc_reg_psprel (unsigned char reg
, unw_word pspoff
,
767 struct unw_state_record
*sr
)
769 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_PSPREL
,
770 sr
->region_start
+ sr
->region_len
- 1,
775 desc_reg_sprel (unsigned char reg
, unw_word spoff
, struct unw_state_record
*sr
)
777 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_SPREL
,
778 sr
->region_start
+ sr
->region_len
- 1,
783 desc_rp_br (unsigned char dst
, struct unw_state_record
*sr
)
785 sr
->return_link_reg
= dst
;
789 desc_reg_when (unsigned char regnum
, unw_word t
, struct unw_state_record
*sr
)
791 struct unw_reg_info
*reg
= sr
->curr
.reg
+ regnum
;
793 if (reg
->where
== UNW_WHERE_NONE
)
794 reg
->where
= UNW_WHERE_GR_SAVE
;
795 reg
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
799 desc_spill_base (unw_word pspoff
, struct unw_state_record
*sr
)
801 sr
->spill_offset
= 0x10 - 4*pspoff
;
804 static inline unsigned char *
805 desc_spill_mask (unsigned char *imaskp
, struct unw_state_record
*sr
)
808 return imaskp
+ (2*sr
->region_len
+ 7)/8;
815 desc_epilogue (unw_word t
, unw_word ecount
, struct unw_state_record
*sr
)
817 sr
->epilogue_start
= sr
->region_start
+ sr
->region_len
- 1 - t
;
818 sr
->epilogue_count
= ecount
+ 1;
822 desc_copy_state (unw_word label
, struct unw_state_record
*sr
)
824 struct unw_labeled_state
*ls
;
826 for (ls
= sr
->labeled_states
; ls
; ls
= ls
->next
)
828 if (ls
->label
== label
)
830 free_state_stack (&sr
->curr
);
831 memcpy (&sr
->curr
, &ls
->saved_state
, sizeof (sr
->curr
));
832 sr
->curr
.next
= dup_state_stack (ls
->saved_state
.next
);
840 desc_label_state (unw_word label
, struct unw_state_record
*sr
)
842 struct unw_labeled_state
*ls
= alloc_label_state ();
845 memcpy (&ls
->saved_state
, &sr
->curr
, sizeof (ls
->saved_state
));
846 ls
->saved_state
.next
= dup_state_stack (sr
->curr
.next
);
848 /* Insert into list of labeled states. */
849 ls
->next
= sr
->labeled_states
;
850 sr
->labeled_states
= ls
;
854 * General descriptors.
858 desc_is_active (unsigned char qp
, unw_word t
, struct unw_state_record
*sr
)
860 if (sr
->when_target
<= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1))
864 if ((sr
->pr_val
& (1UL << qp
)) == 0)
866 sr
->pr_mask
|= (1UL << qp
);
872 desc_restore_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
873 struct unw_state_record
*sr
)
875 struct unw_reg_info
*r
;
877 if (! desc_is_active (qp
, t
, sr
))
880 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
881 r
->where
= UNW_WHERE_NONE
;
882 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
887 desc_spill_reg_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
888 unsigned char x
, unsigned char ytreg
,
889 struct unw_state_record
*sr
)
891 enum unw_where where
= UNW_WHERE_GR
;
892 struct unw_reg_info
*r
;
894 if (! desc_is_active (qp
, t
, sr
))
898 where
= UNW_WHERE_BR
;
899 else if (ytreg
& 0x80)
900 where
= UNW_WHERE_FR
;
902 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
904 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
905 r
->val
= ytreg
& 0x7f;
909 desc_spill_psprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
910 unw_word pspoff
, struct unw_state_record
*sr
)
912 struct unw_reg_info
*r
;
914 if (! desc_is_active (qp
, t
, sr
))
917 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
918 r
->where
= UNW_WHERE_PSPREL
;
919 r
->when
= sr
->region_start
+ MIN((int)t
, sr
->region_len
- 1);
920 r
->val
= 0x10 - 4*pspoff
;
924 desc_spill_sprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
925 unw_word spoff
, struct unw_state_record
*sr
)
927 struct unw_reg_info
*r
;
929 if (! desc_is_active (qp
, t
, sr
))
932 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
933 r
->where
= UNW_WHERE_SPREL
;
934 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
939 #define UNW_DEC_BAD_CODE(code) abort ();
941 /* Region headers. */
942 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
943 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
945 /* Prologue descriptors. */
946 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
947 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
948 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
949 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
950 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
951 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
952 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
953 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
954 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
955 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
956 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
957 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
958 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
959 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
960 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
961 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
962 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
963 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
964 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
965 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
966 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
968 /* Body descriptors. */
969 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
970 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
971 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
973 /* General unwind descriptors. */
974 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
975 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
976 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
977 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
978 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
979 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
980 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
981 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
985 * Generic IA-64 unwind info decoder.
987 * This file is used both by the Linux kernel and objdump. Please keep
988 * the copies of this file in sync.
990 * You need to customize the decoder by defining the following
991 * macros/constants before including this file:
994 * unw_word Unsigned integer type with at least 64 bits
1008 * Decoder action macros:
1009 * UNW_DEC_BAD_CODE(code)
1010 * UNW_DEC_ABI(fmt,abi,context,arg)
1011 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
1012 * UNW_DEC_BR_MEM(fmt,brmask,arg)
1013 * UNW_DEC_COPY_STATE(fmt,label,arg)
1014 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
1015 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
1016 * UNW_DEC_FR_MEM(fmt,frmask,arg)
1017 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
1018 * UNW_DEC_GR_MEM(fmt,grmask,arg)
1019 * UNW_DEC_LABEL_STATE(fmt,label,arg)
1020 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
1021 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
1022 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
1023 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
1024 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
1025 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
1026 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
1027 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
1028 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
1029 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
1030 * UNW_DEC_REG_REG(fmt,src,dst,arg)
1031 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
1032 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
1033 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
1034 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
1035 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
1036 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
1037 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
1038 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
1039 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
1040 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
1041 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
1042 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
1046 unw_decode_uleb128 (unsigned char **dpp
)
1049 unw_word byte
, result
= 0;
1050 unsigned char *bp
= *dpp
;
1055 result
|= (byte
& 0x7f) << shift
;
1056 if ((byte
& 0x80) == 0)
1064 static unsigned char *
1065 unw_decode_x1 (unsigned char *dp
,
1066 unsigned char code
__attribute__((unused
)),
1069 unsigned char byte1
, abreg
;
1073 t
= unw_decode_uleb128 (&dp
);
1074 off
= unw_decode_uleb128 (&dp
);
1075 abreg
= (byte1
& 0x7f);
1077 UNW_DEC_SPILL_SPREL(X1
, t
, abreg
, off
, arg
);
1079 UNW_DEC_SPILL_PSPREL(X1
, t
, abreg
, off
, arg
);
1083 static unsigned char *
1084 unw_decode_x2 (unsigned char *dp
,
1085 unsigned char code
__attribute__((unused
)),
1088 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
1091 byte1
= *dp
++; byte2
= *dp
++;
1092 t
= unw_decode_uleb128 (&dp
);
1093 abreg
= (byte1
& 0x7f);
1095 x
= (byte1
>> 7) & 1;
1096 if ((byte1
& 0x80) == 0 && ytreg
== 0)
1097 UNW_DEC_RESTORE(X2
, t
, abreg
, arg
);
1099 UNW_DEC_SPILL_REG(X2
, t
, abreg
, x
, ytreg
, arg
);
1103 static unsigned char *
1104 unw_decode_x3 (unsigned char *dp
,
1105 unsigned char code
__attribute__((unused
)),
1108 unsigned char byte1
, byte2
, abreg
, qp
;
1111 byte1
= *dp
++; byte2
= *dp
++;
1112 t
= unw_decode_uleb128 (&dp
);
1113 off
= unw_decode_uleb128 (&dp
);
1115 qp
= (byte1
& 0x3f);
1116 abreg
= (byte2
& 0x7f);
1119 UNW_DEC_SPILL_SPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
1121 UNW_DEC_SPILL_PSPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
1125 static unsigned char *
1126 unw_decode_x4 (unsigned char *dp
,
1127 unsigned char code
__attribute__((unused
)),
1130 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
1133 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
1134 t
= unw_decode_uleb128 (&dp
);
1136 qp
= (byte1
& 0x3f);
1137 abreg
= (byte2
& 0x7f);
1138 x
= (byte2
>> 7) & 1;
1141 if ((byte2
& 0x80) == 0 && byte3
== 0)
1142 UNW_DEC_RESTORE_P(X4
, qp
, t
, abreg
, arg
);
1144 UNW_DEC_SPILL_REG_P(X4
, qp
, t
, abreg
, x
, ytreg
, arg
);
1148 static unsigned char *
1149 unw_decode_r1 (unsigned char *dp
, unsigned char code
, void *arg
)
1151 int body
= (code
& 0x20) != 0;
1154 rlen
= (code
& 0x1f);
1155 UNW_DEC_PROLOGUE(R1
, body
, rlen
, arg
);
1159 static unsigned char *
1160 unw_decode_r2 (unsigned char *dp
, unsigned char code
, void *arg
)
1162 unsigned char byte1
, mask
, grsave
;
1167 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
1168 grsave
= (byte1
& 0x7f);
1169 rlen
= unw_decode_uleb128 (&dp
);
1170 UNW_DEC_PROLOGUE_GR(R2
, rlen
, mask
, grsave
, arg
);
1174 static unsigned char *
1175 unw_decode_r3 (unsigned char *dp
, unsigned char code
, void *arg
)
1179 rlen
= unw_decode_uleb128 (&dp
);
1180 UNW_DEC_PROLOGUE(R3
, ((code
& 0x3) == 1), rlen
, arg
);
1184 static unsigned char *
1185 unw_decode_p1 (unsigned char *dp
, unsigned char code
, void *arg
)
1187 unsigned char brmask
= (code
& 0x1f);
1189 UNW_DEC_BR_MEM(P1
, brmask
, arg
);
1193 static unsigned char *
1194 unw_decode_p2_p5 (unsigned char *dp
, unsigned char code
, void *arg
)
1196 if ((code
& 0x10) == 0)
1198 unsigned char byte1
= *dp
++;
1200 UNW_DEC_BR_GR(P2
, ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
1201 (byte1
& 0x7f), arg
);
1203 else if ((code
& 0x08) == 0)
1205 unsigned char byte1
= *dp
++, r
, dst
;
1207 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
1208 dst
= (byte1
& 0x7f);
1211 case 0: UNW_DEC_REG_GR(P3
, UNW_REG_PSP
, dst
, arg
); break;
1212 case 1: UNW_DEC_REG_GR(P3
, UNW_REG_RP
, dst
, arg
); break;
1213 case 2: UNW_DEC_REG_GR(P3
, UNW_REG_PFS
, dst
, arg
); break;
1214 case 3: UNW_DEC_REG_GR(P3
, UNW_REG_PR
, dst
, arg
); break;
1215 case 4: UNW_DEC_REG_GR(P3
, UNW_REG_UNAT
, dst
, arg
); break;
1216 case 5: UNW_DEC_REG_GR(P3
, UNW_REG_LC
, dst
, arg
); break;
1217 case 6: UNW_DEC_RP_BR(P3
, dst
, arg
); break;
1218 case 7: UNW_DEC_REG_GR(P3
, UNW_REG_RNAT
, dst
, arg
); break;
1219 case 8: UNW_DEC_REG_GR(P3
, UNW_REG_BSP
, dst
, arg
); break;
1220 case 9: UNW_DEC_REG_GR(P3
, UNW_REG_BSPSTORE
, dst
, arg
); break;
1221 case 10: UNW_DEC_REG_GR(P3
, UNW_REG_FPSR
, dst
, arg
); break;
1222 case 11: UNW_DEC_PRIUNAT_GR(P3
, dst
, arg
); break;
1223 default: UNW_DEC_BAD_CODE(r
); break;
1226 else if ((code
& 0x7) == 0)
1227 UNW_DEC_SPILL_MASK(P4
, dp
, arg
);
1228 else if ((code
& 0x7) == 1)
1230 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
1232 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
1233 grmask
= ((byte1
>> 4) & 0xf);
1234 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
1235 UNW_DEC_FRGR_MEM(P5
, grmask
, frmask
, arg
);
1238 UNW_DEC_BAD_CODE(code
);
1242 static unsigned char *
1243 unw_decode_p6 (unsigned char *dp
, unsigned char code
, void *arg
)
1245 int gregs
= (code
& 0x10) != 0;
1246 unsigned char mask
= (code
& 0x0f);
1249 UNW_DEC_GR_MEM(P6
, mask
, arg
);
1251 UNW_DEC_FR_MEM(P6
, mask
, arg
);
1255 static unsigned char *
1256 unw_decode_p7_p10 (unsigned char *dp
, unsigned char code
, void *arg
)
1258 unsigned char r
, byte1
, byte2
;
1261 if ((code
& 0x10) == 0)
1264 t
= unw_decode_uleb128 (&dp
);
1268 size
= unw_decode_uleb128 (&dp
);
1269 UNW_DEC_MEM_STACK_F(P7
, t
, size
, arg
);
1272 case 1: UNW_DEC_MEM_STACK_V(P7
, t
, arg
); break;
1273 case 2: UNW_DEC_SPILL_BASE(P7
, t
, arg
); break;
1274 case 3: UNW_DEC_REG_SPREL(P7
, UNW_REG_PSP
, t
, arg
); break;
1275 case 4: UNW_DEC_REG_WHEN(P7
, UNW_REG_RP
, t
, arg
); break;
1276 case 5: UNW_DEC_REG_PSPREL(P7
, UNW_REG_RP
, t
, arg
); break;
1277 case 6: UNW_DEC_REG_WHEN(P7
, UNW_REG_PFS
, t
, arg
); break;
1278 case 7: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PFS
, t
, arg
); break;
1279 case 8: UNW_DEC_REG_WHEN(P7
, UNW_REG_PR
, t
, arg
); break;
1280 case 9: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PR
, t
, arg
); break;
1281 case 10: UNW_DEC_REG_WHEN(P7
, UNW_REG_LC
, t
, arg
); break;
1282 case 11: UNW_DEC_REG_PSPREL(P7
, UNW_REG_LC
, t
, arg
); break;
1283 case 12: UNW_DEC_REG_WHEN(P7
, UNW_REG_UNAT
, t
, arg
); break;
1284 case 13: UNW_DEC_REG_PSPREL(P7
, UNW_REG_UNAT
, t
, arg
); break;
1285 case 14: UNW_DEC_REG_WHEN(P7
, UNW_REG_FPSR
, t
, arg
); break;
1286 case 15: UNW_DEC_REG_PSPREL(P7
, UNW_REG_FPSR
, t
, arg
); break;
1287 default: UNW_DEC_BAD_CODE(r
); break;
1297 t
= unw_decode_uleb128 (&dp
);
1300 case 1: UNW_DEC_REG_SPREL(P8
, UNW_REG_RP
, t
, arg
); break;
1301 case 2: UNW_DEC_REG_SPREL(P8
, UNW_REG_PFS
, t
, arg
); break;
1302 case 3: UNW_DEC_REG_SPREL(P8
, UNW_REG_PR
, t
, arg
); break;
1303 case 4: UNW_DEC_REG_SPREL(P8
, UNW_REG_LC
, t
, arg
); break;
1304 case 5: UNW_DEC_REG_SPREL(P8
, UNW_REG_UNAT
, t
, arg
); break;
1305 case 6: UNW_DEC_REG_SPREL(P8
, UNW_REG_FPSR
, t
, arg
); break;
1306 case 7: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSP
, t
, arg
); break;
1307 case 8: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1308 case 9: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1309 case 10: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1310 case 11: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1311 case 12: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1312 case 13: UNW_DEC_REG_WHEN(P8
, UNW_REG_RNAT
, t
, arg
); break;
1313 case 14: UNW_DEC_REG_PSPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1314 case 15: UNW_DEC_REG_SPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1315 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8
, t
, arg
); break;
1316 case 17: UNW_DEC_PRIUNAT_PSPREL(P8
, t
, arg
); break;
1317 case 18: UNW_DEC_PRIUNAT_SPREL(P8
, t
, arg
); break;
1318 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8
, t
, arg
); break;
1319 default: UNW_DEC_BAD_CODE(r
); break;
1325 byte1
= *dp
++; byte2
= *dp
++;
1326 UNW_DEC_GR_GR(P9
, (byte1
& 0xf), (byte2
& 0x7f), arg
);
1330 byte1
= *dp
++; byte2
= *dp
++;
1331 UNW_DEC_ABI(P10
, byte1
, byte2
, arg
);
1335 return unw_decode_x1 (dp
, code
, arg
);
1338 return unw_decode_x2 (dp
, code
, arg
);
1341 return unw_decode_x3 (dp
, code
, arg
);
1344 return unw_decode_x4 (dp
, code
, arg
);
1347 UNW_DEC_BAD_CODE(code
);
1354 static unsigned char *
1355 unw_decode_b1 (unsigned char *dp
, unsigned char code
, void *arg
)
1357 unw_word label
= (code
& 0x1f);
1359 if ((code
& 0x20) != 0)
1360 UNW_DEC_COPY_STATE(B1
, label
, arg
);
1362 UNW_DEC_LABEL_STATE(B1
, label
, arg
);
1366 static unsigned char *
1367 unw_decode_b2 (unsigned char *dp
, unsigned char code
, void *arg
)
1371 t
= unw_decode_uleb128 (&dp
);
1372 UNW_DEC_EPILOGUE(B2
, t
, (code
& 0x1f), arg
);
1376 static unsigned char *
1377 unw_decode_b3_x4 (unsigned char *dp
, unsigned char code
, void *arg
)
1379 unw_word t
, ecount
, label
;
1381 if ((code
& 0x10) == 0)
1383 t
= unw_decode_uleb128 (&dp
);
1384 ecount
= unw_decode_uleb128 (&dp
);
1385 UNW_DEC_EPILOGUE(B3
, t
, ecount
, arg
);
1387 else if ((code
& 0x07) == 0)
1389 label
= unw_decode_uleb128 (&dp
);
1390 if ((code
& 0x08) != 0)
1391 UNW_DEC_COPY_STATE(B4
, label
, arg
);
1393 UNW_DEC_LABEL_STATE(B4
, label
, arg
);
1398 case 1: return unw_decode_x1 (dp
, code
, arg
);
1399 case 2: return unw_decode_x2 (dp
, code
, arg
);
1400 case 3: return unw_decode_x3 (dp
, code
, arg
);
1401 case 4: return unw_decode_x4 (dp
, code
, arg
);
1402 default: UNW_DEC_BAD_CODE(code
); break;
1407 typedef unsigned char *(*unw_decoder
) (unsigned char *, unsigned char, void *);
1409 static const unw_decoder unw_decode_table
[2][8] =
1411 /* prologue table: */
1413 unw_decode_r1
, /* 0 */
1417 unw_decode_p1
, /* 4 */
1423 unw_decode_r1
, /* 0 */
1427 unw_decode_b1
, /* 4 */
1435 * Decode one descriptor and return address of next descriptor.
1437 static inline unsigned char *
1438 unw_decode (unsigned char *dp
, int inside_body
, void *arg
)
1440 unw_decoder decoder
;
1444 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1445 dp
= (*decoder
) (dp
, code
, arg
);
1450 /* RSE helper functions. */
1452 static inline unsigned long
1453 ia64_rse_slot_num (unsigned long *addr
)
1455 return (((unsigned long) addr
) >> 3) & 0x3f;
1458 /* Return TRUE if ADDR is the address of an RNAT slot. */
1459 static inline unsigned long
1460 ia64_rse_is_rnat_slot (unsigned long *addr
)
1462 return ia64_rse_slot_num (addr
) == 0x3f;
1465 /* Returns the address of the RNAT slot that covers the slot at
1466 address SLOT_ADDR. */
1467 static inline unsigned long *
1468 ia64_rse_rnat_addr (unsigned long *slot_addr
)
1470 return (unsigned long *) ((unsigned long) slot_addr
| (0x3f << 3));
1473 /* Calculate the number of registers in the dirty partition starting at
1474 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1475 divided by eight because the 64th slot is used to store ar.rnat. */
1476 static inline unsigned long
1477 ia64_rse_num_regs (unsigned long *bspstore
, unsigned long *bsp
)
1479 unsigned long slots
= (bsp
- bspstore
);
1481 return slots
- (ia64_rse_slot_num (bspstore
) + slots
)/0x40;
1484 /* The inverse of the above: given bspstore and the number of
1485 registers, calculate ar.bsp. */
1486 static inline unsigned long *
1487 ia64_rse_skip_regs (unsigned long *addr
, long num_regs
)
1489 long delta
= ia64_rse_slot_num (addr
) + num_regs
;
1493 return addr
+ num_regs
+ delta
/0x3f;
1497 /* Copy register backing store from SRC to DST, LEN words
1498 (which include both saved registers and nat collections).
1499 DST_RNAT is a partial nat collection for DST. SRC and DST
1500 don't have to be equal modulo 64 slots, so it cannot be
1501 done with a simple memcpy as the nat collections will be
1502 at different relative offsets and need to be combined together. */
1504 ia64_copy_rbs (struct _Unwind_Context
*info
, unsigned long dst
,
1505 unsigned long src
, long len
, unsigned long dst_rnat
)
1508 unsigned long src_rnat
;
1509 unsigned long shift1
, shift2
;
1512 dst_rnat
&= (1UL << ((dst
>> 3) & 0x3f)) - 1;
1513 src_rnat
= src
>= info
->regstk_top
1514 ? info
->rnat
: *(unsigned long *) (src
| 0x1f8);
1515 src_rnat
&= ~((1UL << ((src
>> 3) & 0x3f)) - 1);
1516 /* Just to make sure. */
1517 src_rnat
&= ~(1UL << 63);
1518 shift1
= ((dst
- src
) >> 3) & 0x3f;
1519 if ((dst
& 0x1f8) < (src
& 0x1f8))
1521 shift2
= 0x3f - shift1
;
1522 if ((dst
& 0x1f8) >= (src
& 0x1f8))
1524 count
= ~dst
& 0x1f8;
1527 count
= ~src
& 0x1f8;
1531 src_rnat
= src
>= info
->regstk_top
1532 ? info
->rnat
: *(unsigned long *) (src
| 0x1f8);
1533 /* Just to make sure. */
1534 src_rnat
&= ~(1UL << 63);
1535 count
= shift2
<< 3;
1539 memcpy ((char *) dst
, (char *) src
, count
);
1543 dst_rnat
|= (src_rnat
<< shift1
) & ~(1UL << 63);
1546 *(long *) dst
= dst_rnat
;
1549 count
= shift1
<< 3;
1553 memcpy ((char *) dst
, (char *) src
, count
);
1557 dst_rnat
|= (src_rnat
>> shift2
);
1559 if ((dst
& 0x1f8) == 0x1f8)
1561 *(long *) dst
= dst_rnat
;
1565 /* Set info->regstk_top to lowest rbs address which will use
1566 info->rnat collection. */
1567 info
->regstk_top
= dst
& ~0x1ffUL
;
1568 info
->rnat
= dst_rnat
;
1571 /* Unwind accessors. */
1574 unw_access_gr (struct _Unwind_Context
*info
, int regnum
,
1575 unsigned long *val
, char *nat
, int write
)
1577 unsigned long *addr
, *nat_addr
= 0, nat_mask
= 0, dummy_nat
;
1578 struct unw_ireg
*ireg
;
1580 if ((unsigned) regnum
- 1 >= 127)
1585 nat_addr
= addr
= &dummy_nat
;
1588 else if (regnum
< 32)
1590 /* Access a non-stacked register. */
1591 ireg
= &info
->ireg
[regnum
- 2];
1595 nat_addr
= addr
+ ireg
->nat
.off
;
1596 switch (ireg
->nat
.type
)
1599 /* Simulate getf.sig/setf.sig. */
1604 /* Write NaTVal and be done with it. */
1611 else if (addr
[0] == 0 && addr
[1] == 0x1ffe)
1613 /* Return NaT and be done with it. */
1622 nat_addr
= &dummy_nat
;
1625 case UNW_NAT_MEMSTK
:
1626 nat_mask
= 1UL << ((long) addr
& 0x1f8)/8;
1629 case UNW_NAT_REGSTK
:
1630 if ((unsigned long) addr
>= info
->regstk_top
)
1631 nat_addr
= &info
->rnat
;
1633 nat_addr
= ia64_rse_rnat_addr (addr
);
1634 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1641 /* Access a stacked register. */
1642 addr
= ia64_rse_skip_regs ((unsigned long *) info
->bsp
, regnum
- 32);
1643 if ((unsigned long) addr
>= info
->regstk_top
)
1644 nat_addr
= &info
->rnat
;
1646 nat_addr
= ia64_rse_rnat_addr (addr
);
1647 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1654 *nat_addr
|= nat_mask
;
1656 *nat_addr
&= ~nat_mask
;
1661 *nat
= (*nat_addr
& nat_mask
) != 0;
1665 /* Get the value of register REG as saved in CONTEXT. */
1668 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
1675 else if (index
>= 15 && index
<= 18)
1676 return context
->eh_data
[index
- 15];
1678 unw_access_gr (context
, index
, &ret
, &nat
, 0);
1683 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1686 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
1692 else if (index
>= 15 && index
<= 18)
1693 context
->eh_data
[index
- 15] = val
;
1695 unw_access_gr (context
, index
, &val
, &nat
, 1);
1698 /* Retrieve the return address for CONTEXT. */
1701 _Unwind_GetIP (struct _Unwind_Context
*context
)
1706 /* Overwrite the return address for CONTEXT with VAL. */
1709 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
1715 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
1717 return context
->lsda
;
1721 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
1723 return context
->region_start
;
1727 _Unwind_FindEnclosingFunction (void *pc
)
1729 struct unw_table_entry
*ent
;
1730 unsigned long segment_base
, gp
;
1732 ent
= _Unwind_FindTableEntry (pc
, &segment_base
, &gp
);
1736 return (void *)(segment_base
+ ent
->start_offset
);
1739 /* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance,
1740 the CFA is the value of the stack pointer on entry; In IA-64 unwind
1741 parlance, this is the PSP. */
1744 _Unwind_GetCFA (struct _Unwind_Context
*context
)
1746 return (_Unwind_Ptr
) context
->psp
;
1749 /* Get the value of the Backing Store Pointer as saved in CONTEXT. */
1752 _Unwind_GetBSP (struct _Unwind_Context
*context
)
1754 return (_Unwind_Ptr
) context
->bsp
;
1758 static _Unwind_Reason_Code
1759 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1761 struct unw_table_entry
*ent
;
1762 unsigned long *unw
, header
, length
;
1763 unsigned char *insn
, *insn_end
;
1764 unsigned long segment_base
;
1765 struct unw_reg_info
*r
;
1767 memset (fs
, 0, sizeof (*fs
));
1768 for (r
= fs
->curr
.reg
; r
< fs
->curr
.reg
+ UNW_NUM_REGS
; ++r
)
1769 r
->when
= UNW_WHEN_NEVER
;
1772 ent
= _Unwind_FindTableEntry ((void *) context
->rp
,
1773 &segment_base
, &context
->gp
);
1776 /* Couldn't find unwind info for this function. Try an
1777 os-specific fallback mechanism. This will necessarily
1778 not provide a personality routine or LSDA. */
1779 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1780 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
1782 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1783 handlers, and which keeps the return value in B0 does not need
1784 an unwind table entry.
1786 This can only happen in the frame after unwinding through a signal
1787 handler. Avoid infinite looping by requiring that B0 != RP.
1788 RP == 0 terminates the chain. */
1789 if (context
->br_loc
[0] && *context
->br_loc
[0] != context
->rp
1790 && context
->rp
!= 0)
1792 fs
->curr
.reg
[UNW_REG_RP
].where
= UNW_WHERE_BR
;
1793 fs
->curr
.reg
[UNW_REG_RP
].when
= -1;
1794 fs
->curr
.reg
[UNW_REG_RP
].val
= 0;
1798 return _URC_END_OF_STACK
;
1800 return _URC_NO_REASON
;
1802 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 (ie 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 r28 = [r20], 8 \n\t"
2279 "(p7) ldf.fill f23 = [r29] \n\t"
2280 "cmp.ne p6, p0 = r0, r22 \n\t"
2282 "ld8 r29 = [r20], 8 \n\t"
2283 "(p6) ldf.fill f24 = [r22] \n\t"
2284 "cmp.ne p7, p0 = r0, r23 \n\t"
2286 "(p7) ldf.fill f25 = [r23] \n\t"
2287 "cmp.ne p6, p0 = r0, r24 \n\t"
2288 "cmp.ne p7, p0 = r0, r25 \n\t"
2290 "(p6) ldf.fill f26 = [r24] \n\t"
2291 "(p7) ldf.fill f27 = [r25] \n\t"
2292 "cmp.ne p6, p0 = r0, r26 \n\t"
2294 "(p6) ldf.fill f28 = [r26] \n\t"
2295 "cmp.ne p7, p0 = r0, r27 \n\t"
2296 "cmp.ne p6, p0 = r0, r28 \n\t"
2298 "(p7) ldf.fill f29 = [r27] \n\t"
2299 "(p6) ldf.fill f30 = [r28] \n\t"
2300 "cmp.ne p7, p0 = r0, r29 \n\t"
2302 "(p7) ldf.fill f31 = [r29] \n\t"
2303 "add r20 = uc_rnat, %0 \n\t"
2304 "add r21 = uc_bsp, %0 \n\t"
2306 /* Load the balance of the thread state from the context. */
2307 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
2308 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
2310 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
2311 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
2313 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2314 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
2316 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2317 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
2319 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2320 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2322 /* Load data for the exception handler. */
2323 "ld8 r15 = [r20], 16 \n\t"
2324 "ld8 r16 = [r21], 16 \n\t"
2326 "ld8 r17 = [r20] \n\t"
2327 "ld8 r18 = [r21] \n\t"
2329 /* Install the balance of the thread state loaded above. */
2330 "cmp.ne p6, p0 = r0, r25 \n\t"
2331 "cmp.ne p7, p0 = r0, r27 \n\t"
2333 "(p6) ld8 r25 = [r25] \n\t"
2334 "(p7) ld8 r27 = [r27] \n\t"
2336 "(p7) mov.m ar.unat = r27 \n\t"
2337 "(p6) mov.i ar.pfs = r25 \n\t"
2338 "cmp.ne p9, p0 = r0, r29 \n\t"
2340 "(p9) ld8 r29 = [r29] \n\t"
2341 "cmp.ne p6, p0 = r0, r30 \n\t"
2343 "(p6) ld8 r30 = [r30] \n\t"
2344 /* Don't clobber p6-p9, which are in use at present. */
2345 "mov pr = r28, ~0x3c0 \n\t"
2346 "(p9) mov.i ar.lc = r29 \n\t"
2348 "mov.m r25 = ar.rsc \n\t"
2349 "(p6) mov.m ar.fpsr = r30 \n\t"
2351 "and r29 = 0x1c, r25 \n\t"
2354 "mov.m ar.rsc = r29 \n\t"
2356 /* This must be done before setting AR.BSPSTORE, otherwise
2357 AR.BSP will be initialized with a random displacement
2358 below the value we want, based on the current number of
2359 dirty stacked registers. */
2363 "mov.m ar.bspstore = r23 \n\t"
2365 "mov.m ar.rnat = r22 \n\t"
2367 "mov.m ar.rsc = r25 \n\t"
2369 "br.ret.sptk.few b0"
2370 : : "r"(target
), "r"(ireg_buf
), "r"(ireg_nat
), "r"(ireg_pr
)
2371 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2372 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2378 static inline _Unwind_Ptr
2379 uw_identify_context (struct _Unwind_Context
*context
)
2381 return _Unwind_GetIP (context
);
2384 #include "unwind.inc"
2386 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
2387 alias (_Unwind_Backtrace
);
2388 alias (_Unwind_DeleteException
);
2389 alias (_Unwind_FindEnclosingFunction
);
2390 alias (_Unwind_FindTableEntry
);
2391 alias (_Unwind_ForcedUnwind
);
2392 alias (_Unwind_GetBSP
);
2393 alias (_Unwind_GetCFA
);
2394 alias (_Unwind_GetGR
);
2395 alias (_Unwind_GetIP
);
2396 alias (_Unwind_GetLanguageSpecificData
);
2397 alias (_Unwind_GetRegionStart
);
2398 alias (_Unwind_RaiseException
);
2399 alias (_Unwind_Resume
);
2400 alias (_Unwind_Resume_or_Rethrow
);
2401 alias (_Unwind_SetGR
);
2402 alias (_Unwind_SetIP
);