2002-05-09 Hassan Aurag <aurag@cae.com>
[official-gcc.git] / gcc / config / ia64 / unwind-ia64.c
blobdaf02a2cd30d9fa5fcf6c80519a62b7aa8b9805c
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
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 GNU CC.
11 GNU CC 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)
14 any later version.
16 GNU CC 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 GNU CC; 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. */
34 #include "tconfig.h"
35 #include "tsystem.h"
36 #include "unwind.h"
37 #include "unwind-ia64.h"
38 #include "ia64intrin.h"
40 /* This isn't thread safe, but nice for occasional tests. */
41 #undef ENABLE_MALLOC_CHECKING
43 #ifndef __USING_SJLJ_EXCEPTIONS__
44 #define UNW_VER(x) ((x) >> 48)
45 #define UNW_FLAG_MASK 0x0000ffff00000000
46 #define UNW_FLAG_OSMASK 0x0000f00000000000
47 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
48 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
49 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
51 enum unw_application_register
53 UNW_AR_BSP,
54 UNW_AR_BSPSTORE,
55 UNW_AR_PFS,
56 UNW_AR_RNAT,
57 UNW_AR_UNAT,
58 UNW_AR_LC,
59 UNW_AR_EC,
60 UNW_AR_FPSR,
61 UNW_AR_RSC,
62 UNW_AR_CCV
65 enum unw_register_index
67 /* Primary UNAT. */
68 UNW_REG_PRI_UNAT_GR,
69 UNW_REG_PRI_UNAT_MEM,
71 /* Memory Stack. */
72 UNW_REG_PSP, /* previous memory stack pointer */
74 /* Register Stack. */
75 UNW_REG_BSP, /* register stack pointer */
76 UNW_REG_BSPSTORE,
77 UNW_REG_PFS, /* previous function state */
78 UNW_REG_RNAT,
79 /* Return Pointer. */
80 UNW_REG_RP,
82 /* Special preserved registers. */
83 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
85 /* Non-stacked general registers. */
86 UNW_REG_R2,
87 UNW_REG_R4 = UNW_REG_R2 + 2,
88 UNW_REG_R7 = UNW_REG_R2 + 5,
89 UNW_REG_R31 = UNW_REG_R2 + 29,
91 /* Non-stacked floating point registers. */
92 UNW_REG_F2,
93 UNW_REG_F5 = UNW_REG_F2 + 3,
94 UNW_REG_F16 = UNW_REG_F2 + 14,
95 UNW_REG_F31 = UNW_REG_F2 + 29,
97 /* Branch registers. */
98 UNW_REG_B0, UNW_REG_B1,
99 UNW_REG_B5 = UNW_REG_B1 + 4,
101 UNW_NUM_REGS
104 enum unw_where
106 UNW_WHERE_NONE, /* register isn't saved at all */
107 UNW_WHERE_GR, /* register is saved in a general register */
108 UNW_WHERE_FR, /* register is saved in a floating-point register */
109 UNW_WHERE_BR, /* register is saved in a branch register */
110 UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
111 UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
113 /* At the end of each prologue these locations get resolved to
114 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
115 UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
116 UNW_WHERE_GR_SAVE /* register is saved in next general register */
119 #define UNW_WHEN_NEVER 0x7fffffff
121 struct unw_reg_info
123 unsigned long val; /* save location: register number or offset */
124 enum unw_where where; /* where the register gets saved */
125 int when; /* when the register gets saved */
128 struct unw_reg_state {
129 struct unw_reg_state *next; /* next (outer) element on state stack */
130 struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
133 struct unw_labeled_state {
134 struct unw_labeled_state *next; /* next labeled state (or NULL) */
135 unsigned long label; /* label for this state */
136 struct unw_reg_state saved_state;
139 typedef struct unw_state_record
141 unsigned int first_region : 1; /* is this the first region? */
142 unsigned int done : 1; /* are we done scanning descriptors? */
143 unsigned int any_spills : 1; /* got any register spills? */
144 unsigned int in_body : 1; /* are we inside a body? */
145 unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */
146 unsigned char *imask; /* imask of of spill_mask record or NULL */
147 unsigned long pr_val; /* predicate values */
148 unsigned long pr_mask; /* predicate mask */
149 long spill_offset; /* psp-relative offset for spill base */
150 int region_start;
151 int region_len;
152 int epilogue_start;
153 int epilogue_count;
154 int when_target;
156 unsigned char gr_save_loc; /* next general register to use for saving */
157 unsigned char return_link_reg; /* branch register for return link */
159 struct unw_labeled_state *labeled_states; /* list of all labeled states */
160 struct unw_reg_state curr; /* current state */
162 _Unwind_Personality_Fn personality;
164 } _Unwind_FrameState;
166 enum unw_nat_type
168 UNW_NAT_NONE, /* NaT not represented */
169 UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
170 UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
171 UNW_NAT_REGSTK /* NaT is in rnat */
174 struct unw_stack
176 unsigned long limit;
177 unsigned long top;
180 struct _Unwind_Context
182 /* Initial frame info. */
183 unsigned long rnat; /* rse nat collection */
184 unsigned long regstk_top; /* bsp for first frame */
186 /* Current frame info. */
187 unsigned long bsp; /* backing store pointer value
188 corresponding to psp. */
189 unsigned long sp; /* stack pointer value */
190 unsigned long psp; /* previous sp value */
191 unsigned long rp; /* return pointer */
192 unsigned long pr; /* predicate collection */
194 unsigned long region_start; /* start of unwind region */
195 unsigned long gp; /* global pointer value */
196 void *lsda; /* language specific data area */
198 /* Preserved state. */
199 unsigned long *bsp_loc; /* previous bsp save location
200 Appears to be write-only? */
201 unsigned long *bspstore_loc;
202 unsigned long *pfs_loc; /* Save location for pfs in current
203 (corr. to sp) frame. Target
204 contains cfm for caller. */
205 unsigned long *pri_unat_loc;
206 unsigned long *unat_loc;
207 unsigned long *lc_loc;
208 unsigned long *fpsr_loc;
210 unsigned long eh_data[4];
212 struct unw_ireg
214 unsigned long *loc;
215 struct unw_ireg_nat
217 enum unw_nat_type type : 3;
218 signed long off : 61; /* NaT word is at loc+nat.off */
219 } nat;
220 } ireg[32 - 2]; /* Indexed by <register number> - 2 */
222 unsigned long *br_loc[7];
223 void *fr_loc[32 - 2];
225 /* ??? We initially point pri_unat_loc here. The entire NAT bit
226 logic needs work. */
227 unsigned long initial_unat;
230 typedef unsigned long unw_word;
232 /* Implicit register save order. See section 11.4.2.3 Rules for Using
233 Unwind Descriptors, rule 3. */
235 static unsigned char const save_order[] =
237 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
238 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
242 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
244 /* MASK is a bitmap describing the allocation state of emergency buffers,
245 with bit set indicating free. Return >= 0 if allocation is successful;
246 < 0 if failure. */
248 static inline int
249 atomic_alloc (unsigned int *mask)
251 unsigned int old = *mask, ret, new;
253 while (1)
255 if (old == 0)
256 return -1;
257 ret = old & -old;
258 new = old & ~ret;
259 new = __sync_val_compare_and_swap (mask, old, new);
260 if (old == new)
261 break;
262 old = new;
265 return __builtin_ffs (ret) - 1;
268 /* Similarly, free an emergency buffer. */
270 static inline void
271 atomic_free (unsigned int *mask, int bit)
273 __sync_xor_and_fetch (mask, 1 << bit);
277 #define SIZE(X) (sizeof(X) / sizeof(*(X)))
278 #define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
279 #define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
281 static struct unw_reg_state emergency_reg_state[32];
282 static int emergency_reg_state_free = MASK_FOR (emergency_reg_state);
284 static struct unw_labeled_state emergency_labeled_state[8];
285 static int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state);
287 #ifdef ENABLE_MALLOC_CHECKING
288 static int reg_state_alloced;
289 static int labeled_state_alloced;
290 #endif
292 /* Allocation and deallocation of structures. */
294 static struct unw_reg_state *
295 alloc_reg_state (void)
297 struct unw_reg_state *rs;
299 #ifdef ENABLE_MALLOC_CHECKING
300 reg_state_alloced++;
301 #endif
303 rs = malloc (sizeof (struct unw_reg_state));
304 if (!rs)
306 int n = atomic_alloc (&emergency_reg_state_free);
307 if (n >= 0)
308 rs = &emergency_reg_state[n];
311 return rs;
314 static void
315 free_reg_state (struct unw_reg_state *rs)
317 #ifdef ENABLE_MALLOC_CHECKING
318 reg_state_alloced--;
319 #endif
321 if (PTR_IN (emergency_reg_state, rs))
322 atomic_free (&emergency_reg_state_free, rs - emergency_reg_state);
323 else
324 free (rs);
327 static struct unw_labeled_state *
328 alloc_label_state (void)
330 struct unw_labeled_state *ls;
332 #ifdef ENABLE_MALLOC_CHECKING
333 labeled_state_alloced++;
334 #endif
336 ls = malloc(sizeof(struct unw_labeled_state));
337 if (!ls)
339 int n = atomic_alloc (&emergency_labeled_state_free);
340 if (n >= 0)
341 ls = &emergency_labeled_state[n];
344 return ls;
347 static void
348 free_label_state (struct unw_labeled_state *ls)
350 #ifdef ENABLE_MALLOC_CHECKING
351 labeled_state_alloced--;
352 #endif
354 if (PTR_IN (emergency_labeled_state, ls))
355 atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls);
356 else
357 free (ls);
360 /* Routines to manipulate the state stack. */
362 static void
363 push (struct unw_state_record *sr)
365 struct unw_reg_state *rs = alloc_reg_state ();
366 memcpy (rs, &sr->curr, sizeof (*rs));
367 sr->curr.next = rs;
370 static void
371 pop (struct unw_state_record *sr)
373 struct unw_reg_state *rs = sr->curr.next;
375 if (!rs)
376 abort ();
377 memcpy (&sr->curr, rs, sizeof(*rs));
378 free_reg_state (rs);
381 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
383 static struct unw_reg_state *
384 dup_state_stack (struct unw_reg_state *rs)
386 struct unw_reg_state *copy, *prev = NULL, *first = NULL;
388 while (rs)
390 copy = alloc_reg_state ();
391 memcpy (copy, rs, sizeof(*copy));
392 if (first)
393 prev->next = copy;
394 else
395 first = copy;
396 rs = rs->next;
397 prev = copy;
400 return first;
403 /* Free all stacked register states (but not RS itself). */
404 static void
405 free_state_stack (struct unw_reg_state *rs)
407 struct unw_reg_state *p, *next;
409 for (p = rs->next; p != NULL; p = next)
411 next = p->next;
412 free_reg_state (p);
414 rs->next = NULL;
417 /* Free all labeled states. */
419 static void
420 free_label_states (struct unw_labeled_state *ls)
422 struct unw_labeled_state *next;
424 for (; ls ; ls = next)
426 next = ls->next;
428 free_state_stack (&ls->saved_state);
429 free_label_state (ls);
433 /* Unwind decoder routines */
435 static enum unw_register_index __attribute__((const))
436 decode_abreg (unsigned char abreg, int memory)
438 switch (abreg)
440 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
441 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
442 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
443 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
444 case 0x60: return UNW_REG_PR;
445 case 0x61: return UNW_REG_PSP;
446 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
447 case 0x63: return UNW_REG_RP;
448 case 0x64: return UNW_REG_BSP;
449 case 0x65: return UNW_REG_BSPSTORE;
450 case 0x66: return UNW_REG_RNAT;
451 case 0x67: return UNW_REG_UNAT;
452 case 0x68: return UNW_REG_FPSR;
453 case 0x69: return UNW_REG_PFS;
454 case 0x6a: return UNW_REG_LC;
455 default:
456 abort ();
460 static void
461 set_reg (struct unw_reg_info *reg, enum unw_where where,
462 int when, unsigned long val)
464 reg->val = val;
465 reg->where = where;
466 if (reg->when == UNW_WHEN_NEVER)
467 reg->when = when;
470 static void
471 alloc_spill_area (unsigned long *offp, unsigned long regsize,
472 struct unw_reg_info *lo, struct unw_reg_info *hi)
474 struct unw_reg_info *reg;
476 for (reg = hi; reg >= lo; --reg)
478 if (reg->where == UNW_WHERE_SPILL_HOME)
480 reg->where = UNW_WHERE_PSPREL;
481 *offp -= regsize;
482 reg->val = *offp;
487 static inline void
488 spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim,
489 unw_word t)
491 struct unw_reg_info *reg;
493 for (reg = *regp; reg <= lim; ++reg)
495 if (reg->where == UNW_WHERE_SPILL_HOME)
497 reg->when = t;
498 *regp = reg + 1;
499 return;
502 /* Excess spill. */
503 abort ();
506 static void
507 finish_prologue (struct unw_state_record *sr)
509 struct unw_reg_info *reg;
510 unsigned long off;
511 int i;
513 /* First, resolve implicit register save locations
514 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
516 for (i = 0; i < (int) sizeof (save_order); ++i)
518 reg = sr->curr.reg + save_order[i];
519 if (reg->where == UNW_WHERE_GR_SAVE)
521 reg->where = UNW_WHERE_GR;
522 reg->val = sr->gr_save_loc++;
526 /* Next, compute when the fp, general, and branch registers get saved.
527 This must come before alloc_spill_area() because we need to know
528 which registers are spilled to their home locations. */
529 if (sr->imask)
531 static unsigned char const limit[3] = {
532 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
535 unsigned char kind, mask = 0, *cp = sr->imask;
536 int t;
537 struct unw_reg_info *(regs[3]);
539 regs[0] = sr->curr.reg + UNW_REG_F2;
540 regs[1] = sr->curr.reg + UNW_REG_R4;
541 regs[2] = sr->curr.reg + UNW_REG_B1;
543 for (t = 0; t < sr->region_len; ++t)
545 if ((t & 3) == 0)
546 mask = *cp++;
547 kind = (mask >> 2*(3-(t & 3))) & 3;
548 if (kind > 0)
549 spill_next_when (&regs[kind - 1], sr->curr.reg + limit[kind - 1],
550 sr->region_start + t);
554 /* Next, lay out the memory stack spill area. */
555 if (sr->any_spills)
557 off = sr->spill_offset;
558 alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2,
559 sr->curr.reg + UNW_REG_F31);
560 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1,
561 sr->curr.reg + UNW_REG_B5);
562 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4,
563 sr->curr.reg + UNW_REG_R7);
568 * Region header descriptors.
571 static void
572 desc_prologue (int body, unw_word rlen, unsigned char mask,
573 unsigned char grsave, struct unw_state_record *sr)
575 int i;
577 if (!(sr->in_body || sr->first_region))
578 finish_prologue (sr);
579 sr->first_region = 0;
581 /* Check if we're done. */
582 if (sr->when_target < sr->region_start + sr->region_len)
584 sr->done = 1;
585 return;
588 for (i = 0; i < sr->epilogue_count; ++i)
589 pop (sr);
591 sr->epilogue_count = 0;
592 sr->epilogue_start = UNW_WHEN_NEVER;
594 if (!body)
595 push (sr);
597 sr->region_start += sr->region_len;
598 sr->region_len = rlen;
599 sr->in_body = body;
601 if (!body)
603 for (i = 0; i < 4; ++i)
605 if (mask & 0x8)
606 set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR,
607 sr->region_start + sr->region_len - 1, grsave++);
608 mask <<= 1;
610 sr->gr_save_loc = grsave;
611 sr->any_spills = 0;
612 sr->imask = 0;
613 sr->spill_offset = 0x10; /* default to psp+16 */
618 * Prologue descriptors.
621 static inline void
622 desc_abi (unsigned char abi __attribute__((unused)),
623 unsigned char context __attribute__((unused)),
624 struct unw_state_record *sr __attribute__((unused)))
626 /* Anything to do? */
629 static inline void
630 desc_br_gr (unsigned char brmask, unsigned char gr,
631 struct unw_state_record *sr)
633 int i;
635 for (i = 0; i < 5; ++i)
637 if (brmask & 1)
638 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
639 sr->region_start + sr->region_len - 1, gr++);
640 brmask >>= 1;
644 static inline void
645 desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
647 int i;
649 for (i = 0; i < 5; ++i)
651 if (brmask & 1)
653 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
654 sr->region_start + sr->region_len - 1, 0);
655 sr->any_spills = 1;
657 brmask >>= 1;
661 static inline void
662 desc_frgr_mem (unsigned char grmask, unw_word frmask,
663 struct unw_state_record *sr)
665 int i;
667 for (i = 0; i < 4; ++i)
669 if ((grmask & 1) != 0)
671 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
672 sr->region_start + sr->region_len - 1, 0);
673 sr->any_spills = 1;
675 grmask >>= 1;
677 for (i = 0; i < 20; ++i)
679 if ((frmask & 1) != 0)
681 enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4;
682 set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
683 sr->region_start + sr->region_len - 1, 0);
684 sr->any_spills = 1;
686 frmask >>= 1;
690 static inline void
691 desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
693 int i;
695 for (i = 0; i < 4; ++i)
697 if ((frmask & 1) != 0)
699 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
700 sr->region_start + sr->region_len - 1, 0);
701 sr->any_spills = 1;
703 frmask >>= 1;
707 static inline void
708 desc_gr_gr (unsigned char grmask, unsigned char gr,
709 struct unw_state_record *sr)
711 int i;
713 for (i = 0; i < 4; ++i)
715 if ((grmask & 1) != 0)
716 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
717 sr->region_start + sr->region_len - 1, gr++);
718 grmask >>= 1;
722 static inline void
723 desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
725 int i;
727 for (i = 0; i < 4; ++i)
729 if ((grmask & 1) != 0)
731 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
732 sr->region_start + sr->region_len - 1, 0);
733 sr->any_spills = 1;
735 grmask >>= 1;
739 static inline void
740 desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
742 set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
743 sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size);
746 static inline void
747 desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
749 sr->curr.reg[UNW_REG_PSP].when
750 = sr->region_start + MIN ((int)t, sr->region_len - 1);
753 static inline void
754 desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
756 set_reg (sr->curr.reg + reg, UNW_WHERE_GR,
757 sr->region_start + sr->region_len - 1, dst);
760 static inline void
761 desc_reg_psprel (unsigned char reg, unw_word pspoff,
762 struct unw_state_record *sr)
764 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL,
765 sr->region_start + sr->region_len - 1,
766 0x10 - 4*pspoff);
769 static inline void
770 desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
772 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL,
773 sr->region_start + sr->region_len - 1,
774 4*spoff);
777 static inline void
778 desc_rp_br (unsigned char dst, struct unw_state_record *sr)
780 sr->return_link_reg = dst;
783 static inline void
784 desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
786 struct unw_reg_info *reg = sr->curr.reg + regnum;
788 if (reg->where == UNW_WHERE_NONE)
789 reg->where = UNW_WHERE_GR_SAVE;
790 reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
793 static inline void
794 desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
796 sr->spill_offset = 0x10 - 4*pspoff;
799 static inline unsigned char *
800 desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
802 sr->imask = imaskp;
803 return imaskp + (2*sr->region_len + 7)/8;
807 * Body descriptors.
809 static inline void
810 desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
812 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
813 sr->epilogue_count = ecount + 1;
816 static inline void
817 desc_copy_state (unw_word label, struct unw_state_record *sr)
819 struct unw_labeled_state *ls;
821 for (ls = sr->labeled_states; ls; ls = ls->next)
823 if (ls->label == label)
825 free_state_stack (&sr->curr);
826 memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
827 sr->curr.next = dup_state_stack (ls->saved_state.next);
828 return;
831 abort ();
834 static inline void
835 desc_label_state (unw_word label, struct unw_state_record *sr)
837 struct unw_labeled_state *ls = alloc_label_state ();
839 ls->label = label;
840 memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
841 ls->saved_state.next = dup_state_stack (sr->curr.next);
843 /* Insert into list of labeled states. */
844 ls->next = sr->labeled_states;
845 sr->labeled_states = ls;
849 * General descriptors.
852 static inline int
853 desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
855 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1))
856 return 0;
857 if (qp > 0)
859 if ((sr->pr_val & (1UL << qp)) == 0)
860 return 0;
861 sr->pr_mask |= (1UL << qp);
863 return 1;
866 static inline void
867 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
868 struct unw_state_record *sr)
870 struct unw_reg_info *r;
872 if (! desc_is_active (qp, t, sr))
873 return;
875 r = sr->curr.reg + decode_abreg (abreg, 0);
876 r->where = UNW_WHERE_NONE;
877 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
878 r->val = 0;
881 static inline void
882 desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg,
883 unsigned char x, unsigned char ytreg,
884 struct unw_state_record *sr)
886 enum unw_where where = UNW_WHERE_GR;
887 struct unw_reg_info *r;
889 if (! desc_is_active (qp, t, sr))
890 return;
892 if (x)
893 where = UNW_WHERE_BR;
894 else if (ytreg & 0x80)
895 where = UNW_WHERE_FR;
897 r = sr->curr.reg + decode_abreg (abreg, 0);
898 r->where = where;
899 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
900 r->val = ytreg & 0x7f;
903 static inline void
904 desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg,
905 unw_word pspoff, struct unw_state_record *sr)
907 struct unw_reg_info *r;
909 if (! desc_is_active (qp, t, sr))
910 return;
912 r = sr->curr.reg + decode_abreg (abreg, 1);
913 r->where = UNW_WHERE_PSPREL;
914 r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
915 r->val = 0x10 - 4*pspoff;
918 static inline void
919 desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg,
920 unw_word spoff, struct unw_state_record *sr)
922 struct unw_reg_info *r;
924 if (! desc_is_active (qp, t, sr))
925 return;
927 r = sr->curr.reg + decode_abreg (abreg, 1);
928 r->where = UNW_WHERE_SPREL;
929 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
930 r->val = 4*spoff;
934 #define UNW_DEC_BAD_CODE(code) abort ();
936 /* Region headers. */
937 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
938 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
940 /* Prologue descriptors. */
941 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
942 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
943 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
944 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
945 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
946 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
947 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
948 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
949 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
950 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
951 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
952 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
953 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
954 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
955 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
956 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
957 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
958 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
959 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
960 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
961 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
963 /* Body descriptors. */
964 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
965 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
966 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
968 /* General unwind descriptors. */
969 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
970 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
971 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
972 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
973 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
974 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
975 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
976 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
980 * Generic IA-64 unwind info decoder.
982 * This file is used both by the Linux kernel and objdump. Please keep
983 * the copies of this file in sync.
985 * You need to customize the decoder by defining the following
986 * macros/constants before including this file:
988 * Types:
989 * unw_word Unsigned integer type with at least 64 bits
991 * Register names:
992 * UNW_REG_BSP
993 * UNW_REG_BSPSTORE
994 * UNW_REG_FPSR
995 * UNW_REG_LC
996 * UNW_REG_PFS
997 * UNW_REG_PR
998 * UNW_REG_RNAT
999 * UNW_REG_PSP
1000 * UNW_REG_RP
1001 * UNW_REG_UNAT
1003 * Decoder action macros:
1004 * UNW_DEC_BAD_CODE(code)
1005 * UNW_DEC_ABI(fmt,abi,context,arg)
1006 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
1007 * UNW_DEC_BR_MEM(fmt,brmask,arg)
1008 * UNW_DEC_COPY_STATE(fmt,label,arg)
1009 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
1010 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
1011 * UNW_DEC_FR_MEM(fmt,frmask,arg)
1012 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
1013 * UNW_DEC_GR_MEM(fmt,grmask,arg)
1014 * UNW_DEC_LABEL_STATE(fmt,label,arg)
1015 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
1016 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
1017 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
1018 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
1019 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
1020 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
1021 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
1022 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
1023 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
1024 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
1025 * UNW_DEC_REG_REG(fmt,src,dst,arg)
1026 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
1027 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
1028 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
1029 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
1030 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
1031 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
1032 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
1033 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
1034 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
1035 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
1036 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
1037 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
1040 static unw_word
1041 unw_decode_uleb128 (unsigned char **dpp)
1043 unsigned shift = 0;
1044 unw_word byte, result = 0;
1045 unsigned char *bp = *dpp;
1047 while (1)
1049 byte = *bp++;
1050 result |= (byte & 0x7f) << shift;
1051 if ((byte & 0x80) == 0)
1052 break;
1053 shift += 7;
1055 *dpp = bp;
1056 return result;
1059 static unsigned char *
1060 unw_decode_x1 (unsigned char *dp,
1061 unsigned char code __attribute__((unused)),
1062 void *arg)
1064 unsigned char byte1, abreg;
1065 unw_word t, off;
1067 byte1 = *dp++;
1068 t = unw_decode_uleb128 (&dp);
1069 off = unw_decode_uleb128 (&dp);
1070 abreg = (byte1 & 0x7f);
1071 if (byte1 & 0x80)
1072 UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
1073 else
1074 UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
1075 return dp;
1078 static unsigned char *
1079 unw_decode_x2 (unsigned char *dp,
1080 unsigned char code __attribute__((unused)),
1081 void *arg)
1083 unsigned char byte1, byte2, abreg, x, ytreg;
1084 unw_word t;
1086 byte1 = *dp++; byte2 = *dp++;
1087 t = unw_decode_uleb128 (&dp);
1088 abreg = (byte1 & 0x7f);
1089 ytreg = byte2;
1090 x = (byte1 >> 7) & 1;
1091 if ((byte1 & 0x80) == 0 && ytreg == 0)
1092 UNW_DEC_RESTORE(X2, t, abreg, arg);
1093 else
1094 UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
1095 return dp;
1098 static unsigned char *
1099 unw_decode_x3 (unsigned char *dp,
1100 unsigned char code __attribute__((unused)),
1101 void *arg)
1103 unsigned char byte1, byte2, abreg, qp;
1104 unw_word t, off;
1106 byte1 = *dp++; byte2 = *dp++;
1107 t = unw_decode_uleb128 (&dp);
1108 off = unw_decode_uleb128 (&dp);
1110 qp = (byte1 & 0x3f);
1111 abreg = (byte2 & 0x7f);
1113 if (byte1 & 0x80)
1114 UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
1115 else
1116 UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
1117 return dp;
1120 static unsigned char *
1121 unw_decode_x4 (unsigned char *dp,
1122 unsigned char code __attribute__((unused)),
1123 void *arg)
1125 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
1126 unw_word t;
1128 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1129 t = unw_decode_uleb128 (&dp);
1131 qp = (byte1 & 0x3f);
1132 abreg = (byte2 & 0x7f);
1133 x = (byte2 >> 7) & 1;
1134 ytreg = byte3;
1136 if ((byte2 & 0x80) == 0 && byte3 == 0)
1137 UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
1138 else
1139 UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
1140 return dp;
1143 static unsigned char *
1144 unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
1146 int body = (code & 0x20) != 0;
1147 unw_word rlen;
1149 rlen = (code & 0x1f);
1150 UNW_DEC_PROLOGUE(R1, body, rlen, arg);
1151 return dp;
1154 static unsigned char *
1155 unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
1157 unsigned char byte1, mask, grsave;
1158 unw_word rlen;
1160 byte1 = *dp++;
1162 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1163 grsave = (byte1 & 0x7f);
1164 rlen = unw_decode_uleb128 (&dp);
1165 UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
1166 return dp;
1169 static unsigned char *
1170 unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
1172 unw_word rlen;
1174 rlen = unw_decode_uleb128 (&dp);
1175 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
1176 return dp;
1179 static unsigned char *
1180 unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
1182 unsigned char brmask = (code & 0x1f);
1184 UNW_DEC_BR_MEM(P1, brmask, arg);
1185 return dp;
1188 static unsigned char *
1189 unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
1191 if ((code & 0x10) == 0)
1193 unsigned char byte1 = *dp++;
1195 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
1196 (byte1 & 0x7f), arg);
1198 else if ((code & 0x08) == 0)
1200 unsigned char byte1 = *dp++, r, dst;
1202 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1203 dst = (byte1 & 0x7f);
1204 switch (r)
1206 case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
1207 case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
1208 case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
1209 case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
1210 case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
1211 case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
1212 case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
1213 case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
1214 case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
1215 case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
1216 case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
1217 case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
1218 default: UNW_DEC_BAD_CODE(r); break;
1221 else if ((code & 0x7) == 0)
1222 UNW_DEC_SPILL_MASK(P4, dp, arg);
1223 else if ((code & 0x7) == 1)
1225 unw_word grmask, frmask, byte1, byte2, byte3;
1227 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1228 grmask = ((byte1 >> 4) & 0xf);
1229 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
1230 UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
1232 else
1233 UNW_DEC_BAD_CODE(code);
1234 return dp;
1237 static unsigned char *
1238 unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
1240 int gregs = (code & 0x10) != 0;
1241 unsigned char mask = (code & 0x0f);
1243 if (gregs)
1244 UNW_DEC_GR_MEM(P6, mask, arg);
1245 else
1246 UNW_DEC_FR_MEM(P6, mask, arg);
1247 return dp;
1250 static unsigned char *
1251 unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
1253 unsigned char r, byte1, byte2;
1254 unw_word t, size;
1256 if ((code & 0x10) == 0)
1258 r = (code & 0xf);
1259 t = unw_decode_uleb128 (&dp);
1260 switch (r)
1262 case 0:
1263 size = unw_decode_uleb128 (&dp);
1264 UNW_DEC_MEM_STACK_F(P7, t, size, arg);
1265 break;
1267 case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
1268 case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
1269 case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
1270 case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
1271 case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
1272 case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
1273 case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
1274 case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
1275 case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
1276 case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
1277 case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
1278 case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
1279 case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
1280 case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
1281 case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
1282 default: UNW_DEC_BAD_CODE(r); break;
1285 else
1287 switch (code & 0xf)
1289 case 0x0: /* p8 */
1291 r = *dp++;
1292 t = unw_decode_uleb128 (&dp);
1293 switch (r)
1295 case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
1296 case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
1297 case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
1298 case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
1299 case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
1300 case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
1301 case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
1302 case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
1303 case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
1304 case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
1305 case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1306 case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1307 case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
1308 case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
1309 case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
1310 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
1311 case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
1312 case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
1313 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
1314 default: UNW_DEC_BAD_CODE(r); break;
1317 break;
1319 case 0x1:
1320 byte1 = *dp++; byte2 = *dp++;
1321 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
1322 break;
1324 case 0xf: /* p10 */
1325 byte1 = *dp++; byte2 = *dp++;
1326 UNW_DEC_ABI(P10, byte1, byte2, arg);
1327 break;
1329 case 0x9:
1330 return unw_decode_x1 (dp, code, arg);
1332 case 0xa:
1333 return unw_decode_x2 (dp, code, arg);
1335 case 0xb:
1336 return unw_decode_x3 (dp, code, arg);
1338 case 0xc:
1339 return unw_decode_x4 (dp, code, arg);
1341 default:
1342 UNW_DEC_BAD_CODE(code);
1343 break;
1346 return dp;
1349 static unsigned char *
1350 unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
1352 unw_word label = (code & 0x1f);
1354 if ((code & 0x20) != 0)
1355 UNW_DEC_COPY_STATE(B1, label, arg);
1356 else
1357 UNW_DEC_LABEL_STATE(B1, label, arg);
1358 return dp;
1361 static unsigned char *
1362 unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
1364 unw_word t;
1366 t = unw_decode_uleb128 (&dp);
1367 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
1368 return dp;
1371 static unsigned char *
1372 unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
1374 unw_word t, ecount, label;
1376 if ((code & 0x10) == 0)
1378 t = unw_decode_uleb128 (&dp);
1379 ecount = unw_decode_uleb128 (&dp);
1380 UNW_DEC_EPILOGUE(B3, t, ecount, arg);
1382 else if ((code & 0x07) == 0)
1384 label = unw_decode_uleb128 (&dp);
1385 if ((code & 0x08) != 0)
1386 UNW_DEC_COPY_STATE(B4, label, arg);
1387 else
1388 UNW_DEC_LABEL_STATE(B4, label, arg);
1390 else
1391 switch (code & 0x7)
1393 case 1: return unw_decode_x1 (dp, code, arg);
1394 case 2: return unw_decode_x2 (dp, code, arg);
1395 case 3: return unw_decode_x3 (dp, code, arg);
1396 case 4: return unw_decode_x4 (dp, code, arg);
1397 default: UNW_DEC_BAD_CODE(code); break;
1399 return dp;
1402 typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
1404 static const unw_decoder unw_decode_table[2][8] =
1406 /* prologue table: */
1408 unw_decode_r1, /* 0 */
1409 unw_decode_r1,
1410 unw_decode_r2,
1411 unw_decode_r3,
1412 unw_decode_p1, /* 4 */
1413 unw_decode_p2_p5,
1414 unw_decode_p6,
1415 unw_decode_p7_p10
1418 unw_decode_r1, /* 0 */
1419 unw_decode_r1,
1420 unw_decode_r2,
1421 unw_decode_r3,
1422 unw_decode_b1, /* 4 */
1423 unw_decode_b1,
1424 unw_decode_b2,
1425 unw_decode_b3_x4
1430 * Decode one descriptor and return address of next descriptor.
1432 static inline unsigned char *
1433 unw_decode (unsigned char *dp, int inside_body, void *arg)
1435 unw_decoder decoder;
1436 unsigned char code;
1438 code = *dp++;
1439 decoder = unw_decode_table[inside_body][code >> 5];
1440 dp = (*decoder) (dp, code, arg);
1441 return dp;
1445 /* RSE helper functions. */
1447 static inline unsigned long
1448 ia64_rse_slot_num (unsigned long *addr)
1450 return (((unsigned long) addr) >> 3) & 0x3f;
1453 /* Return TRUE if ADDR is the address of an RNAT slot. */
1454 static inline unsigned long
1455 ia64_rse_is_rnat_slot (unsigned long *addr)
1457 return ia64_rse_slot_num (addr) == 0x3f;
1460 /* Returns the address of the RNAT slot that covers the slot at
1461 address SLOT_ADDR. */
1462 static inline unsigned long *
1463 ia64_rse_rnat_addr (unsigned long *slot_addr)
1465 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
1468 /* Calcuate the number of registers in the dirty partition starting at
1469 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1470 divided by eight because the 64th slot is used to store ar.rnat. */
1471 static inline unsigned long
1472 ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
1474 unsigned long slots = (bsp - bspstore);
1476 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40;
1479 /* The inverse of the above: given bspstore and the number of
1480 registers, calculate ar.bsp. */
1481 static inline unsigned long *
1482 ia64_rse_skip_regs (unsigned long *addr, long num_regs)
1484 long delta = ia64_rse_slot_num (addr) + num_regs;
1486 if (num_regs < 0)
1487 delta -= 0x3e;
1488 return addr + num_regs + delta/0x3f;
1492 /* Unwind accessors. */
1494 static void
1495 unw_access_gr (struct _Unwind_Context *info, int regnum,
1496 unsigned long *val, char *nat, int write)
1498 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat;
1499 struct unw_ireg *ireg;
1501 if ((unsigned) regnum - 1 >= 127)
1502 abort ();
1504 if (regnum < 1)
1506 nat_addr = addr = &dummy_nat;
1507 dummy_nat = 0;
1509 else if (regnum < 32)
1511 /* Access a non-stacked register. */
1512 ireg = &info->ireg[regnum - 2];
1513 addr = ireg->loc;
1514 if (addr)
1516 nat_addr = addr + ireg->nat.off;
1517 switch (ireg->nat.type)
1519 case UNW_NAT_VAL:
1520 /* Simulate getf.sig/setf.sig. */
1521 if (write)
1523 if (*nat)
1525 /* Write NaTVal and be done with it. */
1526 addr[0] = 0;
1527 addr[1] = 0x1fffe;
1528 return;
1530 addr[1] = 0x1003e;
1532 else if (addr[0] == 0 && addr[1] == 0x1ffe)
1534 /* Return NaT and be done with it. */
1535 *val = 0;
1536 *nat = 1;
1537 return;
1539 /* FALLTHRU */
1541 case UNW_NAT_NONE:
1542 dummy_nat = 0;
1543 nat_addr = &dummy_nat;
1544 break;
1546 case UNW_NAT_MEMSTK:
1547 nat_mask = 1UL << ((long) addr & 0x1f8)/8;
1548 break;
1550 case UNW_NAT_REGSTK:
1551 nat_addr = ia64_rse_rnat_addr (addr);
1552 if ((unsigned long) nat_addr >= info->regstk_top)
1553 nat_addr = &info->rnat;
1554 nat_mask = 1UL << ia64_rse_slot_num (addr);
1555 break;
1559 else
1561 /* Access a stacked register. */
1562 addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
1563 nat_addr = ia64_rse_rnat_addr (addr);
1564 if ((unsigned long) nat_addr >= info->regstk_top)
1565 nat_addr = &info->rnat;
1566 nat_mask = 1UL << ia64_rse_slot_num (addr);
1569 if (write)
1571 *addr = *val;
1572 if (*nat)
1573 *nat_addr |= nat_mask;
1574 else
1575 *nat_addr &= ~nat_mask;
1577 else
1579 *val = *addr;
1580 *nat = (*nat_addr & nat_mask) != 0;
1584 /* Get the value of register REG as saved in CONTEXT. */
1586 _Unwind_Word
1587 _Unwind_GetGR (struct _Unwind_Context *context, int index)
1589 _Unwind_Word ret;
1590 char nat;
1592 if (index == 1)
1593 return context->gp;
1594 else if (index >= 15 && index <= 18)
1595 return context->eh_data[index - 15];
1596 else
1597 unw_access_gr (context, index, &ret, &nat, 0);
1599 return ret;
1602 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1604 void
1605 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
1607 char nat = 0;
1609 if (index == 1)
1610 context->gp = val;
1611 else if (index >= 15 && index <= 18)
1612 context->eh_data[index - 15] = val;
1613 else
1614 unw_access_gr (context, index, &val, &nat, 1);
1617 /* Retrieve the return address for CONTEXT. */
1619 inline _Unwind_Ptr
1620 _Unwind_GetIP (struct _Unwind_Context *context)
1622 return context->rp;
1625 /* Overwrite the return address for CONTEXT with VAL. */
1627 inline void
1628 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1630 context->rp = val;
1633 void *
1634 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1636 return context->lsda;
1639 _Unwind_Ptr
1640 _Unwind_GetRegionStart (struct _Unwind_Context *context)
1642 return context->region_start;
1646 static _Unwind_Reason_Code
1647 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1649 struct unw_table_entry *ent;
1650 unsigned long *unw, header, length;
1651 unsigned char *insn, *insn_end;
1652 unsigned long segment_base;
1653 struct unw_reg_info *r;
1655 memset (fs, 0, sizeof (*fs));
1656 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1657 r->when = UNW_WHEN_NEVER;
1658 context->lsda = 0;
1660 ent = _Unwind_FindTableEntry ((void *) context->rp,
1661 &segment_base, &context->gp);
1662 if (ent == NULL)
1664 /* Couldn't find unwind info for this function. Try an
1665 os-specific fallback mechanism. This will necessarily
1666 not provide a personality routine or LSDA. */
1667 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1668 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1670 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1671 handlers, and which keeps the return value in B0 does not need
1672 an unwind table entry.
1674 This can only happen in the frame after unwinding through a signal
1675 handler. Avoid infinite looping by requiring that B0 != RP. */
1676 if (context->br_loc[0] && *context->br_loc[0] != context->rp)
1678 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1679 fs->curr.reg[UNW_REG_RP].when = -1;
1680 fs->curr.reg[UNW_REG_RP].val = 0;
1681 goto success;
1684 return _URC_END_OF_STACK;
1685 success:
1686 return _URC_NO_REASON;
1687 #else
1688 return _URC_END_OF_STACK;
1689 #endif
1692 context->region_start = ent->start_offset + segment_base;
1693 fs->when_target = (context->rp - context->region_start) / 16 * 3;
1695 unw = (unsigned long *) (ent->info_offset + segment_base);
1696 header = *unw;
1697 length = UNW_LENGTH (header);
1699 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */
1701 if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))
1703 fs->personality =
1704 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1705 context->lsda = unw + length + 2;
1708 insn = (unsigned char *) (unw + 1);
1709 insn_end = (unsigned char *) (unw + 1 + length);
1710 while (!fs->done && insn < insn_end)
1711 insn = unw_decode (insn, fs->in_body, fs);
1713 free_label_states (fs->labeled_states);
1714 free_state_stack (&fs->curr);
1716 #ifdef ENABLE_MALLOC_CHECKING
1717 if (reg_state_alloced || labeled_state_alloced)
1718 abort ();
1719 #endif
1721 /* If we're in the epilogue, sp has been restored and all values
1722 on the memory stack below psp also have been restored. */
1723 if (fs->when_target > fs->epilogue_start)
1725 struct unw_reg_info *r;
1727 fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1728 fs->curr.reg[UNW_REG_PSP].val = 0;
1729 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1730 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1731 || r->where == UNW_WHERE_SPREL)
1732 r->where = UNW_WHERE_NONE;
1735 /* If RP did't get saved, generate entry for the return link register. */
1736 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target)
1738 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1739 fs->curr.reg[UNW_REG_RP].when = -1;
1740 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg;
1743 return _URC_NO_REASON;
1746 static void
1747 uw_update_reg_address (struct _Unwind_Context *context,
1748 _Unwind_FrameState *fs,
1749 enum unw_register_index regno)
1751 struct unw_reg_info *r = fs->curr.reg + regno;
1752 void *addr;
1753 unsigned long rval;
1755 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1756 return;
1758 rval = r->val;
1759 switch (r->where)
1761 case UNW_WHERE_GR:
1762 if (rval >= 32)
1763 addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32);
1764 else if (rval >= 2)
1765 addr = context->ireg[rval - 2].loc;
1766 else
1767 abort ();
1768 break;
1770 case UNW_WHERE_FR:
1771 if (rval >= 2 && rval < 32)
1772 addr = context->fr_loc[rval - 2];
1773 else
1774 abort ();
1775 break;
1777 case UNW_WHERE_BR:
1778 /* Note that while RVAL can only be 1-5 from normal descriptors,
1779 we can want to look at B0 due to having manually unwound a
1780 signal frame. */
1781 if (rval <= 5)
1782 addr = context->br_loc[rval];
1783 else
1784 abort ();
1785 break;
1787 case UNW_WHERE_SPREL:
1788 addr = (void *)(context->sp + rval);
1789 break;
1791 case UNW_WHERE_PSPREL:
1792 addr = (void *)(context->psp + rval);
1793 break;
1795 default:
1796 abort ();
1799 switch (regno)
1801 case UNW_REG_R2 ... UNW_REG_R31:
1802 context->ireg[regno - UNW_REG_R2].loc = addr;
1803 switch (r->where)
1805 case UNW_WHERE_GR:
1806 if (rval >= 32)
1808 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1809 context->ireg[regno - UNW_REG_R2].nat.off
1810 = context->pri_unat_loc - (unsigned long *) addr;
1812 else if (rval >= 2)
1814 context->ireg[regno - UNW_REG_R2].nat
1815 = context->ireg[rval - 2].nat;
1817 else
1818 abort ();
1819 break;
1821 case UNW_WHERE_FR:
1822 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL;
1823 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1824 break;
1826 case UNW_WHERE_BR:
1827 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1828 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1829 break;
1831 case UNW_WHERE_PSPREL:
1832 case UNW_WHERE_SPREL:
1833 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1834 context->ireg[regno - UNW_REG_R2].nat.off
1835 = context->pri_unat_loc - (unsigned long *) addr;
1836 break;
1838 default:
1839 abort ();
1841 break;
1843 case UNW_REG_F2 ... UNW_REG_F31:
1844 context->fr_loc[regno - UNW_REG_F2] = addr;
1845 break;
1847 case UNW_REG_B1 ... UNW_REG_B5:
1848 context->br_loc[regno - UNW_REG_B0] = addr;
1849 break;
1851 case UNW_REG_BSP:
1852 context->bsp_loc = addr;
1853 break;
1854 case UNW_REG_BSPSTORE:
1855 context->bspstore_loc = addr;
1856 break;
1857 case UNW_REG_PFS:
1858 context->pfs_loc = addr;
1859 break;
1860 case UNW_REG_RP:
1861 context->rp = *(unsigned long *)addr;
1862 break;
1863 case UNW_REG_UNAT:
1864 context->unat_loc = addr;
1865 break;
1866 case UNW_REG_PR:
1867 context->pr = *(unsigned long *) addr;
1868 break;
1869 case UNW_REG_LC:
1870 context->lc_loc = addr;
1871 break;
1872 case UNW_REG_FPSR:
1873 context->fpsr_loc = addr;
1874 break;
1876 case UNW_REG_PSP:
1877 context->psp = *(unsigned long *)addr;
1878 break;
1880 default:
1881 abort ();
1885 static void
1886 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1888 long i;
1890 context->sp = context->psp;
1892 /* First, set PSP. Subsequent instructions may depend on this value. */
1893 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
1895 if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
1896 context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val;
1897 else
1898 uw_update_reg_address (context, fs, UNW_REG_PSP);
1901 /* Determine the location of the primary UNaT. */
1903 int i;
1904 if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
1905 i = UNW_REG_PRI_UNAT_MEM;
1906 else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when)
1907 i = UNW_REG_PRI_UNAT_GR;
1908 else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when
1909 > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
1910 i = UNW_REG_PRI_UNAT_MEM;
1911 else
1912 i = UNW_REG_PRI_UNAT_GR;
1913 uw_update_reg_address (context, fs, i);
1916 /* Compute the addresses of all registers saved in this frame. */
1917 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
1918 uw_update_reg_address (context, fs, i);
1920 /* Unwind BSP for the local registers allocated this frame. */
1921 /* ??? What to do with stored BSP or BSPSTORE registers. */
1922 /* We assert that we are either at a call site, or we have
1923 just unwound through a signal frame. In either case
1924 pfs_loc is valid. */
1925 if (!(fs -> no_reg_stack_frame))
1927 unsigned long pfs = *context->pfs_loc;
1928 unsigned long sol = (pfs >> 7) & 0x7f;
1929 context->bsp = (unsigned long)
1930 ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol);
1934 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1935 level will be the return address and the CFA. Note that CFA = SP+16. */
1937 #define uw_init_context(CONTEXT) \
1938 do { \
1939 /* ??? There is a whole lot o code in uw_install_context that \
1940 tries to avoid spilling the entire machine state here. We \
1941 should try to make that work again. */ \
1942 __builtin_unwind_init(); \
1943 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
1944 } while (0)
1946 static void
1947 uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
1949 void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
1950 /* Set psp to the caller's stack pointer. */
1951 void *psp = __builtin_dwarf_cfa () - 16;
1952 _Unwind_FrameState fs;
1954 /* Flush the register stack to memory so that we can access it. */
1955 __builtin_ia64_flushrs ();
1957 memset (context, 0, sizeof (struct _Unwind_Context));
1958 context->bsp = context->regstk_top = (unsigned long) bsp;
1959 context->psp = (unsigned long) psp;
1960 context->rp = (unsigned long) rp;
1961 asm ("mov %0 = sp" : "=r" (context->sp));
1962 asm ("mov %0 = pr" : "=r" (context->pr));
1963 context->pri_unat_loc = &context->initial_unat; /* ??? */
1964 /* ??? Get rnat. Don't we have to turn off the rse for that? */
1966 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1967 abort ();
1969 uw_update_context (context, &fs);
1972 /* Install (ie longjmp to) the contents of TARGET. */
1974 static void __attribute__((noreturn))
1975 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
1976 struct _Unwind_Context *target)
1978 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
1979 long i;
1981 /* Copy integer register data from the target context to a
1982 temporary buffer. Do this so that we can frob AR.UNAT
1983 to get the NaT bits for these registers set properly. */
1984 for (i = 4; i <= 7; ++i)
1986 char nat;
1987 void *t = target->ireg[i - 2].loc;
1988 if (t)
1990 unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0);
1991 ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f);
1992 /* Set p6 - p9. */
1993 ireg_pr |= 4L << i;
1997 /* The value in uc_bsp that we've computed is that for the
1998 target function. The value that we install below will be
1999 adjusted by the BR.RET instruction based on the contents
2000 of AR.PFS. So we must unadjust that here. */
2001 target->bsp = (unsigned long)
2002 ia64_rse_skip_regs ((unsigned long *)target->bsp,
2003 (*target->pfs_loc >> 7) & 0x7f);
2005 /* Provide assembly with the offsets into the _Unwind_Context. */
2006 asm volatile ("uc_rnat = %0"
2007 : : "i"(offsetof (struct _Unwind_Context, rnat)));
2008 asm volatile ("uc_bsp = %0"
2009 : : "i"(offsetof (struct _Unwind_Context, bsp)));
2010 asm volatile ("uc_psp = %0"
2011 : : "i"(offsetof (struct _Unwind_Context, psp)));
2012 asm volatile ("uc_rp = %0"
2013 : : "i"(offsetof (struct _Unwind_Context, rp)));
2014 asm volatile ("uc_pr = %0"
2015 : : "i"(offsetof (struct _Unwind_Context, pr)));
2016 asm volatile ("uc_gp = %0"
2017 : : "i"(offsetof (struct _Unwind_Context, gp)));
2018 asm volatile ("uc_pfs_loc = %0"
2019 : : "i"(offsetof (struct _Unwind_Context, pfs_loc)));
2020 asm volatile ("uc_unat_loc = %0"
2021 : : "i"(offsetof (struct _Unwind_Context, unat_loc)));
2022 asm volatile ("uc_lc_loc = %0"
2023 : : "i"(offsetof (struct _Unwind_Context, lc_loc)));
2024 asm volatile ("uc_fpsr_loc = %0"
2025 : : "i"(offsetof (struct _Unwind_Context, fpsr_loc)));
2026 asm volatile ("uc_eh_data = %0"
2027 : : "i"(offsetof (struct _Unwind_Context, eh_data)));
2028 asm volatile ("uc_br_loc = %0"
2029 : : "i"(offsetof (struct _Unwind_Context, br_loc)));
2030 asm volatile ("uc_fr_loc = %0"
2031 : : "i"(offsetof (struct _Unwind_Context, fr_loc)));
2033 asm volatile (
2034 /* Load up call-saved non-window integer registers from ireg_buf. */
2035 "add r20 = 8, %1 \n\t"
2036 "mov ar.unat = %2 \n\t"
2037 "mov pr = %3, 0x3c0 \n\t"
2038 ";; \n\t"
2039 "(p6) ld8.fill r4 = [%1] \n\t"
2040 "(p7) ld8.fill r5 = [r20] \n\t"
2041 "add r21 = uc_br_loc + 8, %0 \n\t"
2042 "adds %1 = 16, %1 \n\t"
2043 "adds r20 = 16, r20 \n\t"
2044 ";; \n\t"
2045 "(p8) ld8.fill r6 = [%1] \n\t"
2046 "(p9) ld8.fill r7 = [r20] \n\t"
2047 "add r20 = uc_br_loc, %0 \n\t"
2048 ";; \n\t"
2049 /* Load up call-saved branch registers. */
2050 "ld8 r22 = [r20], 16 \n\t"
2051 "ld8 r23 = [r21], 16 \n\t"
2052 ";; \n\t"
2053 "ld8 r24 = [r20], 16 \n\t"
2054 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 24)\n\t"
2055 ";; \n\t"
2056 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 32)\n\t"
2057 "ld8 r27 = [r21], 24 \n\t"
2058 "cmp.ne p6, p0 = r0, r22 \n\t"
2059 ";; \n\t"
2060 "ld8 r28 = [r20], 8 \n\t"
2061 "(p6) ld8 r22 = [r22] \n\t"
2062 "cmp.ne p7, p0 = r0, r23 \n\t"
2063 ";; \n\t"
2064 "(p7) ld8 r23 = [r23] \n\t"
2065 "cmp.ne p8, p0 = r0, r24 \n\t"
2066 ";; \n\t"
2067 "(p8) ld8 r24 = [r24] \n\t"
2068 "(p6) mov b1 = r22 \n\t"
2069 "cmp.ne p9, p0 = r0, r25 \n\t"
2070 ";; \n\t"
2071 "(p9) ld8 r25 = [r25] \n\t"
2072 "(p7) mov b2 = r23 \n\t"
2073 "cmp.ne p6, p0 = r0, r26 \n\t"
2074 ";; \n\t"
2075 "(p6) ld8 r26 = [r26] \n\t"
2076 "(p8) mov b3 = r24 \n\t"
2077 "cmp.ne p7, p0 = r0, r27 \n\t"
2078 ";; \n\t"
2079 /* Load up call-saved fp registers. */
2080 "(p7) ldf.fill f2 = [r27] \n\t"
2081 "(p9) mov b4 = r25 \n\t"
2082 "cmp.ne p8, p0 = r0, r28 \n\t"
2083 ";; \n\t"
2084 "(p8) ldf.fill f3 = [r28] \n\t"
2085 "(p6) mov b5 = r26 \n\t"
2086 ";; \n\t"
2087 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
2088 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
2089 ";; \n\t"
2090 "ld8 r22 = [r20], 16 \n\t"
2091 "ld8 r23 = [r21], 16 \n\t"
2092 ";; \n\t"
2093 "ld8 r24 = [r20], 16 \n\t"
2094 "ld8 r25 = [r21] \n\t"
2095 "cmp.ne p6, p0 = r0, r29 \n\t"
2096 ";; \n\t"
2097 "ld8 r26 = [r20], 8 \n\t"
2098 "(p6) ldf.fill f4 = [r29] \n\t"
2099 "cmp.ne p7, p0 = r0, r30 \n\t"
2100 ";; \n\t"
2101 "ld8 r27 = [r20], 8 \n\t"
2102 "(p7) ldf.fill f5 = [r30] \n\t"
2103 "cmp.ne p6, p0 = r0, r22 \n\t"
2104 ";; \n\t"
2105 "ld8 r28 = [r20], 8 \n\t"
2106 "(p6) ldf.fill f16 = [r22] \n\t"
2107 "cmp.ne p7, p0 = r0, r23 \n\t"
2108 ";; \n\t"
2109 "ld8 r29 = [r20], 8 \n\t"
2110 "(p7) ldf.fill f17 = [r23] \n\t"
2111 "cmp.ne p6, p0 = r0, r24 \n\t"
2112 ";; \n\t"
2113 "ld8 r22 = [r20], 8 \n\t"
2114 "(p6) ldf.fill f18 = [r24] \n\t"
2115 "cmp.ne p7, p0 = r0, r25 \n\t"
2116 ";; \n\t"
2117 "ld8 r23 = [r20], 8 \n\t"
2118 "(p7) ldf.fill f19 = [r25] \n\t"
2119 "cmp.ne p6, p0 = r0, r26 \n\t"
2120 ";; \n\t"
2121 "ld8 r24 = [r20], 8 \n\t"
2122 "(p6) ldf.fill f20 = [r26] \n\t"
2123 "cmp.ne p7, p0 = r0, r27 \n\t"
2124 ";; \n\t"
2125 "ld8 r25 = [r20], 8 \n\t"
2126 "(p7) ldf.fill f21 = [r27] \n\t"
2127 "cmp.ne p6, p0 = r0, r28 \n\t"
2128 ";; \n\t"
2129 "ld8 r26 = [r20], 8 \n\t"
2130 "(p6) ldf.fill f22 = [r28] \n\t"
2131 "cmp.ne p7, p0 = r0, r29 \n\t"
2132 ";; \n\t"
2133 "ld8 r28 = [r20], 8 \n\t"
2134 "(p7) ldf.fill f23 = [r29] \n\t"
2135 "cmp.ne p6, p0 = r0, r22 \n\t"
2136 ";; \n\t"
2137 "ld8 r29 = [r20], 8 \n\t"
2138 "(p6) ldf.fill f24 = [r22] \n\t"
2139 "cmp.ne p7, p0 = r0, r23 \n\t"
2140 ";; \n\t"
2141 "(p7) ldf.fill f25 = [r23] \n\t"
2142 "cmp.ne p6, p0 = r0, r24 \n\t"
2143 "cmp.ne p7, p0 = r0, r25 \n\t"
2144 ";; \n\t"
2145 "(p6) ldf.fill f26 = [r24] \n\t"
2146 "(p7) ldf.fill f27 = [r25] \n\t"
2147 "cmp.ne p6, p0 = r0, r26 \n\t"
2148 ";; \n\t"
2149 "(p6) ldf.fill f28 = [r26] \n\t"
2150 "cmp.ne p7, p0 = r0, r27 \n\t"
2151 "cmp.ne p6, p0 = r0, r28 \n\t"
2152 ";; \n\t"
2153 "(p7) ldf.fill f29 = [r27] \n\t"
2154 "(p6) ldf.fill f30 = [r28] \n\t"
2155 "cmp.ne p7, p0 = r0, r29 \n\t"
2156 ";; \n\t"
2157 "(p7) ldf.fill f31 = [r29] \n\t"
2158 "add r20 = uc_rnat, %0 \n\t"
2159 "add r21 = uc_bsp, %0 \n\t"
2160 ";; \n\t"
2161 /* Load the balance of the thread state from the context. */
2162 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
2163 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
2164 ";; \n\t"
2165 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
2166 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
2167 ";; \n\t"
2168 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2169 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
2170 ";; \n\t"
2171 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2172 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
2173 ";; \n\t"
2174 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2175 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2176 ";; \n\t"
2177 /* Load data for the exception handler. */
2178 "ld8 r15 = [r20], 16 \n\t"
2179 "ld8 r16 = [r21], 16 \n\t"
2180 ";; \n\t"
2181 "ld8 r17 = [r20] \n\t"
2182 "ld8 r18 = [r21] \n\t"
2183 ";; \n\t"
2184 /* Install the balance of the thread state loaded above. */
2185 "cmp.ne p6, p0 = r0, r25 \n\t"
2186 "cmp.ne p7, p0 = r0, r27 \n\t"
2187 ";; \n\t"
2188 "(p6) ld8 r25 = [r25] \n\t"
2189 "(p7) ld8 r27 = [r27] \n\t"
2190 ";; \n\t"
2191 "(p7) mov.m ar.unat = r27 \n\t"
2192 "(p6) mov.i ar.pfs = r25 \n\t"
2193 "cmp.ne p9, p0 = r0, r29 \n\t"
2194 ";; \n\t"
2195 "(p9) ld8 r29 = [r29] \n\t"
2196 "cmp.ne p6, p0 = r0, r30 \n\t"
2197 ";; \n\t"
2198 "(p6) ld8 r30 = [r30] \n\t"
2199 /* Don't clobber p6-p9, which are in use at present. */
2200 "mov pr = r28, ~0x3c0 \n\t"
2201 "(p9) mov.i ar.lc = r29 \n\t"
2202 ";; \n\t"
2203 "mov.m r25 = ar.rsc \n\t"
2204 "(p6) mov.i ar.fpsr = r30 \n\t"
2205 ";; \n\t"
2206 "and r25 = 0x1c, r25 \n\t"
2207 "mov b0 = r26 \n\t"
2208 ";; \n\t"
2209 "mov.m ar.rsc = r25 \n\t"
2210 ";; \n\t"
2211 /* This must be done before setting AR.BSPSTORE, otherwise
2212 AR.BSP will be initialized with a random displacement
2213 below the value we want, based on the current number of
2214 dirty stacked registers. */
2215 "loadrs \n\t"
2216 "invala \n\t"
2217 ";; \n\t"
2218 "mov.m ar.bspstore = r23 \n\t"
2219 ";; \n\t"
2220 "or r25 = 0x3, r25 \n\t"
2221 "mov.m ar.rnat = r22 \n\t"
2222 ";; \n\t"
2223 "mov.m ar.rsc = r25 \n\t"
2224 "mov sp = r24 \n\t"
2225 "br.ret.sptk.few b0"
2226 : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr)
2227 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2228 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2229 "r30", "r31");
2230 /* NOTREACHED */
2231 while (1);
2234 static inline _Unwind_Ptr
2235 uw_identify_context (struct _Unwind_Context *context)
2237 return _Unwind_GetIP (context);
2240 #include "unwind.inc"
2241 #endif