]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/ia64/unwind-ia64.c
Makefile.in (UNWIND_H): Remove.
[thirdparty/gcc.git] / libgcc / config / ia64 / unwind-ia64.c
CommitLineData
2a1ee410
RH
1/* Subroutines needed for unwinding IA-64 standard format stack frame
2 info for exception handling.
748086b7 3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
58cd1d70 4 2009, 2011 Free Software Foundation, Inc.
2a1ee410
RH
5 Contributed by Andrew MacLeod <amacleod@cygnus.com>
6 Andrew Haley <aph@cygnus.com>
7 David Mosberger-Tang <davidm@hpl.hp.com>
8
3bed2930 9 This file is part of GCC.
2a1ee410 10
3bed2930 11 GCC is free software; you can redistribute it and/or modify
2a1ee410 12 it under the terms of the GNU General Public License as published by
748086b7 13 the Free Software Foundation; either version 3, or (at your option)
2a1ee410
RH
14 any later version.
15
3bed2930 16 GCC is distributed in the hope that it will be useful,
2a1ee410
RH
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.
20
748086b7
JJ
21 Under Section 7 of GPL version 3, you are granted additional
22 permissions described in the GCC Runtime Library Exception, version
23 3.1, as published by the Free Software Foundation.
2a1ee410 24
748086b7
JJ
25 You should have received a copy of the GNU General Public License and
26 a copy of the GCC Runtime Library Exception along with this program;
27 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
28 <http://www.gnu.org/licenses/>. */
2a1ee410
RH
29
30#include "tconfig.h"
31#include "tsystem.h"
07938cec
HB
32#include "coretypes.h"
33#include "tm.h"
2a1ee410
RH
34#include "unwind.h"
35#include "unwind-ia64.h"
443728bb 36#include "unwind-compat.h"
72e32876
RH
37#include "ia64intrin.h"
38
39/* This isn't thread safe, but nice for occasional tests. */
40#undef ENABLE_MALLOC_CHECKING
2a1ee410 41
0d24f4d1 42#ifndef __USING_SJLJ_EXCEPTIONS__
8662eb14 43
2a1ee410
RH
44enum unw_application_register
45{
46 UNW_AR_BSP,
47 UNW_AR_BSPSTORE,
48 UNW_AR_PFS,
49 UNW_AR_RNAT,
50 UNW_AR_UNAT,
51 UNW_AR_LC,
52 UNW_AR_EC,
53 UNW_AR_FPSR,
54 UNW_AR_RSC,
55 UNW_AR_CCV
56};
57
58enum unw_register_index
59{
60 /* Primary UNAT. */
61 UNW_REG_PRI_UNAT_GR,
62 UNW_REG_PRI_UNAT_MEM,
63
64 /* Memory Stack. */
65 UNW_REG_PSP, /* previous memory stack pointer */
66
67 /* Register Stack. */
68 UNW_REG_BSP, /* register stack pointer */
69 UNW_REG_BSPSTORE,
70 UNW_REG_PFS, /* previous function state */
71 UNW_REG_RNAT,
72 /* Return Pointer. */
73 UNW_REG_RP,
74
75 /* Special preserved registers. */
76 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
77
78 /* Non-stacked general registers. */
79 UNW_REG_R2,
80 UNW_REG_R4 = UNW_REG_R2 + 2,
81 UNW_REG_R7 = UNW_REG_R2 + 5,
82 UNW_REG_R31 = UNW_REG_R2 + 29,
83
84 /* Non-stacked floating point registers. */
85 UNW_REG_F2,
86 UNW_REG_F5 = UNW_REG_F2 + 3,
87 UNW_REG_F16 = UNW_REG_F2 + 14,
88 UNW_REG_F31 = UNW_REG_F2 + 29,
89
90 /* Branch registers. */
443621af 91 UNW_REG_B0, UNW_REG_B1,
2a1ee410
RH
92 UNW_REG_B5 = UNW_REG_B1 + 4,
93
94 UNW_NUM_REGS
95};
96
97enum unw_where
98{
99 UNW_WHERE_NONE, /* register isn't saved at all */
100 UNW_WHERE_GR, /* register is saved in a general register */
101 UNW_WHERE_FR, /* register is saved in a floating-point register */
102 UNW_WHERE_BR, /* register is saved in a branch register */
103 UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
104 UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
105
106 /* At the end of each prologue these locations get resolved to
107 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
108 UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
109 UNW_WHERE_GR_SAVE /* register is saved in next general register */
110};
111
112#define UNW_WHEN_NEVER 0x7fffffff
113
114struct unw_reg_info
115{
116 unsigned long val; /* save location: register number or offset */
117 enum unw_where where; /* where the register gets saved */
118 int when; /* when the register gets saved */
119};
120
5025a549
DM
121struct unw_reg_state {
122 struct unw_reg_state *next; /* next (outer) element on state stack */
123 struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
124};
125
126struct unw_labeled_state {
127 struct unw_labeled_state *next; /* next labeled state (or NULL) */
128 unsigned long label; /* label for this state */
129 struct unw_reg_state saved_state;
130};
131
2a1ee410
RH
132typedef struct unw_state_record
133{
134 unsigned int first_region : 1; /* is this the first region? */
135 unsigned int done : 1; /* are we done scanning descriptors? */
136 unsigned int any_spills : 1; /* got any register spills? */
137 unsigned int in_body : 1; /* are we inside a body? */
d7e60e95 138 unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */
43aa4e05 139 unsigned char *imask; /* imask of spill_mask record or NULL */
2a1ee410
RH
140 unsigned long pr_val; /* predicate values */
141 unsigned long pr_mask; /* predicate mask */
142 long spill_offset; /* psp-relative offset for spill base */
143 int region_start;
144 int region_len;
145 int epilogue_start;
146 int epilogue_count;
147 int when_target;
148
149 unsigned char gr_save_loc; /* next general register to use for saving */
150 unsigned char return_link_reg; /* branch register for return link */
3950dcdf 151 unsigned short unwabi;
2a1ee410 152
5025a549
DM
153 struct unw_labeled_state *labeled_states; /* list of all labeled states */
154 struct unw_reg_state curr; /* current state */
2a1ee410
RH
155
156 _Unwind_Personality_Fn personality;
157
158} _Unwind_FrameState;
159
160enum unw_nat_type
161{
162 UNW_NAT_NONE, /* NaT not represented */
163 UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
164 UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
165 UNW_NAT_REGSTK /* NaT is in rnat */
166};
167
168struct unw_stack
169{
170 unsigned long limit;
171 unsigned long top;
172};
173
174struct _Unwind_Context
175{
176 /* Initial frame info. */
177 unsigned long rnat; /* rse nat collection */
e8c89d29
JJ
178 unsigned long regstk_top; /* lowest address of rbs stored register
179 which uses context->rnat collection */
2a1ee410
RH
180
181 /* Current frame info. */
4d9720f0
HB
182 unsigned long bsp; /* backing store pointer value
183 corresponding to psp. */
2a1ee410
RH
184 unsigned long sp; /* stack pointer value */
185 unsigned long psp; /* previous sp value */
186 unsigned long rp; /* return pointer */
187 unsigned long pr; /* predicate collection */
188
189 unsigned long region_start; /* start of unwind region */
190 unsigned long gp; /* global pointer value */
191 void *lsda; /* language specific data area */
192
193 /* Preserved state. */
d7e60e95
HB
194 unsigned long *bsp_loc; /* previous bsp save location
195 Appears to be write-only? */
2a1ee410 196 unsigned long *bspstore_loc;
d7e60e95
HB
197 unsigned long *pfs_loc; /* Save location for pfs in current
198 (corr. to sp) frame. Target
199 contains cfm for caller. */
ac77b88e
EB
200 unsigned long *signal_pfs_loc;/* Save location for pfs in current
201 signal frame. Target contains
202 pfs for caller. */
2a1ee410
RH
203 unsigned long *pri_unat_loc;
204 unsigned long *unat_loc;
205 unsigned long *lc_loc;
206 unsigned long *fpsr_loc;
207
208 unsigned long eh_data[4];
209
210 struct unw_ireg
211 {
212 unsigned long *loc;
213 struct unw_ireg_nat
214 {
215 enum unw_nat_type type : 3;
216 signed long off : 61; /* NaT word is at loc+nat.off */
217 } nat;
4d9720f0 218 } ireg[32 - 2]; /* Indexed by <register number> - 2 */
2a1ee410 219
3950dcdf 220 unsigned long *br_loc[8];
2a1ee410 221 void *fr_loc[32 - 2];
4d9720f0
HB
222
223 /* ??? We initially point pri_unat_loc here. The entire NAT bit
224 logic needs work. */
225 unsigned long initial_unat;
2a1ee410
RH
226};
227
228typedef unsigned long unw_word;
229
230/* Implicit register save order. See section 11.4.2.3 Rules for Using
231 Unwind Descriptors, rule 3. */
232
233static unsigned char const save_order[] =
234{
235 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
236 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
237};
238
239\f
240#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
241
72e32876
RH
242/* MASK is a bitmap describing the allocation state of emergency buffers,
243 with bit set indicating free. Return >= 0 if allocation is successful;
244 < 0 if failure. */
2a1ee410 245
72e32876
RH
246static inline int
247atomic_alloc (unsigned int *mask)
248{
249 unsigned int old = *mask, ret, new;
250
251 while (1)
252 {
253 if (old == 0)
254 return -1;
255 ret = old & -old;
256 new = old & ~ret;
257 new = __sync_val_compare_and_swap (mask, old, new);
258 if (old == new)
259 break;
260 old = new;
261 }
262
263 return __builtin_ffs (ret) - 1;
264}
265
266/* Similarly, free an emergency buffer. */
267
268static inline void
269atomic_free (unsigned int *mask, int bit)
270{
271 __sync_xor_and_fetch (mask, 1 << bit);
272}
273
274
275#define SIZE(X) (sizeof(X) / sizeof(*(X)))
276#define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
277#define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
278
279static struct unw_reg_state emergency_reg_state[32];
8f6c5889 280static unsigned int emergency_reg_state_free = MASK_FOR (emergency_reg_state);
72e32876
RH
281
282static struct unw_labeled_state emergency_labeled_state[8];
8f6c5889 283static unsigned int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state);
72e32876
RH
284
285#ifdef ENABLE_MALLOC_CHECKING
286static int reg_state_alloced;
287static int labeled_state_alloced;
288#endif
289
290/* Allocation and deallocation of structures. */
291
292static struct unw_reg_state *
293alloc_reg_state (void)
2a1ee410
RH
294{
295 struct unw_reg_state *rs;
296
72e32876
RH
297#ifdef ENABLE_MALLOC_CHECKING
298 reg_state_alloced++;
299#endif
300
2a1ee410 301 rs = malloc (sizeof (struct unw_reg_state));
72e32876
RH
302 if (!rs)
303 {
304 int n = atomic_alloc (&emergency_reg_state_free);
305 if (n >= 0)
306 rs = &emergency_reg_state[n];
307 }
308
309 return rs;
310}
311
312static void
313free_reg_state (struct unw_reg_state *rs)
314{
315#ifdef ENABLE_MALLOC_CHECKING
316 reg_state_alloced--;
317#endif
318
319 if (PTR_IN (emergency_reg_state, rs))
320 atomic_free (&emergency_reg_state_free, rs - emergency_reg_state);
321 else
322 free (rs);
323}
324
325static struct unw_labeled_state *
326alloc_label_state (void)
327{
328 struct unw_labeled_state *ls;
329
330#ifdef ENABLE_MALLOC_CHECKING
331 labeled_state_alloced++;
332#endif
333
334 ls = malloc(sizeof(struct unw_labeled_state));
335 if (!ls)
336 {
337 int n = atomic_alloc (&emergency_labeled_state_free);
338 if (n >= 0)
339 ls = &emergency_labeled_state[n];
340 }
341
342 return ls;
343}
344
345static void
346free_label_state (struct unw_labeled_state *ls)
347{
348#ifdef ENABLE_MALLOC_CHECKING
349 labeled_state_alloced--;
350#endif
351
352 if (PTR_IN (emergency_labeled_state, ls))
353 atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls);
354 else
355 free (ls);
356}
357
358/* Routines to manipulate the state stack. */
359
360static void
361push (struct unw_state_record *sr)
362{
363 struct unw_reg_state *rs = alloc_reg_state ();
2a1ee410 364 memcpy (rs, &sr->curr, sizeof (*rs));
5025a549 365 sr->curr.next = rs;
2a1ee410
RH
366}
367
368static void
369pop (struct unw_state_record *sr)
370{
5025a549 371 struct unw_reg_state *rs = sr->curr.next;
2a1ee410 372
5025a549 373 if (!rs)
72e32876
RH
374 abort ();
375 memcpy (&sr->curr, rs, sizeof(*rs));
376 free_reg_state (rs);
2a1ee410
RH
377}
378
5025a549 379/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
72e32876 380
5025a549
DM
381static struct unw_reg_state *
382dup_state_stack (struct unw_reg_state *rs)
383{
384 struct unw_reg_state *copy, *prev = NULL, *first = NULL;
385
386 while (rs)
387 {
72e32876
RH
388 copy = alloc_reg_state ();
389 memcpy (copy, rs, sizeof(*copy));
5025a549
DM
390 if (first)
391 prev->next = copy;
392 else
393 first = copy;
394 rs = rs->next;
395 prev = copy;
396 }
72e32876 397
5025a549
DM
398 return first;
399}
400
401/* Free all stacked register states (but not RS itself). */
402static void
403free_state_stack (struct unw_reg_state *rs)
404{
405 struct unw_reg_state *p, *next;
406
407 for (p = rs->next; p != NULL; p = next)
408 {
409 next = p->next;
72e32876 410 free_reg_state (p);
5025a549
DM
411 }
412 rs->next = NULL;
413}
72e32876
RH
414
415/* Free all labeled states. */
416
417static void
418free_label_states (struct unw_labeled_state *ls)
419{
420 struct unw_labeled_state *next;
421
422 for (; ls ; ls = next)
423 {
424 next = ls->next;
425
426 free_state_stack (&ls->saved_state);
427 free_label_state (ls);
428 }
429}
5025a549
DM
430\f
431/* Unwind decoder routines */
432
2a1ee410
RH
433static enum unw_register_index __attribute__((const))
434decode_abreg (unsigned char abreg, int memory)
435{
436 switch (abreg)
437 {
b874a90d
DR
438#if TARGET_ABI_OPEN_VMS
439 /* OpenVMS Calling Standard specifies R3 - R31. */
440 case 0x03 ... 0x1f: return UNW_REG_R2 + (abreg - 0x02);
441#else
442 /* Standard Intel ABI specifies GR 4 - 7. */
2a1ee410 443 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
b874a90d 444#endif
2a1ee410
RH
445 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
446 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
447 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
448 case 0x60: return UNW_REG_PR;
449 case 0x61: return UNW_REG_PSP;
450 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
451 case 0x63: return UNW_REG_RP;
452 case 0x64: return UNW_REG_BSP;
453 case 0x65: return UNW_REG_BSPSTORE;
454 case 0x66: return UNW_REG_RNAT;
455 case 0x67: return UNW_REG_UNAT;
456 case 0x68: return UNW_REG_FPSR;
457 case 0x69: return UNW_REG_PFS;
458 case 0x6a: return UNW_REG_LC;
459 default:
460 abort ();
461 }
462}
463
464static void
465set_reg (struct unw_reg_info *reg, enum unw_where where,
466 int when, unsigned long val)
467{
468 reg->val = val;
469 reg->where = where;
470 if (reg->when == UNW_WHEN_NEVER)
471 reg->when = when;
472}
473
474static void
475alloc_spill_area (unsigned long *offp, unsigned long regsize,
476 struct unw_reg_info *lo, struct unw_reg_info *hi)
477{
478 struct unw_reg_info *reg;
479
480 for (reg = hi; reg >= lo; --reg)
481 {
482 if (reg->where == UNW_WHERE_SPILL_HOME)
483 {
484 reg->where = UNW_WHERE_PSPREL;
1d9ad0e0
RH
485 *offp -= regsize;
486 reg->val = *offp;
2a1ee410
RH
487 }
488 }
489}
490
491static inline void
492spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim,
493 unw_word t)
494{
495 struct unw_reg_info *reg;
496
497 for (reg = *regp; reg <= lim; ++reg)
498 {
499 if (reg->where == UNW_WHERE_SPILL_HOME)
500 {
501 reg->when = t;
502 *regp = reg + 1;
503 return;
504 }
505 }
506 /* Excess spill. */
507 abort ();
508}
509
510static void
511finish_prologue (struct unw_state_record *sr)
512{
513 struct unw_reg_info *reg;
514 unsigned long off;
515 int i;
516
517 /* First, resolve implicit register save locations
518 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
519
72e32876 520 for (i = 0; i < (int) sizeof (save_order); ++i)
2a1ee410
RH
521 {
522 reg = sr->curr.reg + save_order[i];
523 if (reg->where == UNW_WHERE_GR_SAVE)
524 {
525 reg->where = UNW_WHERE_GR;
526 reg->val = sr->gr_save_loc++;
527 }
528 }
529
530 /* Next, compute when the fp, general, and branch registers get saved.
531 This must come before alloc_spill_area() because we need to know
532 which registers are spilled to their home locations. */
533 if (sr->imask)
534 {
535 static unsigned char const limit[3] = {
536 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
537 };
538
539 unsigned char kind, mask = 0, *cp = sr->imask;
540 int t;
541 struct unw_reg_info *(regs[3]);
542
543 regs[0] = sr->curr.reg + UNW_REG_F2;
544 regs[1] = sr->curr.reg + UNW_REG_R4;
545 regs[2] = sr->curr.reg + UNW_REG_B1;
546
547 for (t = 0; t < sr->region_len; ++t)
548 {
549 if ((t & 3) == 0)
550 mask = *cp++;
551 kind = (mask >> 2*(3-(t & 3))) & 3;
552 if (kind > 0)
72e32876
RH
553 spill_next_when (&regs[kind - 1], sr->curr.reg + limit[kind - 1],
554 sr->region_start + t);
2a1ee410
RH
555 }
556 }
557
558 /* Next, lay out the memory stack spill area. */
559 if (sr->any_spills)
560 {
561 off = sr->spill_offset;
72e32876
RH
562 alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2,
563 sr->curr.reg + UNW_REG_F31);
564 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1,
565 sr->curr.reg + UNW_REG_B5);
566 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4,
567 sr->curr.reg + UNW_REG_R7);
2a1ee410
RH
568 }
569}
570
571/*
572 * Region header descriptors.
573 */
574
575static void
576desc_prologue (int body, unw_word rlen, unsigned char mask,
577 unsigned char grsave, struct unw_state_record *sr)
578{
579 int i;
580
581 if (!(sr->in_body || sr->first_region))
72e32876 582 finish_prologue (sr);
2a1ee410
RH
583 sr->first_region = 0;
584
585 /* Check if we're done. */
5025a549 586 if (sr->when_target < sr->region_start + sr->region_len)
2a1ee410
RH
587 {
588 sr->done = 1;
589 return;
590 }
591
592 for (i = 0; i < sr->epilogue_count; ++i)
72e32876
RH
593 pop (sr);
594
2a1ee410
RH
595 sr->epilogue_count = 0;
596 sr->epilogue_start = UNW_WHEN_NEVER;
597
598 if (!body)
72e32876 599 push (sr);
2a1ee410
RH
600
601 sr->region_start += sr->region_len;
602 sr->region_len = rlen;
603 sr->in_body = body;
604
605 if (!body)
606 {
607 for (i = 0; i < 4; ++i)
608 {
609 if (mask & 0x8)
610 set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR,
611 sr->region_start + sr->region_len - 1, grsave++);
612 mask <<= 1;
613 }
614 sr->gr_save_loc = grsave;
615 sr->any_spills = 0;
616 sr->imask = 0;
617 sr->spill_offset = 0x10; /* default to psp+16 */
618 }
619}
620
621/*
622 * Prologue descriptors.
623 */
624
625static inline void
3950dcdf
JJ
626desc_abi (unsigned char abi,
627 unsigned char context,
628 struct unw_state_record *sr)
2a1ee410 629{
3950dcdf 630 sr->unwabi = (abi << 8) | context;
2a1ee410
RH
631}
632
633static inline void
634desc_br_gr (unsigned char brmask, unsigned char gr,
635 struct unw_state_record *sr)
636{
637 int i;
638
639 for (i = 0; i < 5; ++i)
640 {
641 if (brmask & 1)
642 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
643 sr->region_start + sr->region_len - 1, gr++);
644 brmask >>= 1;
645 }
646}
647
648static inline void
649desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
650{
651 int i;
652
653 for (i = 0; i < 5; ++i)
654 {
655 if (brmask & 1)
656 {
657 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
658 sr->region_start + sr->region_len - 1, 0);
659 sr->any_spills = 1;
660 }
661 brmask >>= 1;
662 }
663}
664
665static inline void
666desc_frgr_mem (unsigned char grmask, unw_word frmask,
667 struct unw_state_record *sr)
668{
669 int i;
670
671 for (i = 0; i < 4; ++i)
672 {
673 if ((grmask & 1) != 0)
674 {
675 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
676 sr->region_start + sr->region_len - 1, 0);
677 sr->any_spills = 1;
678 }
679 grmask >>= 1;
680 }
681 for (i = 0; i < 20; ++i)
682 {
683 if ((frmask & 1) != 0)
684 {
1d9ad0e0
RH
685 enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4;
686 set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
2a1ee410
RH
687 sr->region_start + sr->region_len - 1, 0);
688 sr->any_spills = 1;
689 }
690 frmask >>= 1;
691 }
692}
693
694static inline void
695desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
696{
697 int i;
698
699 for (i = 0; i < 4; ++i)
700 {
701 if ((frmask & 1) != 0)
702 {
703 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
704 sr->region_start + sr->region_len - 1, 0);
705 sr->any_spills = 1;
706 }
707 frmask >>= 1;
708 }
709}
710
711static inline void
712desc_gr_gr (unsigned char grmask, unsigned char gr,
713 struct unw_state_record *sr)
714{
715 int i;
716
717 for (i = 0; i < 4; ++i)
718 {
719 if ((grmask & 1) != 0)
720 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
721 sr->region_start + sr->region_len - 1, gr++);
722 grmask >>= 1;
723 }
724}
725
726static inline void
727desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
728{
729 int i;
730
731 for (i = 0; i < 4; ++i)
732 {
733 if ((grmask & 1) != 0)
734 {
735 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
736 sr->region_start + sr->region_len - 1, 0);
737 sr->any_spills = 1;
738 }
739 grmask >>= 1;
740 }
741}
742
743static inline void
744desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
745{
746 set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
747 sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size);
748}
749
750static inline void
751desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
752{
753 sr->curr.reg[UNW_REG_PSP].when
754 = sr->region_start + MIN ((int)t, sr->region_len - 1);
755}
756
757static inline void
758desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
759{
760 set_reg (sr->curr.reg + reg, UNW_WHERE_GR,
761 sr->region_start + sr->region_len - 1, dst);
762}
763
764static inline void
765desc_reg_psprel (unsigned char reg, unw_word pspoff,
766 struct unw_state_record *sr)
767{
768 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL,
769 sr->region_start + sr->region_len - 1,
770 0x10 - 4*pspoff);
771}
772
773static inline void
774desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
775{
776 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL,
777 sr->region_start + sr->region_len - 1,
778 4*spoff);
779}
780
781static inline void
782desc_rp_br (unsigned char dst, struct unw_state_record *sr)
783{
784 sr->return_link_reg = dst;
785}
786
787static inline void
788desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
789{
790 struct unw_reg_info *reg = sr->curr.reg + regnum;
791
792 if (reg->where == UNW_WHERE_NONE)
793 reg->where = UNW_WHERE_GR_SAVE;
794 reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
795}
796
797static inline void
798desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
799{
800 sr->spill_offset = 0x10 - 4*pspoff;
801}
802
803static inline unsigned char *
804desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
805{
806 sr->imask = imaskp;
807 return imaskp + (2*sr->region_len + 7)/8;
808}
809
810/*
811 * Body descriptors.
812 */
813static inline void
814desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
815{
816 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
817 sr->epilogue_count = ecount + 1;
818}
819
820static inline void
821desc_copy_state (unw_word label, struct unw_state_record *sr)
822{
5025a549 823 struct unw_labeled_state *ls;
2a1ee410 824
5025a549 825 for (ls = sr->labeled_states; ls; ls = ls->next)
2a1ee410 826 {
5025a549
DM
827 if (ls->label == label)
828 {
72e32876
RH
829 free_state_stack (&sr->curr);
830 memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
831 sr->curr.next = dup_state_stack (ls->saved_state.next);
2a1ee410
RH
832 return;
833 }
834 }
835 abort ();
836}
837
838static inline void
839desc_label_state (unw_word label, struct unw_state_record *sr)
840{
72e32876 841 struct unw_labeled_state *ls = alloc_label_state ();
2a1ee410 842
5025a549 843 ls->label = label;
72e32876
RH
844 memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
845 ls->saved_state.next = dup_state_stack (sr->curr.next);
5025a549 846
72e32876 847 /* Insert into list of labeled states. */
5025a549
DM
848 ls->next = sr->labeled_states;
849 sr->labeled_states = ls;
2a1ee410
RH
850}
851
852/*
853 * General descriptors.
854 */
855
856static inline int
857desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
858{
859 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1))
860 return 0;
861 if (qp > 0)
862 {
863 if ((sr->pr_val & (1UL << qp)) == 0)
864 return 0;
865 sr->pr_mask |= (1UL << qp);
866 }
867 return 1;
868}
869
870static inline void
871desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
872 struct unw_state_record *sr)
873{
874 struct unw_reg_info *r;
875
876 if (! desc_is_active (qp, t, sr))
877 return;
878
879 r = sr->curr.reg + decode_abreg (abreg, 0);
880 r->where = UNW_WHERE_NONE;
881 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
882 r->val = 0;
883}
884
885static inline void
886desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg,
887 unsigned char x, unsigned char ytreg,
888 struct unw_state_record *sr)
889{
890 enum unw_where where = UNW_WHERE_GR;
891 struct unw_reg_info *r;
892
893 if (! desc_is_active (qp, t, sr))
894 return;
895
896 if (x)
897 where = UNW_WHERE_BR;
898 else if (ytreg & 0x80)
899 where = UNW_WHERE_FR;
900
901 r = sr->curr.reg + decode_abreg (abreg, 0);
902 r->where = where;
903 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
904 r->val = ytreg & 0x7f;
905}
906
907static inline void
908desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg,
909 unw_word pspoff, struct unw_state_record *sr)
910{
911 struct unw_reg_info *r;
912
913 if (! desc_is_active (qp, t, sr))
914 return;
915
916 r = sr->curr.reg + decode_abreg (abreg, 1);
917 r->where = UNW_WHERE_PSPREL;
918 r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
919 r->val = 0x10 - 4*pspoff;
920}
921
922static inline void
923desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg,
924 unw_word spoff, struct unw_state_record *sr)
925{
926 struct unw_reg_info *r;
927
928 if (! desc_is_active (qp, t, sr))
929 return;
930
931 r = sr->curr.reg + decode_abreg (abreg, 1);
932 r->where = UNW_WHERE_SPREL;
933 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
934 r->val = 4*spoff;
935}
936
937\f
938#define UNW_DEC_BAD_CODE(code) abort ();
939
940/* Region headers. */
941#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
942#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
943
ed168e45 944/* Prologue descriptors. */
2a1ee410
RH
945#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
946#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
947#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
948#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
949#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
950#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
951#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
952#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
953#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
954#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
955#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
956#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
957#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
958#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
959#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
960#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
961#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
962#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
963#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
964#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
965#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
966
967/* Body descriptors. */
968#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
969#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
970#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
971
972/* General unwind descriptors. */
973#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
974#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
975#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
976#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
977#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
978#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
979#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
980#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
981
982\f
983/*
984 * Generic IA-64 unwind info decoder.
985 *
986 * This file is used both by the Linux kernel and objdump. Please keep
987 * the copies of this file in sync.
988 *
989 * You need to customize the decoder by defining the following
990 * macros/constants before including this file:
991 *
992 * Types:
993 * unw_word Unsigned integer type with at least 64 bits
994 *
995 * Register names:
996 * UNW_REG_BSP
997 * UNW_REG_BSPSTORE
998 * UNW_REG_FPSR
999 * UNW_REG_LC
1000 * UNW_REG_PFS
1001 * UNW_REG_PR
1002 * UNW_REG_RNAT
1003 * UNW_REG_PSP
1004 * UNW_REG_RP
1005 * UNW_REG_UNAT
1006 *
1007 * Decoder action macros:
1008 * UNW_DEC_BAD_CODE(code)
1009 * UNW_DEC_ABI(fmt,abi,context,arg)
1010 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
1011 * UNW_DEC_BR_MEM(fmt,brmask,arg)
1012 * UNW_DEC_COPY_STATE(fmt,label,arg)
1013 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
1014 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
1015 * UNW_DEC_FR_MEM(fmt,frmask,arg)
1016 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
1017 * UNW_DEC_GR_MEM(fmt,grmask,arg)
1018 * UNW_DEC_LABEL_STATE(fmt,label,arg)
1019 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
1020 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
1021 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
1022 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
1023 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
1024 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
1025 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
1026 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
1027 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
1028 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
1029 * UNW_DEC_REG_REG(fmt,src,dst,arg)
1030 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
1031 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
1032 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
1033 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
1034 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
1035 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
1036 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
1037 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
1038 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
1039 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
1040 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
1041 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
1042 */
1043
1044static unw_word
1045unw_decode_uleb128 (unsigned char **dpp)
1046{
1047 unsigned shift = 0;
1048 unw_word byte, result = 0;
1049 unsigned char *bp = *dpp;
1050
1051 while (1)
1052 {
1053 byte = *bp++;
1054 result |= (byte & 0x7f) << shift;
1055 if ((byte & 0x80) == 0)
1056 break;
1057 shift += 7;
1058 }
1059 *dpp = bp;
1060 return result;
1061}
1062
1063static unsigned char *
1064unw_decode_x1 (unsigned char *dp,
1065 unsigned char code __attribute__((unused)),
1066 void *arg)
1067{
1068 unsigned char byte1, abreg;
1069 unw_word t, off;
1070
1071 byte1 = *dp++;
1072 t = unw_decode_uleb128 (&dp);
1073 off = unw_decode_uleb128 (&dp);
1074 abreg = (byte1 & 0x7f);
1075 if (byte1 & 0x80)
1076 UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
1077 else
1078 UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
1079 return dp;
1080}
1081
1082static unsigned char *
1083unw_decode_x2 (unsigned char *dp,
1084 unsigned char code __attribute__((unused)),
1085 void *arg)
1086{
1087 unsigned char byte1, byte2, abreg, x, ytreg;
1088 unw_word t;
1089
1090 byte1 = *dp++; byte2 = *dp++;
1091 t = unw_decode_uleb128 (&dp);
1092 abreg = (byte1 & 0x7f);
1093 ytreg = byte2;
1094 x = (byte1 >> 7) & 1;
1095 if ((byte1 & 0x80) == 0 && ytreg == 0)
1096 UNW_DEC_RESTORE(X2, t, abreg, arg);
1097 else
1098 UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
1099 return dp;
1100}
1101
1102static unsigned char *
1103unw_decode_x3 (unsigned char *dp,
1104 unsigned char code __attribute__((unused)),
1105 void *arg)
1106{
1107 unsigned char byte1, byte2, abreg, qp;
1108 unw_word t, off;
1109
1110 byte1 = *dp++; byte2 = *dp++;
1111 t = unw_decode_uleb128 (&dp);
1112 off = unw_decode_uleb128 (&dp);
1113
1114 qp = (byte1 & 0x3f);
1115 abreg = (byte2 & 0x7f);
1116
1117 if (byte1 & 0x80)
1118 UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
1119 else
1120 UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
1121 return dp;
1122}
1123
1124static unsigned char *
1125unw_decode_x4 (unsigned char *dp,
1126 unsigned char code __attribute__((unused)),
1127 void *arg)
1128{
1129 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
1130 unw_word t;
1131
1132 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1133 t = unw_decode_uleb128 (&dp);
1134
1135 qp = (byte1 & 0x3f);
1136 abreg = (byte2 & 0x7f);
1137 x = (byte2 >> 7) & 1;
1138 ytreg = byte3;
1139
1140 if ((byte2 & 0x80) == 0 && byte3 == 0)
1141 UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
1142 else
1143 UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
1144 return dp;
1145}
1146
1147static unsigned char *
1148unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
1149{
1150 int body = (code & 0x20) != 0;
1151 unw_word rlen;
1152
1153 rlen = (code & 0x1f);
1154 UNW_DEC_PROLOGUE(R1, body, rlen, arg);
1155 return dp;
1156}
1157
1158static unsigned char *
1159unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
1160{
1161 unsigned char byte1, mask, grsave;
1162 unw_word rlen;
1163
1164 byte1 = *dp++;
1165
1166 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1167 grsave = (byte1 & 0x7f);
1168 rlen = unw_decode_uleb128 (&dp);
1169 UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
1170 return dp;
1171}
1172
1173static unsigned char *
1174unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
1175{
1176 unw_word rlen;
1177
1178 rlen = unw_decode_uleb128 (&dp);
1179 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
1180 return dp;
1181}
1182
1183static unsigned char *
1184unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
1185{
1186 unsigned char brmask = (code & 0x1f);
1187
1188 UNW_DEC_BR_MEM(P1, brmask, arg);
1189 return dp;
1190}
1191
1192static unsigned char *
1193unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
1194{
1195 if ((code & 0x10) == 0)
1196 {
1197 unsigned char byte1 = *dp++;
1198
1199 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
1200 (byte1 & 0x7f), arg);
1201 }
1202 else if ((code & 0x08) == 0)
1203 {
1204 unsigned char byte1 = *dp++, r, dst;
1205
1206 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1207 dst = (byte1 & 0x7f);
1208 switch (r)
1209 {
1210 case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
1211 case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
1212 case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
1213 case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
1214 case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
1215 case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
1216 case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
1217 case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
1218 case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
1219 case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
1220 case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
1221 case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
1222 default: UNW_DEC_BAD_CODE(r); break;
1223 }
1224 }
1225 else if ((code & 0x7) == 0)
1226 UNW_DEC_SPILL_MASK(P4, dp, arg);
1227 else if ((code & 0x7) == 1)
1228 {
1229 unw_word grmask, frmask, byte1, byte2, byte3;
1230
1231 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1232 grmask = ((byte1 >> 4) & 0xf);
1233 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
1234 UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
1235 }
1236 else
1237 UNW_DEC_BAD_CODE(code);
1238 return dp;
1239}
1240
1241static unsigned char *
1242unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
1243{
1244 int gregs = (code & 0x10) != 0;
1245 unsigned char mask = (code & 0x0f);
1246
1247 if (gregs)
1248 UNW_DEC_GR_MEM(P6, mask, arg);
1249 else
1250 UNW_DEC_FR_MEM(P6, mask, arg);
1251 return dp;
1252}
1253
1254static unsigned char *
1255unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
1256{
1257 unsigned char r, byte1, byte2;
1258 unw_word t, size;
1259
1260 if ((code & 0x10) == 0)
1261 {
1262 r = (code & 0xf);
1263 t = unw_decode_uleb128 (&dp);
1264 switch (r)
1265 {
1266 case 0:
1267 size = unw_decode_uleb128 (&dp);
1268 UNW_DEC_MEM_STACK_F(P7, t, size, arg);
1269 break;
1270
1271 case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
1272 case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
1273 case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
1274 case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
1275 case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
1276 case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
1277 case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
1278 case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
1279 case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
1280 case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
1281 case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
1282 case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
1283 case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
1284 case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
1285 case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
1286 default: UNW_DEC_BAD_CODE(r); break;
1287 }
1288 }
1289 else
1290 {
1291 switch (code & 0xf)
1292 {
1293 case 0x0: /* p8 */
1294 {
1295 r = *dp++;
1296 t = unw_decode_uleb128 (&dp);
1297 switch (r)
1298 {
1299 case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
1300 case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
1301 case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
1302 case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
1303 case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
1304 case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
1305 case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
1306 case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
1307 case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
1308 case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
1309 case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1310 case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1311 case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
1312 case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
1313 case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
1314 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
1315 case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
1316 case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
1317 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
1318 default: UNW_DEC_BAD_CODE(r); break;
1319 }
1320 }
1321 break;
1322
1323 case 0x1:
1324 byte1 = *dp++; byte2 = *dp++;
1325 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
1326 break;
1327
1328 case 0xf: /* p10 */
1329 byte1 = *dp++; byte2 = *dp++;
1330 UNW_DEC_ABI(P10, byte1, byte2, arg);
1331 break;
1332
1333 case 0x9:
1334 return unw_decode_x1 (dp, code, arg);
1335
1336 case 0xa:
1337 return unw_decode_x2 (dp, code, arg);
1338
1339 case 0xb:
1340 return unw_decode_x3 (dp, code, arg);
1341
1342 case 0xc:
1343 return unw_decode_x4 (dp, code, arg);
1344
1345 default:
1346 UNW_DEC_BAD_CODE(code);
1347 break;
1348 }
1349 }
1350 return dp;
1351}
1352
1353static unsigned char *
1354unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
1355{
1356 unw_word label = (code & 0x1f);
1357
1358 if ((code & 0x20) != 0)
1359 UNW_DEC_COPY_STATE(B1, label, arg);
1360 else
1361 UNW_DEC_LABEL_STATE(B1, label, arg);
1362 return dp;
1363}
1364
1365static unsigned char *
1366unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
1367{
1368 unw_word t;
1369
1370 t = unw_decode_uleb128 (&dp);
1371 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
1372 return dp;
1373}
1374
1375static unsigned char *
1376unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
1377{
1378 unw_word t, ecount, label;
1379
1380 if ((code & 0x10) == 0)
1381 {
1382 t = unw_decode_uleb128 (&dp);
1383 ecount = unw_decode_uleb128 (&dp);
1384 UNW_DEC_EPILOGUE(B3, t, ecount, arg);
1385 }
1386 else if ((code & 0x07) == 0)
1387 {
1388 label = unw_decode_uleb128 (&dp);
1389 if ((code & 0x08) != 0)
1390 UNW_DEC_COPY_STATE(B4, label, arg);
1391 else
1392 UNW_DEC_LABEL_STATE(B4, label, arg);
1393 }
1394 else
1395 switch (code & 0x7)
1396 {
1397 case 1: return unw_decode_x1 (dp, code, arg);
1398 case 2: return unw_decode_x2 (dp, code, arg);
1399 case 3: return unw_decode_x3 (dp, code, arg);
1400 case 4: return unw_decode_x4 (dp, code, arg);
1401 default: UNW_DEC_BAD_CODE(code); break;
1402 }
1403 return dp;
1404}
1405
1406typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
1407
0139adca 1408static const unw_decoder unw_decode_table[2][8] =
2a1ee410
RH
1409{
1410 /* prologue table: */
1411 {
1412 unw_decode_r1, /* 0 */
1413 unw_decode_r1,
1414 unw_decode_r2,
1415 unw_decode_r3,
1416 unw_decode_p1, /* 4 */
1417 unw_decode_p2_p5,
1418 unw_decode_p6,
1419 unw_decode_p7_p10
1420 },
1421 {
1422 unw_decode_r1, /* 0 */
1423 unw_decode_r1,
1424 unw_decode_r2,
1425 unw_decode_r3,
1426 unw_decode_b1, /* 4 */
1427 unw_decode_b1,
1428 unw_decode_b2,
1429 unw_decode_b3_x4
1430 }
1431};
1432
1433/*
1434 * Decode one descriptor and return address of next descriptor.
1435 */
1436static inline unsigned char *
1437unw_decode (unsigned char *dp, int inside_body, void *arg)
1438{
1439 unw_decoder decoder;
1440 unsigned char code;
1441
1442 code = *dp++;
1443 decoder = unw_decode_table[inside_body][code >> 5];
1444 dp = (*decoder) (dp, code, arg);
1445 return dp;
1446}
1447
1448\f
1449/* RSE helper functions. */
1450
1451static inline unsigned long
1452ia64_rse_slot_num (unsigned long *addr)
1453{
1454 return (((unsigned long) addr) >> 3) & 0x3f;
1455}
1456
1457/* Return TRUE if ADDR is the address of an RNAT slot. */
1458static inline unsigned long
1459ia64_rse_is_rnat_slot (unsigned long *addr)
1460{
1461 return ia64_rse_slot_num (addr) == 0x3f;
1462}
1463
1464/* Returns the address of the RNAT slot that covers the slot at
1465 address SLOT_ADDR. */
1466static inline unsigned long *
1467ia64_rse_rnat_addr (unsigned long *slot_addr)
1468{
1469 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
1470}
1471
9e4f94de 1472/* Calculate the number of registers in the dirty partition starting at
2a1ee410
RH
1473 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1474 divided by eight because the 64th slot is used to store ar.rnat. */
1475static inline unsigned long
1476ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
1477{
1478 unsigned long slots = (bsp - bspstore);
1479
1480 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40;
1481}
1482
1483/* The inverse of the above: given bspstore and the number of
1484 registers, calculate ar.bsp. */
1485static inline unsigned long *
1486ia64_rse_skip_regs (unsigned long *addr, long num_regs)
1487{
1488 long delta = ia64_rse_slot_num (addr) + num_regs;
1489
1490 if (num_regs < 0)
1491 delta -= 0x3e;
1492 return addr + num_regs + delta/0x3f;
1493}
1494
1495\f
e8c89d29
JJ
1496/* Copy register backing store from SRC to DST, LEN words
1497 (which include both saved registers and nat collections).
1498 DST_RNAT is a partial nat collection for DST. SRC and DST
1499 don't have to be equal modulo 64 slots, so it cannot be
1500 done with a simple memcpy as the nat collections will be
1501 at different relative offsets and need to be combined together. */
1502static void
1503ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst,
1504 unsigned long src, long len, unsigned long dst_rnat)
1505{
1506 long count;
1507 unsigned long src_rnat;
1508 unsigned long shift1, shift2;
1509
1510 len <<= 3;
1511 dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1;
1512 src_rnat = src >= info->regstk_top
1513 ? info->rnat : *(unsigned long *) (src | 0x1f8);
1514 src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1);
1515 /* Just to make sure. */
1516 src_rnat &= ~(1UL << 63);
1517 shift1 = ((dst - src) >> 3) & 0x3f;
1518 if ((dst & 0x1f8) < (src & 0x1f8))
1519 shift1--;
1520 shift2 = 0x3f - shift1;
1521 if ((dst & 0x1f8) >= (src & 0x1f8))
1522 {
1523 count = ~dst & 0x1f8;
1524 goto first;
1525 }
1526 count = ~src & 0x1f8;
1527 goto second;
1528 while (len > 0)
1529 {
1530 src_rnat = src >= info->regstk_top
1531 ? info->rnat : *(unsigned long *) (src | 0x1f8);
1532 /* Just to make sure. */
1533 src_rnat &= ~(1UL << 63);
1534 count = shift2 << 3;
1535first:
1536 if (count > len)
1537 count = len;
1538 memcpy ((char *) dst, (char *) src, count);
1539 dst += count;
1540 src += count;
1541 len -= count;
1542 dst_rnat |= (src_rnat << shift1) & ~(1UL << 63);
1543 if (len <= 0)
1544 break;
1545 *(long *) dst = dst_rnat;
1546 dst += 8;
1547 dst_rnat = 0;
1548 count = shift1 << 3;
1549second:
1550 if (count > len)
1551 count = len;
1552 memcpy ((char *) dst, (char *) src, count);
1553 dst += count;
1554 src += count + 8;
1555 len -= count + 8;
1556 dst_rnat |= (src_rnat >> shift2);
1557 }
1558 if ((dst & 0x1f8) == 0x1f8)
1559 {
1560 *(long *) dst = dst_rnat;
1561 dst += 8;
1562 dst_rnat = 0;
1563 }
1564 /* Set info->regstk_top to lowest rbs address which will use
1565 info->rnat collection. */
1566 info->regstk_top = dst & ~0x1ffUL;
1567 info->rnat = dst_rnat;
1568}
1569
2a1ee410
RH
1570/* Unwind accessors. */
1571
1572static void
1573unw_access_gr (struct _Unwind_Context *info, int regnum,
1574 unsigned long *val, char *nat, int write)
1575{
1576 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat;
1577 struct unw_ireg *ireg;
1578
1579 if ((unsigned) regnum - 1 >= 127)
1580 abort ();
1581
1582 if (regnum < 1)
1583 {
1584 nat_addr = addr = &dummy_nat;
1585 dummy_nat = 0;
1586 }
1587 else if (regnum < 32)
1588 {
1589 /* Access a non-stacked register. */
4d9720f0 1590 ireg = &info->ireg[regnum - 2];
2a1ee410
RH
1591 addr = ireg->loc;
1592 if (addr)
1593 {
1594 nat_addr = addr + ireg->nat.off;
1595 switch (ireg->nat.type)
1596 {
1597 case UNW_NAT_VAL:
1598 /* Simulate getf.sig/setf.sig. */
1599 if (write)
1600 {
1601 if (*nat)
1602 {
1603 /* Write NaTVal and be done with it. */
1604 addr[0] = 0;
1605 addr[1] = 0x1fffe;
1606 return;
1607 }
1608 addr[1] = 0x1003e;
1609 }
1610 else if (addr[0] == 0 && addr[1] == 0x1ffe)
1611 {
1612 /* Return NaT and be done with it. */
1613 *val = 0;
1614 *nat = 1;
1615 return;
1616 }
5efb1046 1617 /* FALLTHRU */
2a1ee410
RH
1618
1619 case UNW_NAT_NONE:
1620 dummy_nat = 0;
1621 nat_addr = &dummy_nat;
1622 break;
1623
1624 case UNW_NAT_MEMSTK:
1625 nat_mask = 1UL << ((long) addr & 0x1f8)/8;
1626 break;
1627
1628 case UNW_NAT_REGSTK:
e8c89d29 1629 if ((unsigned long) addr >= info->regstk_top)
2a1ee410 1630 nat_addr = &info->rnat;
e8c89d29
JJ
1631 else
1632 nat_addr = ia64_rse_rnat_addr (addr);
2a1ee410
RH
1633 nat_mask = 1UL << ia64_rse_slot_num (addr);
1634 break;
1635 }
1636 }
1637 }
1638 else
1639 {
1640 /* Access a stacked register. */
1641 addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
e8c89d29 1642 if ((unsigned long) addr >= info->regstk_top)
2a1ee410 1643 nat_addr = &info->rnat;
e8c89d29
JJ
1644 else
1645 nat_addr = ia64_rse_rnat_addr (addr);
2a1ee410
RH
1646 nat_mask = 1UL << ia64_rse_slot_num (addr);
1647 }
1648
1649 if (write)
1650 {
1651 *addr = *val;
1652 if (*nat)
1653 *nat_addr |= nat_mask;
1654 else
1655 *nat_addr &= ~nat_mask;
1656 }
1657 else
1658 {
1659 *val = *addr;
1660 *nat = (*nat_addr & nat_mask) != 0;
1661 }
1662}
1663\f
1664/* Get the value of register REG as saved in CONTEXT. */
1665
1666_Unwind_Word
1667_Unwind_GetGR (struct _Unwind_Context *context, int index)
1668{
1669 _Unwind_Word ret;
1670 char nat;
1671
1672 if (index == 1)
1673 return context->gp;
1674 else if (index >= 15 && index <= 18)
1675 return context->eh_data[index - 15];
1676 else
1677 unw_access_gr (context, index, &ret, &nat, 0);
1678
1679 return ret;
1680}
1681
1682/* Overwrite the saved value for register REG in CONTEXT with VAL. */
1683
1684void
1685_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
1686{
1687 char nat = 0;
1688
1689 if (index == 1)
1690 context->gp = val;
1691 else if (index >= 15 && index <= 18)
1692 context->eh_data[index - 15] = val;
1693 else
1694 unw_access_gr (context, index, &val, &nat, 1);
1695}
1696
1697/* Retrieve the return address for CONTEXT. */
1698
1699inline _Unwind_Ptr
1700_Unwind_GetIP (struct _Unwind_Context *context)
1701{
1702 return context->rp;
1703}
1704
754e45a8
JJ
1705inline _Unwind_Ptr
1706_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
1707{
1708 *ip_before_insn = 0;
1709 return context->rp;
1710}
1711
2a1ee410
RH
1712/* Overwrite the return address for CONTEXT with VAL. */
1713
1714inline void
1715_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1716{
1717 context->rp = val;
1718}
1719
1720void *
1721_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1722{
1723 return context->lsda;
1724}
1725
1726_Unwind_Ptr
1727_Unwind_GetRegionStart (struct _Unwind_Context *context)
1728{
1729 return context->region_start;
1730}
1731
5dafd282 1732void *
5154b05d 1733_Unwind_FindEnclosingFunction (void *pc)
5dafd282 1734{
b874a90d 1735 struct unw_table_entry *entp, ent;
61193e7b
RH
1736 unsigned long segment_base, gp;
1737
b874a90d
DR
1738 entp = _Unwind_FindTableEntry (pc, &segment_base, &gp, &ent);
1739 if (entp == NULL)
61193e7b
RH
1740 return NULL;
1741 else
b874a90d 1742 return (void *)(segment_base + entp->start_offset);
61193e7b
RH
1743}
1744
1745/* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance,
1746 the CFA is the value of the stack pointer on entry; In IA-64 unwind
1747 parlance, this is the PSP. */
1748
1749_Unwind_Word
1750_Unwind_GetCFA (struct _Unwind_Context *context)
1751{
1752 return (_Unwind_Ptr) context->psp;
5dafd282
AH
1753}
1754
bc93e287
JJ
1755/* Get the value of the Backing Store Pointer as saved in CONTEXT. */
1756
1757_Unwind_Word
1758_Unwind_GetBSP (struct _Unwind_Context *context)
1759{
1760 return (_Unwind_Ptr) context->bsp;
1761}
1762
58cd1d70 1763#include "md-unwind-support.h"
201cdb74
RO
1764
1765/* By default, assume personality routine interface compatibility with
1766 our expectations. */
1767#ifndef MD_UNW_COMPATIBLE_PERSONALITY_P
1768#define MD_UNW_COMPATIBLE_PERSONALITY_P(HEADER) 1
1769#endif
1770
2a1ee410
RH
1771\f
1772static _Unwind_Reason_Code
1773uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1774{
b874a90d 1775 struct unw_table_entry *entp, ent;
2a1ee410
RH
1776 unsigned long *unw, header, length;
1777 unsigned char *insn, *insn_end;
1778 unsigned long segment_base;
d7e60e95 1779 struct unw_reg_info *r;
2a1ee410
RH
1780
1781 memset (fs, 0, sizeof (*fs));
d7e60e95
HB
1782 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1783 r->when = UNW_WHEN_NEVER;
2a1ee410
RH
1784 context->lsda = 0;
1785
b874a90d
DR
1786 entp = _Unwind_FindTableEntry ((void *) context->rp,
1787 &segment_base, &context->gp, &ent);
1788 if (entp == NULL)
2a1ee410
RH
1789 {
1790 /* Couldn't find unwind info for this function. Try an
1791 os-specific fallback mechanism. This will necessarily
4d9720f0 1792 not provide a personality routine or LSDA. */
2a1ee410 1793#ifdef MD_FALLBACK_FRAME_STATE_FOR
8662eb14
AM
1794 if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON)
1795 return _URC_NO_REASON;
ac77b88e 1796#endif
443621af
RH
1797
1798 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1799 handlers, and which keeps the return value in B0 does not need
1800 an unwind table entry.
1801
1802 This can only happen in the frame after unwinding through a signal
897105a1
JJ
1803 handler. Avoid infinite looping by requiring that B0 != RP.
1804 RP == 0 terminates the chain. */
ac77b88e
EB
1805 if (context->br_loc[0]
1806 && *context->br_loc[0] != context->rp
897105a1 1807 && context->rp != 0)
ac77b88e
EB
1808 goto skip_unwind_info;
1809
8662eb14 1810 return _URC_END_OF_STACK;
2a1ee410
RH
1811 }
1812
b874a90d 1813 context->region_start = entp->start_offset + segment_base;
e8c89d29
JJ
1814 fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3
1815 + (context->rp & 15);
2a1ee410 1816
b874a90d 1817 unw = (unsigned long *) (entp->info_offset + segment_base);
2a1ee410
RH
1818 header = *unw;
1819 length = UNW_LENGTH (header);
1820
b874a90d
DR
1821 /* Some operating systems use the personality routine slot in way not
1822 compatible with what we expect. For instance, OpenVMS uses this slot to
1823 designate "condition handlers" with very different arguments than what we
1824 would be providing. Such cases are typically identified from OS specific
1825 bits in the unwind information block header, and checked by the target
1826 MD_UNW_COMPATIBLE_PERSONALITY_P macro.
1827
1828 We just pretend there is no personality from our standpoint in such
1829 situations, and expect GCC not to set the identifying bits itself so that
1830 compatible personalities for GCC compiled code are called.
1831
1832 Of course, this raises the question of what combinations of native/GCC
1833 calls can be expected to behave properly exception handling-wise. We are
1834 not to provide a magic answer here, merely to prevent crashes assuming
1835 users know what they are doing.
1836
1837 ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK as well. */
2a1ee410 1838
b874a90d
DR
1839 if (MD_UNW_COMPATIBLE_PERSONALITY_P (header)
1840 && (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header)))
2a1ee410
RH
1841 {
1842 fs->personality =
1843 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1844 context->lsda = unw + length + 2;
1845 }
1846
1847 insn = (unsigned char *) (unw + 1);
1848 insn_end = (unsigned char *) (unw + 1 + length);
1849 while (!fs->done && insn < insn_end)
1850 insn = unw_decode (insn, fs->in_body, fs);
1851
72e32876
RH
1852 free_label_states (fs->labeled_states);
1853 free_state_stack (&fs->curr);
1854
1855#ifdef ENABLE_MALLOC_CHECKING
1856 if (reg_state_alloced || labeled_state_alloced)
1857 abort ();
1858#endif
1859
2a1ee410
RH
1860 /* If we're in the epilogue, sp has been restored and all values
1861 on the memory stack below psp also have been restored. */
1862 if (fs->when_target > fs->epilogue_start)
1863 {
1864 struct unw_reg_info *r;
1865
1866 fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1867 fs->curr.reg[UNW_REG_PSP].val = 0;
1868 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1869 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1870 || r->where == UNW_WHERE_SPREL)
1871 r->where = UNW_WHERE_NONE;
1872 }
1873
ac77b88e
EB
1874skip_unwind_info:
1875 /* If RP didn't get saved, generate entry for the return link register. */
2a1ee410
RH
1876 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target)
1877 {
1878 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1879 fs->curr.reg[UNW_REG_RP].when = -1;
1880 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg;
1881 }
1882
ac77b88e
EB
1883 /* There is a subtlety for the frame after unwinding through a signal
1884 handler: should we restore the cfm as usual or the pfs? We can't
1885 restore both because we use br.ret to resume execution of user code.
1886 For other frames the procedure is by definition non-leaf so the pfs
1887 is saved and restored and thus effectively dead in the body; only
1888 the cfm need therefore be restored.
1889
1890 Here we have 2 cases:
1891 - either the pfs is saved and restored and thus effectively dead
1892 like in regular frames; then we do nothing special and restore
1893 the cfm.
1894 - or the pfs is not saved and thus live; but in that case the
1895 procedure is necessarily leaf so the cfm is effectively dead
1896 and we restore the pfs. */
1897 if (context->signal_pfs_loc)
1898 {
1899 if (fs->curr.reg[UNW_REG_PFS].when >= fs->when_target)
1900 context->pfs_loc = context->signal_pfs_loc;
1901 context->signal_pfs_loc = NULL;
1902 }
1903
2a1ee410
RH
1904 return _URC_NO_REASON;
1905}
1906
1907static void
1908uw_update_reg_address (struct _Unwind_Context *context,
1909 _Unwind_FrameState *fs,
1910 enum unw_register_index regno)
1911{
1912 struct unw_reg_info *r = fs->curr.reg + regno;
1913 void *addr;
1914 unsigned long rval;
1915
1916 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1917 return;
1918
1919 rval = r->val;
1920 switch (r->where)
1921 {
1922 case UNW_WHERE_GR:
1923 if (rval >= 32)
1924 addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32);
1925 else if (rval >= 2)
1926 addr = context->ireg[rval - 2].loc;
b80c0987
JJ
1927 else if (rval == 0)
1928 {
1929 static const unsigned long dummy;
1930 addr = (void *) &dummy;
1931 }
2a1ee410
RH
1932 else
1933 abort ();
1934 break;
1935
1936 case UNW_WHERE_FR:
1937 if (rval >= 2 && rval < 32)
1938 addr = context->fr_loc[rval - 2];
1939 else
1940 abort ();
1941 break;
1942
1943 case UNW_WHERE_BR:
443621af 1944 /* Note that while RVAL can only be 1-5 from normal descriptors,
3950dcdf 1945 we can want to look at B0, B6 and B7 due to having manually unwound a
443621af 1946 signal frame. */
3950dcdf 1947 if (rval < 8)
443621af 1948 addr = context->br_loc[rval];
2a1ee410
RH
1949 else
1950 abort ();
1951 break;
1952
1953 case UNW_WHERE_SPREL:
1954 addr = (void *)(context->sp + rval);
1955 break;
1956
1957 case UNW_WHERE_PSPREL:
1958 addr = (void *)(context->psp + rval);
1959 break;
1960
1961 default:
1962 abort ();
1963 }
1964
1965 switch (regno)
1966 {
1967 case UNW_REG_R2 ... UNW_REG_R31:
1968 context->ireg[regno - UNW_REG_R2].loc = addr;
1969 switch (r->where)
1970 {
1971 case UNW_WHERE_GR:
1972 if (rval >= 32)
1973 {
1974 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1975 context->ireg[regno - UNW_REG_R2].nat.off
1976 = context->pri_unat_loc - (unsigned long *) addr;
1977 }
1978 else if (rval >= 2)
1979 {
1980 context->ireg[regno - UNW_REG_R2].nat
1981 = context->ireg[rval - 2].nat;
1982 }
b80c0987
JJ
1983 else if (rval == 0)
1984 {
1985 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1986 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1987 }
2a1ee410
RH
1988 else
1989 abort ();
1990 break;
1991
1992 case UNW_WHERE_FR:
1993 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL;
1994 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1995 break;
1996
1997 case UNW_WHERE_BR:
1998 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1999 context->ireg[regno - UNW_REG_R2].nat.off = 0;
2000 break;
2001
2002 case UNW_WHERE_PSPREL:
2003 case UNW_WHERE_SPREL:
2004 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
2005 context->ireg[regno - UNW_REG_R2].nat.off
2006 = context->pri_unat_loc - (unsigned long *) addr;
2007 break;
2008
2009 default:
2010 abort ();
2011 }
2012 break;
2013
2014 case UNW_REG_F2 ... UNW_REG_F31:
2015 context->fr_loc[regno - UNW_REG_F2] = addr;
2016 break;
2017
2018 case UNW_REG_B1 ... UNW_REG_B5:
443621af 2019 context->br_loc[regno - UNW_REG_B0] = addr;
2a1ee410
RH
2020 break;
2021
2022 case UNW_REG_BSP:
2023 context->bsp_loc = addr;
2024 break;
2025 case UNW_REG_BSPSTORE:
2026 context->bspstore_loc = addr;
2027 break;
2028 case UNW_REG_PFS:
2029 context->pfs_loc = addr;
2030 break;
2031 case UNW_REG_RP:
2032 context->rp = *(unsigned long *)addr;
2033 break;
2034 case UNW_REG_UNAT:
2035 context->unat_loc = addr;
2036 break;
2037 case UNW_REG_PR:
2038 context->pr = *(unsigned long *) addr;
2039 break;
2040 case UNW_REG_LC:
2041 context->lc_loc = addr;
2042 break;
2043 case UNW_REG_FPSR:
2044 context->fpsr_loc = addr;
2045 break;
2046
2047 case UNW_REG_PSP:
2048 context->psp = *(unsigned long *)addr;
2049 break;
2050
72e32876 2051 default:
2a1ee410
RH
2052 abort ();
2053 }
2054}
2055
2056static void
2057uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2058{
2059 long i;
2060
3950dcdf
JJ
2061#ifdef MD_HANDLE_UNWABI
2062 MD_HANDLE_UNWABI (context, fs);
2063#endif
2064
2a1ee410
RH
2065 context->sp = context->psp;
2066
2067 /* First, set PSP. Subsequent instructions may depend on this value. */
2068 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
2069 {
2070 if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
2071 context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val;
2072 else
2073 uw_update_reg_address (context, fs, UNW_REG_PSP);
2074 }
2075
2076 /* Determine the location of the primary UNaT. */
2077 {
2078 int i;
2079 if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2080 i = UNW_REG_PRI_UNAT_MEM;
2081 else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when)
2082 i = UNW_REG_PRI_UNAT_GR;
2083 else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when
2084 > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2085 i = UNW_REG_PRI_UNAT_MEM;
2086 else
2087 i = UNW_REG_PRI_UNAT_GR;
2088 uw_update_reg_address (context, fs, i);
2089 }
2090
2091 /* Compute the addresses of all registers saved in this frame. */
2092 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
2093 uw_update_reg_address (context, fs, i);
2094
2095 /* Unwind BSP for the local registers allocated this frame. */
2096 /* ??? What to do with stored BSP or BSPSTORE registers. */
d7e60e95
HB
2097 /* We assert that we are either at a call site, or we have
2098 just unwound through a signal frame. In either case
2099 pfs_loc is valid. */
2100 if (!(fs -> no_reg_stack_frame))
2a1ee410
RH
2101 {
2102 unsigned long pfs = *context->pfs_loc;
2103 unsigned long sol = (pfs >> 7) & 0x7f;
2104 context->bsp = (unsigned long)
2105 ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol);
2106 }
2107}
2108
60aef23e
DJ
2109static void
2110uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2111{
2112 uw_update_context (context, fs);
2113}
2114
2a1ee410 2115/* Fill in CONTEXT for top-of-stack. The only valid registers at this
a58b0342 2116 level will be the return address and the CFA. Note that CFA = SP+16. */
2a1ee410 2117
4d9720f0
HB
2118#define uw_init_context(CONTEXT) \
2119 do { \
2120 /* ??? There is a whole lot o code in uw_install_context that \
2121 tries to avoid spilling the entire machine state here. We \
2122 should try to make that work again. */ \
2123 __builtin_unwind_init(); \
2124 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
2125 } while (0)
2a1ee410 2126
e5b258a4 2127static void __attribute__((noinline))
4d9720f0 2128uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
2a1ee410
RH
2129{
2130 void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
ed168e45 2131 /* Set psp to the caller's stack pointer. */
a58b0342 2132 void *psp = __builtin_dwarf_cfa () - 16;
2a1ee410 2133 _Unwind_FrameState fs;
e8c89d29
JJ
2134 unsigned long rnat, tmp1, tmp2;
2135
2136 /* Flush the register stack to memory so that we can access it.
2137 Get rse nat collection for the last incomplete rbs chunk of
2138 registers at the same time. For this RSE needs to be turned
2139 into the mandatory only mode. */
2140 asm ("mov.m %1 = ar.rsc;;\n\t"
2141 "and %2 = 0x1c, %1;;\n\t"
2142 "mov.m ar.rsc = %2;;\n\t"
2143 "flushrs;;\n\t"
2144 "mov.m %0 = ar.rnat;;\n\t"
2145 "mov.m ar.rsc = %1\n\t"
2146 : "=r" (rnat), "=r" (tmp1), "=r" (tmp2));
2a1ee410
RH
2147
2148 memset (context, 0, sizeof (struct _Unwind_Context));
e8c89d29
JJ
2149 context->bsp = (unsigned long) bsp;
2150 /* Set context->regstk_top to lowest rbs address which will use
2151 context->rnat collection. */
2152 context->regstk_top = context->bsp & ~0x1ffULL;
2153 context->rnat = rnat;
2a1ee410
RH
2154 context->psp = (unsigned long) psp;
2155 context->rp = (unsigned long) rp;
4d9720f0 2156 asm ("mov %0 = sp" : "=r" (context->sp));
2a1ee410 2157 asm ("mov %0 = pr" : "=r" (context->pr));
4d9720f0 2158 context->pri_unat_loc = &context->initial_unat; /* ??? */
2a1ee410
RH
2159
2160 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
2161 abort ();
2162
2a1ee410
RH
2163 uw_update_context (context, &fs);
2164}
2165
112cdef5 2166/* Install (i.e. longjmp to) the contents of TARGET. */
2a1ee410
RH
2167
2168static void __attribute__((noreturn))
2169uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
2170 struct _Unwind_Context *target)
2171{
2172 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
2173 long i;
2174
2175 /* Copy integer register data from the target context to a
2176 temporary buffer. Do this so that we can frob AR.UNAT
2177 to get the NaT bits for these registers set properly. */
2178 for (i = 4; i <= 7; ++i)
2179 {
2180 char nat;
2181 void *t = target->ireg[i - 2].loc;
2182 if (t)
2183 {
2184 unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0);
2185 ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f);
2186 /* Set p6 - p9. */
2187 ireg_pr |= 4L << i;
2188 }
2189 }
2190
2191 /* The value in uc_bsp that we've computed is that for the
2192 target function. The value that we install below will be
2193 adjusted by the BR.RET instruction based on the contents
2194 of AR.PFS. So we must unadjust that here. */
4d9720f0
HB
2195 target->bsp = (unsigned long)
2196 ia64_rse_skip_regs ((unsigned long *)target->bsp,
2197 (*target->pfs_loc >> 7) & 0x7f);
2a1ee410 2198
e8c89d29
JJ
2199 if (target->bsp < target->regstk_top)
2200 target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp);
2201
2a1ee410
RH
2202 /* Provide assembly with the offsets into the _Unwind_Context. */
2203 asm volatile ("uc_rnat = %0"
2204 : : "i"(offsetof (struct _Unwind_Context, rnat)));
2205 asm volatile ("uc_bsp = %0"
2206 : : "i"(offsetof (struct _Unwind_Context, bsp)));
2207 asm volatile ("uc_psp = %0"
2208 : : "i"(offsetof (struct _Unwind_Context, psp)));
2209 asm volatile ("uc_rp = %0"
2210 : : "i"(offsetof (struct _Unwind_Context, rp)));
2211 asm volatile ("uc_pr = %0"
2212 : : "i"(offsetof (struct _Unwind_Context, pr)));
2213 asm volatile ("uc_gp = %0"
2214 : : "i"(offsetof (struct _Unwind_Context, gp)));
2215 asm volatile ("uc_pfs_loc = %0"
2216 : : "i"(offsetof (struct _Unwind_Context, pfs_loc)));
2217 asm volatile ("uc_unat_loc = %0"
2218 : : "i"(offsetof (struct _Unwind_Context, unat_loc)));
2219 asm volatile ("uc_lc_loc = %0"
2220 : : "i"(offsetof (struct _Unwind_Context, lc_loc)));
2221 asm volatile ("uc_fpsr_loc = %0"
2222 : : "i"(offsetof (struct _Unwind_Context, fpsr_loc)));
2223 asm volatile ("uc_eh_data = %0"
2224 : : "i"(offsetof (struct _Unwind_Context, eh_data)));
2225 asm volatile ("uc_br_loc = %0"
2226 : : "i"(offsetof (struct _Unwind_Context, br_loc)));
2227 asm volatile ("uc_fr_loc = %0"
2228 : : "i"(offsetof (struct _Unwind_Context, fr_loc)));
2229
2230 asm volatile (
2231 /* Load up call-saved non-window integer registers from ireg_buf. */
2232 "add r20 = 8, %1 \n\t"
2233 "mov ar.unat = %2 \n\t"
2234 "mov pr = %3, 0x3c0 \n\t"
2235 ";; \n\t"
2236 "(p6) ld8.fill r4 = [%1] \n\t"
2237 "(p7) ld8.fill r5 = [r20] \n\t"
3950dcdf 2238 "add r21 = uc_br_loc + 16, %0 \n\t"
2a1ee410
RH
2239 "adds %1 = 16, %1 \n\t"
2240 "adds r20 = 16, r20 \n\t"
2241 ";; \n\t"
2242 "(p8) ld8.fill r6 = [%1] \n\t"
2243 "(p9) ld8.fill r7 = [r20] \n\t"
3950dcdf 2244 "add r20 = uc_br_loc + 8, %0 \n\t"
2a1ee410
RH
2245 ";; \n\t"
2246 /* Load up call-saved branch registers. */
2247 "ld8 r22 = [r20], 16 \n\t"
2248 "ld8 r23 = [r21], 16 \n\t"
2249 ";; \n\t"
2250 "ld8 r24 = [r20], 16 \n\t"
3950dcdf 2251 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
2a1ee410 2252 ";; \n\t"
3950dcdf 2253 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
2a1ee410
RH
2254 "ld8 r27 = [r21], 24 \n\t"
2255 "cmp.ne p6, p0 = r0, r22 \n\t"
2256 ";; \n\t"
2257 "ld8 r28 = [r20], 8 \n\t"
2258 "(p6) ld8 r22 = [r22] \n\t"
2259 "cmp.ne p7, p0 = r0, r23 \n\t"
2260 ";; \n\t"
2261 "(p7) ld8 r23 = [r23] \n\t"
2262 "cmp.ne p8, p0 = r0, r24 \n\t"
2263 ";; \n\t"
2264 "(p8) ld8 r24 = [r24] \n\t"
2265 "(p6) mov b1 = r22 \n\t"
2266 "cmp.ne p9, p0 = r0, r25 \n\t"
2267 ";; \n\t"
2268 "(p9) ld8 r25 = [r25] \n\t"
2269 "(p7) mov b2 = r23 \n\t"
2270 "cmp.ne p6, p0 = r0, r26 \n\t"
2271 ";; \n\t"
2272 "(p6) ld8 r26 = [r26] \n\t"
2273 "(p8) mov b3 = r24 \n\t"
2274 "cmp.ne p7, p0 = r0, r27 \n\t"
2275 ";; \n\t"
2276 /* Load up call-saved fp registers. */
2277 "(p7) ldf.fill f2 = [r27] \n\t"
2278 "(p9) mov b4 = r25 \n\t"
2279 "cmp.ne p8, p0 = r0, r28 \n\t"
2280 ";; \n\t"
2281 "(p8) ldf.fill f3 = [r28] \n\t"
2282 "(p6) mov b5 = r26 \n\t"
2283 ";; \n\t"
2284 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
2285 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
2286 ";; \n\t"
2287 "ld8 r22 = [r20], 16 \n\t"
2288 "ld8 r23 = [r21], 16 \n\t"
2289 ";; \n\t"
2290 "ld8 r24 = [r20], 16 \n\t"
2291 "ld8 r25 = [r21] \n\t"
2292 "cmp.ne p6, p0 = r0, r29 \n\t"
2293 ";; \n\t"
2294 "ld8 r26 = [r20], 8 \n\t"
2295 "(p6) ldf.fill f4 = [r29] \n\t"
2296 "cmp.ne p7, p0 = r0, r30 \n\t"
2297 ";; \n\t"
2298 "ld8 r27 = [r20], 8 \n\t"
2299 "(p7) ldf.fill f5 = [r30] \n\t"
2300 "cmp.ne p6, p0 = r0, r22 \n\t"
2301 ";; \n\t"
2302 "ld8 r28 = [r20], 8 \n\t"
2303 "(p6) ldf.fill f16 = [r22] \n\t"
2304 "cmp.ne p7, p0 = r0, r23 \n\t"
2305 ";; \n\t"
2306 "ld8 r29 = [r20], 8 \n\t"
2307 "(p7) ldf.fill f17 = [r23] \n\t"
2308 "cmp.ne p6, p0 = r0, r24 \n\t"
2309 ";; \n\t"
2310 "ld8 r22 = [r20], 8 \n\t"
2311 "(p6) ldf.fill f18 = [r24] \n\t"
2312 "cmp.ne p7, p0 = r0, r25 \n\t"
2313 ";; \n\t"
2314 "ld8 r23 = [r20], 8 \n\t"
2315 "(p7) ldf.fill f19 = [r25] \n\t"
2316 "cmp.ne p6, p0 = r0, r26 \n\t"
2317 ";; \n\t"
2318 "ld8 r24 = [r20], 8 \n\t"
2319 "(p6) ldf.fill f20 = [r26] \n\t"
2320 "cmp.ne p7, p0 = r0, r27 \n\t"
2321 ";; \n\t"
2322 "ld8 r25 = [r20], 8 \n\t"
2323 "(p7) ldf.fill f21 = [r27] \n\t"
2324 "cmp.ne p6, p0 = r0, r28 \n\t"
2325 ";; \n\t"
2326 "ld8 r26 = [r20], 8 \n\t"
2327 "(p6) ldf.fill f22 = [r28] \n\t"
2328 "cmp.ne p7, p0 = r0, r29 \n\t"
2329 ";; \n\t"
43a07983
JW
2330 "ld8 r27 = [r20], 8 \n\t"
2331 ";; \n\t"
2a1ee410
RH
2332 "ld8 r28 = [r20], 8 \n\t"
2333 "(p7) ldf.fill f23 = [r29] \n\t"
2334 "cmp.ne p6, p0 = r0, r22 \n\t"
2335 ";; \n\t"
2336 "ld8 r29 = [r20], 8 \n\t"
2337 "(p6) ldf.fill f24 = [r22] \n\t"
2338 "cmp.ne p7, p0 = r0, r23 \n\t"
2339 ";; \n\t"
2340 "(p7) ldf.fill f25 = [r23] \n\t"
2341 "cmp.ne p6, p0 = r0, r24 \n\t"
2342 "cmp.ne p7, p0 = r0, r25 \n\t"
2343 ";; \n\t"
2344 "(p6) ldf.fill f26 = [r24] \n\t"
2345 "(p7) ldf.fill f27 = [r25] \n\t"
2346 "cmp.ne p6, p0 = r0, r26 \n\t"
2347 ";; \n\t"
2348 "(p6) ldf.fill f28 = [r26] \n\t"
2349 "cmp.ne p7, p0 = r0, r27 \n\t"
2350 "cmp.ne p6, p0 = r0, r28 \n\t"
2351 ";; \n\t"
2352 "(p7) ldf.fill f29 = [r27] \n\t"
2353 "(p6) ldf.fill f30 = [r28] \n\t"
2354 "cmp.ne p7, p0 = r0, r29 \n\t"
2355 ";; \n\t"
2356 "(p7) ldf.fill f31 = [r29] \n\t"
2357 "add r20 = uc_rnat, %0 \n\t"
2358 "add r21 = uc_bsp, %0 \n\t"
2359 ";; \n\t"
2360 /* Load the balance of the thread state from the context. */
2361 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
2362 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
2363 ";; \n\t"
2364 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
2365 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
2366 ";; \n\t"
2367 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2368 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
2369 ";; \n\t"
2370 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2371 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
2372 ";; \n\t"
2373 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2374 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2375 ";; \n\t"
2376 /* Load data for the exception handler. */
2377 "ld8 r15 = [r20], 16 \n\t"
2378 "ld8 r16 = [r21], 16 \n\t"
2379 ";; \n\t"
2380 "ld8 r17 = [r20] \n\t"
2381 "ld8 r18 = [r21] \n\t"
2382 ";; \n\t"
2383 /* Install the balance of the thread state loaded above. */
2384 "cmp.ne p6, p0 = r0, r25 \n\t"
2385 "cmp.ne p7, p0 = r0, r27 \n\t"
2386 ";; \n\t"
2387 "(p6) ld8 r25 = [r25] \n\t"
2388 "(p7) ld8 r27 = [r27] \n\t"
2389 ";; \n\t"
2390 "(p7) mov.m ar.unat = r27 \n\t"
2391 "(p6) mov.i ar.pfs = r25 \n\t"
2392 "cmp.ne p9, p0 = r0, r29 \n\t"
2393 ";; \n\t"
2394 "(p9) ld8 r29 = [r29] \n\t"
2395 "cmp.ne p6, p0 = r0, r30 \n\t"
2396 ";; \n\t"
2397 "(p6) ld8 r30 = [r30] \n\t"
2398 /* Don't clobber p6-p9, which are in use at present. */
2399 "mov pr = r28, ~0x3c0 \n\t"
2400 "(p9) mov.i ar.lc = r29 \n\t"
2401 ";; \n\t"
2402 "mov.m r25 = ar.rsc \n\t"
3950dcdf 2403 "(p6) mov.m ar.fpsr = r30 \n\t"
2a1ee410 2404 ";; \n\t"
e8c89d29 2405 "and r29 = 0x1c, r25 \n\t"
2a1ee410
RH
2406 "mov b0 = r26 \n\t"
2407 ";; \n\t"
e8c89d29 2408 "mov.m ar.rsc = r29 \n\t"
2a1ee410
RH
2409 ";; \n\t"
2410 /* This must be done before setting AR.BSPSTORE, otherwise
2411 AR.BSP will be initialized with a random displacement
2412 below the value we want, based on the current number of
2413 dirty stacked registers. */
2414 "loadrs \n\t"
2415 "invala \n\t"
2416 ";; \n\t"
2417 "mov.m ar.bspstore = r23 \n\t"
2418 ";; \n\t"
2a1ee410
RH
2419 "mov.m ar.rnat = r22 \n\t"
2420 ";; \n\t"
2421 "mov.m ar.rsc = r25 \n\t"
2422 "mov sp = r24 \n\t"
2423 "br.ret.sptk.few b0"
2424 : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr)
2425 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2426 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2427 "r30", "r31");
2428 /* NOTREACHED */
2429 while (1);
2430}
2431
2432static inline _Unwind_Ptr
2433uw_identify_context (struct _Unwind_Context *context)
2434{
2435 return _Unwind_GetIP (context);
2436}
2437
2438#include "unwind.inc"
443728bb
L
2439
2440#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
2441alias (_Unwind_Backtrace);
2442alias (_Unwind_DeleteException);
2443alias (_Unwind_FindEnclosingFunction);
443728bb
L
2444alias (_Unwind_ForcedUnwind);
2445alias (_Unwind_GetBSP);
2446alias (_Unwind_GetCFA);
2447alias (_Unwind_GetGR);
2448alias (_Unwind_GetIP);
2449alias (_Unwind_GetLanguageSpecificData);
2450alias (_Unwind_GetRegionStart);
2451alias (_Unwind_RaiseException);
2452alias (_Unwind_Resume);
2453alias (_Unwind_Resume_or_Rethrow);
2454alias (_Unwind_SetGR);
2455alias (_Unwind_SetIP);
2456#endif
2457
2a1ee410 2458#endif