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