* config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
[official-gcc.git] / gcc / config / ia64 / unwind-ia64.c
blob045abe5b7f60d2144a3b60ce85984ed95f341933
1 /* Subroutines needed for unwinding IA-64 standard format stack frame
2 info for exception handling.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Andrew MacLeod <amacleod@cygnus.com>
5 Andrew Haley <aph@cygnus.com>
6 David Mosberger-Tang <davidm@hpl.hp.com>
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
15 GNU CC is distributed in the hope that it will be useful,
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.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* As a special exception, if you link this library with other files,
26 some of which are compiled with GCC, to produce an executable,
27 this library does not by itself cause the resulting executable
28 to be covered by the GNU General Public License.
29 This exception does not however invalidate any other reasons why
30 the executable file might be covered by the GNU General Public License. */
33 #include "tconfig.h"
34 #include "tsystem.h"
35 #include "unwind.h"
36 #include "unwind-ia64.h"
38 #if !USING_SJLJ_EXCEPTIONS
39 #define UNW_VER(x) ((x) >> 48)
40 #define UNW_FLAG_MASK 0x0000ffff00000000
41 #define UNW_FLAG_OSMASK 0x0000f00000000000
42 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
43 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
44 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
46 enum unw_application_register
48 UNW_AR_BSP,
49 UNW_AR_BSPSTORE,
50 UNW_AR_PFS,
51 UNW_AR_RNAT,
52 UNW_AR_UNAT,
53 UNW_AR_LC,
54 UNW_AR_EC,
55 UNW_AR_FPSR,
56 UNW_AR_RSC,
57 UNW_AR_CCV
60 enum unw_register_index
62 /* Primary UNAT. */
63 UNW_REG_PRI_UNAT_GR,
64 UNW_REG_PRI_UNAT_MEM,
66 /* Memory Stack. */
67 UNW_REG_PSP, /* previous memory stack pointer */
69 /* Register Stack. */
70 UNW_REG_BSP, /* register stack pointer */
71 UNW_REG_BSPSTORE,
72 UNW_REG_PFS, /* previous function state */
73 UNW_REG_RNAT,
74 /* Return Pointer. */
75 UNW_REG_RP,
77 /* Special preserved registers. */
78 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
80 /* Non-stacked general registers. */
81 UNW_REG_R2,
82 UNW_REG_R4 = UNW_REG_R2 + 2,
83 UNW_REG_R7 = UNW_REG_R2 + 5,
84 UNW_REG_R31 = UNW_REG_R2 + 29,
86 /* Non-stacked floating point registers. */
87 UNW_REG_F2,
88 UNW_REG_F5 = UNW_REG_F2 + 3,
89 UNW_REG_F16 = UNW_REG_F2 + 14,
90 UNW_REG_F31 = UNW_REG_F2 + 29,
92 /* Branch registers. */
93 UNW_REG_B0, UNW_REG_B1,
94 UNW_REG_B5 = UNW_REG_B1 + 4,
96 UNW_NUM_REGS
99 enum unw_where
101 UNW_WHERE_NONE, /* register isn't saved at all */
102 UNW_WHERE_GR, /* register is saved in a general register */
103 UNW_WHERE_FR, /* register is saved in a floating-point register */
104 UNW_WHERE_BR, /* register is saved in a branch register */
105 UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
106 UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
108 /* At the end of each prologue these locations get resolved to
109 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
110 UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
111 UNW_WHERE_GR_SAVE /* register is saved in next general register */
114 #define UNW_WHEN_NEVER 0x7fffffff
116 struct unw_reg_info
118 unsigned long val; /* save location: register number or offset */
119 enum unw_where where; /* where the register gets saved */
120 int when; /* when the register gets saved */
123 typedef struct unw_state_record
125 unsigned int first_region : 1; /* is this the first region? */
126 unsigned int done : 1; /* are we done scanning descriptors? */
127 unsigned int any_spills : 1; /* got any register spills? */
128 unsigned int in_body : 1; /* are we inside a body? */
130 unsigned char *imask; /* imask of of spill_mask record or NULL */
131 unsigned long pr_val; /* predicate values */
132 unsigned long pr_mask; /* predicate mask */
133 long spill_offset; /* psp-relative offset for spill base */
134 int region_start;
135 int region_len;
136 int epilogue_start;
137 int epilogue_count;
138 int when_target;
140 unsigned char gr_save_loc; /* next general register to use for saving */
141 unsigned char return_link_reg; /* branch register for return link */
143 struct unw_reg_state {
144 struct unw_reg_state *next;
145 unsigned long label; /* label of this state record */
146 struct unw_reg_info reg[UNW_NUM_REGS];
147 } curr, *stack, *reg_state_list;
149 _Unwind_Personality_Fn personality;
151 } _Unwind_FrameState;
153 enum unw_nat_type
155 UNW_NAT_NONE, /* NaT not represented */
156 UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
157 UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
158 UNW_NAT_REGSTK /* NaT is in rnat */
161 struct unw_stack
163 unsigned long limit;
164 unsigned long top;
167 struct _Unwind_Context
169 /* Initial frame info. */
170 unsigned long rnat; /* rse nat collection */
171 unsigned long regstk_top; /* bsp for first frame */
173 /* Current frame info. */
174 unsigned long bsp; /* backing store pointer value
175 corresponding to psp. */
176 unsigned long sp; /* stack pointer value */
177 unsigned long psp; /* previous sp value */
178 unsigned long rp; /* return pointer */
179 unsigned long pr; /* predicate collection */
181 unsigned long region_start; /* start of unwind region */
182 unsigned long gp; /* global pointer value */
183 void *lsda; /* language specific data area */
185 /* Preserved state. */
186 unsigned long *bsp_loc; /* previous bsp save location */
187 unsigned long *bspstore_loc;
188 unsigned long *pfs_loc;
189 unsigned long *pri_unat_loc;
190 unsigned long *unat_loc;
191 unsigned long *lc_loc;
192 unsigned long *fpsr_loc;
194 unsigned long eh_data[4];
196 struct unw_ireg
198 unsigned long *loc;
199 struct unw_ireg_nat
201 enum unw_nat_type type : 3;
202 signed long off : 61; /* NaT word is at loc+nat.off */
203 } nat;
204 } ireg[32 - 2]; /* Indexed by <register number> - 2 */
206 unsigned long *br_loc[7];
207 void *fr_loc[32 - 2];
209 /* ??? We initially point pri_unat_loc here. The entire NAT bit
210 logic needs work. */
211 unsigned long initial_unat;
214 typedef unsigned long unw_word;
216 /* Implicit register save order. See section 11.4.2.3 Rules for Using
217 Unwind Descriptors, rule 3. */
219 static unsigned char const save_order[] =
221 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
222 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
226 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
228 /* Unwind decoder routines */
230 static void
231 push (struct unw_state_record *sr)
233 struct unw_reg_state *rs;
235 rs = malloc (sizeof (struct unw_reg_state));
236 memcpy (rs, &sr->curr, sizeof (*rs));
237 rs->next = sr->stack;
238 sr->stack = rs;
241 static void
242 pop (struct unw_state_record *sr)
244 struct unw_reg_state *rs;
246 rs = sr->stack;
247 sr->stack = rs->next;
248 free (rs);
251 static enum unw_register_index __attribute__((const))
252 decode_abreg (unsigned char abreg, int memory)
254 switch (abreg)
256 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
257 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
258 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
259 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
260 case 0x60: return UNW_REG_PR;
261 case 0x61: return UNW_REG_PSP;
262 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
263 case 0x63: return UNW_REG_RP;
264 case 0x64: return UNW_REG_BSP;
265 case 0x65: return UNW_REG_BSPSTORE;
266 case 0x66: return UNW_REG_RNAT;
267 case 0x67: return UNW_REG_UNAT;
268 case 0x68: return UNW_REG_FPSR;
269 case 0x69: return UNW_REG_PFS;
270 case 0x6a: return UNW_REG_LC;
271 default:
272 abort ();
276 static void
277 set_reg (struct unw_reg_info *reg, enum unw_where where,
278 int when, unsigned long val)
280 reg->val = val;
281 reg->where = where;
282 if (reg->when == UNW_WHEN_NEVER)
283 reg->when = when;
286 static void
287 alloc_spill_area (unsigned long *offp, unsigned long regsize,
288 struct unw_reg_info *lo, struct unw_reg_info *hi)
290 struct unw_reg_info *reg;
292 for (reg = hi; reg >= lo; --reg)
294 if (reg->where == UNW_WHERE_SPILL_HOME)
296 reg->where = UNW_WHERE_PSPREL;
297 reg->val = 0x10 - *offp;
298 *offp += regsize;
303 static inline void
304 spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim,
305 unw_word t)
307 struct unw_reg_info *reg;
309 for (reg = *regp; reg <= lim; ++reg)
311 if (reg->where == UNW_WHERE_SPILL_HOME)
313 reg->when = t;
314 *regp = reg + 1;
315 return;
318 /* Excess spill. */
319 abort ();
322 static void
323 finish_prologue (struct unw_state_record *sr)
325 struct unw_reg_info *reg;
326 unsigned long off;
327 int i;
329 /* First, resolve implicit register save locations
330 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
332 for (i = 0; i < (int) sizeof(save_order); ++i)
334 reg = sr->curr.reg + save_order[i];
335 if (reg->where == UNW_WHERE_GR_SAVE)
337 reg->where = UNW_WHERE_GR;
338 reg->val = sr->gr_save_loc++;
342 /* Next, compute when the fp, general, and branch registers get saved.
343 This must come before alloc_spill_area() because we need to know
344 which registers are spilled to their home locations. */
345 if (sr->imask)
347 static unsigned char const limit[3] = {
348 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
351 unsigned char kind, mask = 0, *cp = sr->imask;
352 int t;
353 struct unw_reg_info *(regs[3]);
355 regs[0] = sr->curr.reg + UNW_REG_F2;
356 regs[1] = sr->curr.reg + UNW_REG_R4;
357 regs[2] = sr->curr.reg + UNW_REG_B1;
359 for (t = 0; t < sr->region_len; ++t)
361 if ((t & 3) == 0)
362 mask = *cp++;
363 kind = (mask >> 2*(3-(t & 3))) & 3;
364 if (kind > 0)
365 spill_next_when(&regs[kind - 1], sr->curr.reg + limit[kind - 1],
366 sr->region_start + t);
370 /* Next, lay out the memory stack spill area. */
371 if (sr->any_spills)
373 off = sr->spill_offset;
374 alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2,
375 sr->curr.reg + UNW_REG_F31);
376 alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1,
377 sr->curr.reg + UNW_REG_B5);
378 alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4,
379 sr->curr.reg + UNW_REG_R7);
384 * Region header descriptors.
387 static void
388 desc_prologue (int body, unw_word rlen, unsigned char mask,
389 unsigned char grsave, struct unw_state_record *sr)
391 int i;
393 if (!(sr->in_body || sr->first_region))
394 finish_prologue(sr);
395 sr->first_region = 0;
397 /* Check if we're done. */
398 if (body && sr->when_target < sr->region_start + sr->region_len)
400 sr->done = 1;
401 return;
404 for (i = 0; i < sr->epilogue_count; ++i)
405 pop(sr);
406 sr->epilogue_count = 0;
407 sr->epilogue_start = UNW_WHEN_NEVER;
409 if (!body)
410 push(sr);
412 sr->region_start += sr->region_len;
413 sr->region_len = rlen;
414 sr->in_body = body;
416 if (!body)
418 for (i = 0; i < 4; ++i)
420 if (mask & 0x8)
421 set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR,
422 sr->region_start + sr->region_len - 1, grsave++);
423 mask <<= 1;
425 sr->gr_save_loc = grsave;
426 sr->any_spills = 0;
427 sr->imask = 0;
428 sr->spill_offset = 0x10; /* default to psp+16 */
433 * Prologue descriptors.
436 static inline void
437 desc_abi (unsigned char abi __attribute__((unused)),
438 unsigned char context __attribute__((unused)),
439 struct unw_state_record *sr __attribute__((unused)))
441 /* Anything to do? */
444 static inline void
445 desc_br_gr (unsigned char brmask, unsigned char gr,
446 struct unw_state_record *sr)
448 int i;
450 for (i = 0; i < 5; ++i)
452 if (brmask & 1)
453 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
454 sr->region_start + sr->region_len - 1, gr++);
455 brmask >>= 1;
459 static inline void
460 desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
462 int i;
464 for (i = 0; i < 5; ++i)
466 if (brmask & 1)
468 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
469 sr->region_start + sr->region_len - 1, 0);
470 sr->any_spills = 1;
472 brmask >>= 1;
476 static inline void
477 desc_frgr_mem (unsigned char grmask, unw_word frmask,
478 struct unw_state_record *sr)
480 int i;
482 for (i = 0; i < 4; ++i)
484 if ((grmask & 1) != 0)
486 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
487 sr->region_start + sr->region_len - 1, 0);
488 sr->any_spills = 1;
490 grmask >>= 1;
492 for (i = 0; i < 20; ++i)
494 if ((frmask & 1) != 0)
496 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
497 sr->region_start + sr->region_len - 1, 0);
498 sr->any_spills = 1;
500 frmask >>= 1;
504 static inline void
505 desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
507 int i;
509 for (i = 0; i < 4; ++i)
511 if ((frmask & 1) != 0)
513 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
514 sr->region_start + sr->region_len - 1, 0);
515 sr->any_spills = 1;
517 frmask >>= 1;
521 static inline void
522 desc_gr_gr (unsigned char grmask, unsigned char gr,
523 struct unw_state_record *sr)
525 int i;
527 for (i = 0; i < 4; ++i)
529 if ((grmask & 1) != 0)
530 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
531 sr->region_start + sr->region_len - 1, gr++);
532 grmask >>= 1;
536 static inline void
537 desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
539 int i;
541 for (i = 0; i < 4; ++i)
543 if ((grmask & 1) != 0)
545 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
546 sr->region_start + sr->region_len - 1, 0);
547 sr->any_spills = 1;
549 grmask >>= 1;
553 static inline void
554 desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
556 set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
557 sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size);
560 static inline void
561 desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
563 sr->curr.reg[UNW_REG_PSP].when
564 = sr->region_start + MIN ((int)t, sr->region_len - 1);
567 static inline void
568 desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
570 set_reg (sr->curr.reg + reg, UNW_WHERE_GR,
571 sr->region_start + sr->region_len - 1, dst);
574 static inline void
575 desc_reg_psprel (unsigned char reg, unw_word pspoff,
576 struct unw_state_record *sr)
578 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL,
579 sr->region_start + sr->region_len - 1,
580 0x10 - 4*pspoff);
583 static inline void
584 desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
586 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL,
587 sr->region_start + sr->region_len - 1,
588 4*spoff);
591 static inline void
592 desc_rp_br (unsigned char dst, struct unw_state_record *sr)
594 sr->return_link_reg = dst;
597 static inline void
598 desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
600 struct unw_reg_info *reg = sr->curr.reg + regnum;
602 if (reg->where == UNW_WHERE_NONE)
603 reg->where = UNW_WHERE_GR_SAVE;
604 reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
607 static inline void
608 desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
610 sr->spill_offset = 0x10 - 4*pspoff;
613 static inline unsigned char *
614 desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
616 sr->imask = imaskp;
617 return imaskp + (2*sr->region_len + 7)/8;
621 * Body descriptors.
623 static inline void
624 desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
626 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
627 sr->epilogue_count = ecount + 1;
630 static inline void
631 desc_copy_state (unw_word label, struct unw_state_record *sr)
633 struct unw_reg_state *rs;
635 for (rs = sr->reg_state_list; rs; rs = rs->next)
637 if (rs->label == label)
639 memcpy (&sr->curr, rs, sizeof(sr->curr));
640 return;
643 abort ();
646 static inline void
647 desc_label_state (unw_word label, struct unw_state_record *sr)
649 struct unw_reg_state *rs;
651 rs = malloc (sizeof (struct unw_reg_state));
652 memcpy (rs, &sr->curr, sizeof (*rs));
653 rs->label = label;
654 rs->next = sr->reg_state_list;
655 sr->reg_state_list = rs;
659 * General descriptors.
662 static inline int
663 desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
665 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1))
666 return 0;
667 if (qp > 0)
669 if ((sr->pr_val & (1UL << qp)) == 0)
670 return 0;
671 sr->pr_mask |= (1UL << qp);
673 return 1;
676 static inline void
677 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
678 struct unw_state_record *sr)
680 struct unw_reg_info *r;
682 if (! desc_is_active (qp, t, sr))
683 return;
685 r = sr->curr.reg + decode_abreg (abreg, 0);
686 r->where = UNW_WHERE_NONE;
687 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
688 r->val = 0;
691 static inline void
692 desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg,
693 unsigned char x, unsigned char ytreg,
694 struct unw_state_record *sr)
696 enum unw_where where = UNW_WHERE_GR;
697 struct unw_reg_info *r;
699 if (! desc_is_active (qp, t, sr))
700 return;
702 if (x)
703 where = UNW_WHERE_BR;
704 else if (ytreg & 0x80)
705 where = UNW_WHERE_FR;
707 r = sr->curr.reg + decode_abreg (abreg, 0);
708 r->where = where;
709 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
710 r->val = ytreg & 0x7f;
713 static inline void
714 desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg,
715 unw_word pspoff, struct unw_state_record *sr)
717 struct unw_reg_info *r;
719 if (! desc_is_active (qp, t, sr))
720 return;
722 r = sr->curr.reg + decode_abreg (abreg, 1);
723 r->where = UNW_WHERE_PSPREL;
724 r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
725 r->val = 0x10 - 4*pspoff;
728 static inline void
729 desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg,
730 unw_word spoff, struct unw_state_record *sr)
732 struct unw_reg_info *r;
734 if (! desc_is_active (qp, t, sr))
735 return;
737 r = sr->curr.reg + decode_abreg (abreg, 1);
738 r->where = UNW_WHERE_SPREL;
739 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
740 r->val = 4*spoff;
744 #define UNW_DEC_BAD_CODE(code) abort ();
746 /* Region headers. */
747 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
748 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
750 /* Prologue descriptors. */
751 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
752 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
753 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
754 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
755 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
756 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
757 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
758 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
759 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
760 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
761 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
762 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
763 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
764 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
765 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
766 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
767 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
768 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
769 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
770 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
771 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
773 /* Body descriptors. */
774 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
775 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
776 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
778 /* General unwind descriptors. */
779 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
780 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
781 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
782 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
783 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
784 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
785 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
786 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
790 * Generic IA-64 unwind info decoder.
792 * This file is used both by the Linux kernel and objdump. Please keep
793 * the copies of this file in sync.
795 * You need to customize the decoder by defining the following
796 * macros/constants before including this file:
798 * Types:
799 * unw_word Unsigned integer type with at least 64 bits
801 * Register names:
802 * UNW_REG_BSP
803 * UNW_REG_BSPSTORE
804 * UNW_REG_FPSR
805 * UNW_REG_LC
806 * UNW_REG_PFS
807 * UNW_REG_PR
808 * UNW_REG_RNAT
809 * UNW_REG_PSP
810 * UNW_REG_RP
811 * UNW_REG_UNAT
813 * Decoder action macros:
814 * UNW_DEC_BAD_CODE(code)
815 * UNW_DEC_ABI(fmt,abi,context,arg)
816 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
817 * UNW_DEC_BR_MEM(fmt,brmask,arg)
818 * UNW_DEC_COPY_STATE(fmt,label,arg)
819 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
820 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
821 * UNW_DEC_FR_MEM(fmt,frmask,arg)
822 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
823 * UNW_DEC_GR_MEM(fmt,grmask,arg)
824 * UNW_DEC_LABEL_STATE(fmt,label,arg)
825 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
826 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
827 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
828 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
829 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
830 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
831 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
832 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
833 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
834 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
835 * UNW_DEC_REG_REG(fmt,src,dst,arg)
836 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
837 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
838 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
839 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
840 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
841 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
842 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
843 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
844 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
845 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
846 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
847 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
850 static unw_word
851 unw_decode_uleb128 (unsigned char **dpp)
853 unsigned shift = 0;
854 unw_word byte, result = 0;
855 unsigned char *bp = *dpp;
857 while (1)
859 byte = *bp++;
860 result |= (byte & 0x7f) << shift;
861 if ((byte & 0x80) == 0)
862 break;
863 shift += 7;
865 *dpp = bp;
866 return result;
869 static unsigned char *
870 unw_decode_x1 (unsigned char *dp,
871 unsigned char code __attribute__((unused)),
872 void *arg)
874 unsigned char byte1, abreg;
875 unw_word t, off;
877 byte1 = *dp++;
878 t = unw_decode_uleb128 (&dp);
879 off = unw_decode_uleb128 (&dp);
880 abreg = (byte1 & 0x7f);
881 if (byte1 & 0x80)
882 UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
883 else
884 UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
885 return dp;
888 static unsigned char *
889 unw_decode_x2 (unsigned char *dp,
890 unsigned char code __attribute__((unused)),
891 void *arg)
893 unsigned char byte1, byte2, abreg, x, ytreg;
894 unw_word t;
896 byte1 = *dp++; byte2 = *dp++;
897 t = unw_decode_uleb128 (&dp);
898 abreg = (byte1 & 0x7f);
899 ytreg = byte2;
900 x = (byte1 >> 7) & 1;
901 if ((byte1 & 0x80) == 0 && ytreg == 0)
902 UNW_DEC_RESTORE(X2, t, abreg, arg);
903 else
904 UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
905 return dp;
908 static unsigned char *
909 unw_decode_x3 (unsigned char *dp,
910 unsigned char code __attribute__((unused)),
911 void *arg)
913 unsigned char byte1, byte2, abreg, qp;
914 unw_word t, off;
916 byte1 = *dp++; byte2 = *dp++;
917 t = unw_decode_uleb128 (&dp);
918 off = unw_decode_uleb128 (&dp);
920 qp = (byte1 & 0x3f);
921 abreg = (byte2 & 0x7f);
923 if (byte1 & 0x80)
924 UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
925 else
926 UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
927 return dp;
930 static unsigned char *
931 unw_decode_x4 (unsigned char *dp,
932 unsigned char code __attribute__((unused)),
933 void *arg)
935 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
936 unw_word t;
938 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
939 t = unw_decode_uleb128 (&dp);
941 qp = (byte1 & 0x3f);
942 abreg = (byte2 & 0x7f);
943 x = (byte2 >> 7) & 1;
944 ytreg = byte3;
946 if ((byte2 & 0x80) == 0 && byte3 == 0)
947 UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
948 else
949 UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
950 return dp;
953 static unsigned char *
954 unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
956 int body = (code & 0x20) != 0;
957 unw_word rlen;
959 rlen = (code & 0x1f);
960 UNW_DEC_PROLOGUE(R1, body, rlen, arg);
961 return dp;
964 static unsigned char *
965 unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
967 unsigned char byte1, mask, grsave;
968 unw_word rlen;
970 byte1 = *dp++;
972 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
973 grsave = (byte1 & 0x7f);
974 rlen = unw_decode_uleb128 (&dp);
975 UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
976 return dp;
979 static unsigned char *
980 unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
982 unw_word rlen;
984 rlen = unw_decode_uleb128 (&dp);
985 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
986 return dp;
989 static unsigned char *
990 unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
992 unsigned char brmask = (code & 0x1f);
994 UNW_DEC_BR_MEM(P1, brmask, arg);
995 return dp;
998 static unsigned char *
999 unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
1001 if ((code & 0x10) == 0)
1003 unsigned char byte1 = *dp++;
1005 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
1006 (byte1 & 0x7f), arg);
1008 else if ((code & 0x08) == 0)
1010 unsigned char byte1 = *dp++, r, dst;
1012 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1013 dst = (byte1 & 0x7f);
1014 switch (r)
1016 case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
1017 case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
1018 case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
1019 case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
1020 case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
1021 case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
1022 case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
1023 case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
1024 case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
1025 case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
1026 case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
1027 case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
1028 default: UNW_DEC_BAD_CODE(r); break;
1031 else if ((code & 0x7) == 0)
1032 UNW_DEC_SPILL_MASK(P4, dp, arg);
1033 else if ((code & 0x7) == 1)
1035 unw_word grmask, frmask, byte1, byte2, byte3;
1037 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1038 grmask = ((byte1 >> 4) & 0xf);
1039 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
1040 UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
1042 else
1043 UNW_DEC_BAD_CODE(code);
1044 return dp;
1047 static unsigned char *
1048 unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
1050 int gregs = (code & 0x10) != 0;
1051 unsigned char mask = (code & 0x0f);
1053 if (gregs)
1054 UNW_DEC_GR_MEM(P6, mask, arg);
1055 else
1056 UNW_DEC_FR_MEM(P6, mask, arg);
1057 return dp;
1060 static unsigned char *
1061 unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
1063 unsigned char r, byte1, byte2;
1064 unw_word t, size;
1066 if ((code & 0x10) == 0)
1068 r = (code & 0xf);
1069 t = unw_decode_uleb128 (&dp);
1070 switch (r)
1072 case 0:
1073 size = unw_decode_uleb128 (&dp);
1074 UNW_DEC_MEM_STACK_F(P7, t, size, arg);
1075 break;
1077 case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
1078 case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
1079 case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
1080 case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
1081 case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
1082 case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
1083 case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
1084 case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
1085 case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
1086 case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
1087 case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
1088 case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
1089 case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
1090 case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
1091 case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
1092 default: UNW_DEC_BAD_CODE(r); break;
1095 else
1097 switch (code & 0xf)
1099 case 0x0: /* p8 */
1101 r = *dp++;
1102 t = unw_decode_uleb128 (&dp);
1103 switch (r)
1105 case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
1106 case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
1107 case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
1108 case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
1109 case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
1110 case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
1111 case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
1112 case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
1113 case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
1114 case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
1115 case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1116 case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1117 case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
1118 case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
1119 case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
1120 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
1121 case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
1122 case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
1123 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
1124 default: UNW_DEC_BAD_CODE(r); break;
1127 break;
1129 case 0x1:
1130 byte1 = *dp++; byte2 = *dp++;
1131 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
1132 break;
1134 case 0xf: /* p10 */
1135 byte1 = *dp++; byte2 = *dp++;
1136 UNW_DEC_ABI(P10, byte1, byte2, arg);
1137 break;
1139 case 0x9:
1140 return unw_decode_x1 (dp, code, arg);
1142 case 0xa:
1143 return unw_decode_x2 (dp, code, arg);
1145 case 0xb:
1146 return unw_decode_x3 (dp, code, arg);
1148 case 0xc:
1149 return unw_decode_x4 (dp, code, arg);
1151 default:
1152 UNW_DEC_BAD_CODE(code);
1153 break;
1156 return dp;
1159 static unsigned char *
1160 unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
1162 unw_word label = (code & 0x1f);
1164 if ((code & 0x20) != 0)
1165 UNW_DEC_COPY_STATE(B1, label, arg);
1166 else
1167 UNW_DEC_LABEL_STATE(B1, label, arg);
1168 return dp;
1171 static unsigned char *
1172 unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
1174 unw_word t;
1176 t = unw_decode_uleb128 (&dp);
1177 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
1178 return dp;
1181 static unsigned char *
1182 unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
1184 unw_word t, ecount, label;
1186 if ((code & 0x10) == 0)
1188 t = unw_decode_uleb128 (&dp);
1189 ecount = unw_decode_uleb128 (&dp);
1190 UNW_DEC_EPILOGUE(B3, t, ecount, arg);
1192 else if ((code & 0x07) == 0)
1194 label = unw_decode_uleb128 (&dp);
1195 if ((code & 0x08) != 0)
1196 UNW_DEC_COPY_STATE(B4, label, arg);
1197 else
1198 UNW_DEC_LABEL_STATE(B4, label, arg);
1200 else
1201 switch (code & 0x7)
1203 case 1: return unw_decode_x1 (dp, code, arg);
1204 case 2: return unw_decode_x2 (dp, code, arg);
1205 case 3: return unw_decode_x3 (dp, code, arg);
1206 case 4: return unw_decode_x4 (dp, code, arg);
1207 default: UNW_DEC_BAD_CODE(code); break;
1209 return dp;
1212 typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
1214 static unw_decoder unw_decode_table[2][8] =
1216 /* prologue table: */
1218 unw_decode_r1, /* 0 */
1219 unw_decode_r1,
1220 unw_decode_r2,
1221 unw_decode_r3,
1222 unw_decode_p1, /* 4 */
1223 unw_decode_p2_p5,
1224 unw_decode_p6,
1225 unw_decode_p7_p10
1228 unw_decode_r1, /* 0 */
1229 unw_decode_r1,
1230 unw_decode_r2,
1231 unw_decode_r3,
1232 unw_decode_b1, /* 4 */
1233 unw_decode_b1,
1234 unw_decode_b2,
1235 unw_decode_b3_x4
1240 * Decode one descriptor and return address of next descriptor.
1242 static inline unsigned char *
1243 unw_decode (unsigned char *dp, int inside_body, void *arg)
1245 unw_decoder decoder;
1246 unsigned char code;
1248 code = *dp++;
1249 decoder = unw_decode_table[inside_body][code >> 5];
1250 dp = (*decoder) (dp, code, arg);
1251 return dp;
1255 /* RSE helper functions. */
1257 static inline unsigned long
1258 ia64_rse_slot_num (unsigned long *addr)
1260 return (((unsigned long) addr) >> 3) & 0x3f;
1263 /* Return TRUE if ADDR is the address of an RNAT slot. */
1264 static inline unsigned long
1265 ia64_rse_is_rnat_slot (unsigned long *addr)
1267 return ia64_rse_slot_num (addr) == 0x3f;
1270 /* Returns the address of the RNAT slot that covers the slot at
1271 address SLOT_ADDR. */
1272 static inline unsigned long *
1273 ia64_rse_rnat_addr (unsigned long *slot_addr)
1275 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
1278 /* Calcuate the number of registers in the dirty partition starting at
1279 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1280 divided by eight because the 64th slot is used to store ar.rnat. */
1281 static inline unsigned long
1282 ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
1284 unsigned long slots = (bsp - bspstore);
1286 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40;
1289 /* The inverse of the above: given bspstore and the number of
1290 registers, calculate ar.bsp. */
1291 static inline unsigned long *
1292 ia64_rse_skip_regs (unsigned long *addr, long num_regs)
1294 long delta = ia64_rse_slot_num (addr) + num_regs;
1296 if (num_regs < 0)
1297 delta -= 0x3e;
1298 return addr + num_regs + delta/0x3f;
1302 /* Unwind accessors. */
1304 static void
1305 unw_access_gr (struct _Unwind_Context *info, int regnum,
1306 unsigned long *val, char *nat, int write)
1308 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat;
1309 struct unw_ireg *ireg;
1311 if ((unsigned) regnum - 1 >= 127)
1312 abort ();
1314 if (regnum < 1)
1316 nat_addr = addr = &dummy_nat;
1317 dummy_nat = 0;
1319 else if (regnum < 32)
1321 /* Access a non-stacked register. */
1322 ireg = &info->ireg[regnum - 2];
1323 addr = ireg->loc;
1324 if (addr)
1326 nat_addr = addr + ireg->nat.off;
1327 switch (ireg->nat.type)
1329 case UNW_NAT_VAL:
1330 /* Simulate getf.sig/setf.sig. */
1331 if (write)
1333 if (*nat)
1335 /* Write NaTVal and be done with it. */
1336 addr[0] = 0;
1337 addr[1] = 0x1fffe;
1338 return;
1340 addr[1] = 0x1003e;
1342 else if (addr[0] == 0 && addr[1] == 0x1ffe)
1344 /* Return NaT and be done with it. */
1345 *val = 0;
1346 *nat = 1;
1347 return;
1349 /* FALLTHRU */
1351 case UNW_NAT_NONE:
1352 dummy_nat = 0;
1353 nat_addr = &dummy_nat;
1354 break;
1356 case UNW_NAT_MEMSTK:
1357 nat_mask = 1UL << ((long) addr & 0x1f8)/8;
1358 break;
1360 case UNW_NAT_REGSTK:
1361 nat_addr = ia64_rse_rnat_addr (addr);
1362 if ((unsigned long) nat_addr >= info->regstk_top)
1363 nat_addr = &info->rnat;
1364 nat_mask = 1UL << ia64_rse_slot_num (addr);
1365 break;
1369 else
1371 /* Access a stacked register. */
1372 addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
1373 nat_addr = ia64_rse_rnat_addr (addr);
1374 if ((unsigned long) nat_addr >= info->regstk_top)
1375 nat_addr = &info->rnat;
1376 nat_mask = 1UL << ia64_rse_slot_num (addr);
1379 if (write)
1381 *addr = *val;
1382 if (*nat)
1383 *nat_addr |= nat_mask;
1384 else
1385 *nat_addr &= ~nat_mask;
1387 else
1389 *val = *addr;
1390 *nat = (*nat_addr & nat_mask) != 0;
1394 /* Get the value of register REG as saved in CONTEXT. */
1396 _Unwind_Word
1397 _Unwind_GetGR (struct _Unwind_Context *context, int index)
1399 _Unwind_Word ret;
1400 char nat;
1402 if (index == 1)
1403 return context->gp;
1404 else if (index >= 15 && index <= 18)
1405 return context->eh_data[index - 15];
1406 else
1407 unw_access_gr (context, index, &ret, &nat, 0);
1409 return ret;
1412 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1414 void
1415 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
1417 char nat = 0;
1419 if (index == 1)
1420 context->gp = val;
1421 else if (index >= 15 && index <= 18)
1422 context->eh_data[index - 15] = val;
1423 else
1424 unw_access_gr (context, index, &val, &nat, 1);
1427 /* Retrieve the return address for CONTEXT. */
1429 inline _Unwind_Ptr
1430 _Unwind_GetIP (struct _Unwind_Context *context)
1432 return context->rp;
1435 /* Overwrite the return address for CONTEXT with VAL. */
1437 inline void
1438 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1440 context->rp = val;
1443 void *
1444 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1446 return context->lsda;
1449 _Unwind_Ptr
1450 _Unwind_GetRegionStart (struct _Unwind_Context *context)
1452 return context->region_start;
1456 static _Unwind_Reason_Code
1457 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1459 struct unw_table_entry *ent;
1460 unsigned long *unw, header, length;
1461 unsigned char *insn, *insn_end;
1462 unsigned long segment_base;
1464 memset (fs, 0, sizeof (*fs));
1465 context->lsda = 0;
1467 ent = _Unwind_FindTableEntry ((void *) context->rp,
1468 &segment_base, &context->gp);
1469 if (ent == NULL)
1471 /* Couldn't find unwind info for this function. Try an
1472 os-specific fallback mechanism. This will necessarily
1473 not provide a personality routine or LSDA. */
1474 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1475 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1477 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1478 handlers, and which keeps the return value in B0 does not need
1479 an unwind table entry.
1481 This can only happen in the frame after unwinding through a signal
1482 handler. Avoid infinite looping by requiring that B0 != RP. */
1483 if (context->br_loc[0] && *context->br_loc[0] != context->rp)
1485 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1486 fs->curr.reg[UNW_REG_RP].when = -1;
1487 fs->curr.reg[UNW_REG_RP].val = 0;
1488 goto success;
1491 return _URC_END_OF_STACK;
1492 success:
1493 return _URC_NO_REASON;
1494 #else
1495 return _URC_END_OF_STACK;
1496 #endif
1499 context->region_start = ent->start_offset + segment_base;
1500 fs->when_target = (context->rp - context->region_start) / 16 * 3;
1502 unw = (unsigned long *) (ent->info_offset + segment_base);
1503 header = *unw;
1504 length = UNW_LENGTH (header);
1506 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */
1508 if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))
1510 fs->personality =
1511 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1512 context->lsda = unw + length + 2;
1515 insn = (unsigned char *) (unw + 1);
1516 insn_end = (unsigned char *) (unw + 1 + length);
1517 while (!fs->done && insn < insn_end)
1518 insn = unw_decode (insn, fs->in_body, fs);
1520 /* If we're in the epilogue, sp has been restored and all values
1521 on the memory stack below psp also have been restored. */
1522 if (fs->when_target > fs->epilogue_start)
1524 struct unw_reg_info *r;
1526 fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1527 fs->curr.reg[UNW_REG_PSP].val = 0;
1528 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1529 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1530 || r->where == UNW_WHERE_SPREL)
1531 r->where = UNW_WHERE_NONE;
1534 /* If RP did't get saved, generate entry for the return link register. */
1535 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target)
1537 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1538 fs->curr.reg[UNW_REG_RP].when = -1;
1539 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg;
1542 return _URC_NO_REASON;
1545 static void
1546 uw_update_reg_address (struct _Unwind_Context *context,
1547 _Unwind_FrameState *fs,
1548 enum unw_register_index regno)
1550 struct unw_reg_info *r = fs->curr.reg + regno;
1551 void *addr;
1552 unsigned long rval;
1554 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1555 return;
1557 rval = r->val;
1558 switch (r->where)
1560 case UNW_WHERE_GR:
1561 if (rval >= 32)
1562 addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32);
1563 else if (rval >= 2)
1564 addr = context->ireg[rval - 2].loc;
1565 else
1566 abort ();
1567 break;
1569 case UNW_WHERE_FR:
1570 if (rval >= 2 && rval < 32)
1571 addr = context->fr_loc[rval - 2];
1572 else
1573 abort ();
1574 break;
1576 case UNW_WHERE_BR:
1577 /* Note that while RVAL can only be 1-5 from normal descriptors,
1578 we can want to look at B0 due to having manually unwound a
1579 signal frame. */
1580 if (rval >= 0 && rval <= 5)
1581 addr = context->br_loc[rval];
1582 else
1583 abort ();
1584 break;
1586 case UNW_WHERE_SPREL:
1587 addr = (void *)(context->sp + rval);
1588 break;
1590 case UNW_WHERE_PSPREL:
1591 addr = (void *)(context->psp + rval);
1592 break;
1594 default:
1595 abort ();
1598 switch (regno)
1600 case UNW_REG_R2 ... UNW_REG_R31:
1601 context->ireg[regno - UNW_REG_R2].loc = addr;
1602 switch (r->where)
1604 case UNW_WHERE_GR:
1605 if (rval >= 32)
1607 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1608 context->ireg[regno - UNW_REG_R2].nat.off
1609 = context->pri_unat_loc - (unsigned long *) addr;
1611 else if (rval >= 2)
1613 context->ireg[regno - UNW_REG_R2].nat
1614 = context->ireg[rval - 2].nat;
1616 else
1617 abort ();
1618 break;
1620 case UNW_WHERE_FR:
1621 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL;
1622 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1623 break;
1625 case UNW_WHERE_BR:
1626 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1627 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1628 break;
1630 case UNW_WHERE_PSPREL:
1631 case UNW_WHERE_SPREL:
1632 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1633 context->ireg[regno - UNW_REG_R2].nat.off
1634 = context->pri_unat_loc - (unsigned long *) addr;
1635 break;
1637 default:
1638 abort ();
1640 break;
1642 case UNW_REG_F2 ... UNW_REG_F31:
1643 context->fr_loc[regno - UNW_REG_F2] = addr;
1644 break;
1646 case UNW_REG_B1 ... UNW_REG_B5:
1647 context->br_loc[regno - UNW_REG_B0] = addr;
1648 break;
1650 case UNW_REG_BSP:
1651 context->bsp_loc = addr;
1652 break;
1653 case UNW_REG_BSPSTORE:
1654 context->bspstore_loc = addr;
1655 break;
1656 case UNW_REG_PFS:
1657 context->pfs_loc = addr;
1658 break;
1659 case UNW_REG_RP:
1660 context->rp = *(unsigned long *)addr;
1661 break;
1662 case UNW_REG_UNAT:
1663 context->unat_loc = addr;
1664 break;
1665 case UNW_REG_PR:
1666 context->pr = *(unsigned long *) addr;
1667 break;
1668 case UNW_REG_LC:
1669 context->lc_loc = addr;
1670 break;
1671 case UNW_REG_FPSR:
1672 context->fpsr_loc = addr;
1673 break;
1675 case UNW_REG_PSP:
1676 context->psp = *(unsigned long *)addr;
1677 break;
1679 case UNW_REG_RNAT:
1680 case UNW_NUM_REGS:
1681 abort ();
1685 static void
1686 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1688 long i;
1690 context->sp = context->psp;
1692 /* First, set PSP. Subsequent instructions may depend on this value. */
1693 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
1695 if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
1696 context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val;
1697 else
1698 uw_update_reg_address (context, fs, UNW_REG_PSP);
1701 /* Determine the location of the primary UNaT. */
1703 int i;
1704 if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
1705 i = UNW_REG_PRI_UNAT_MEM;
1706 else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when)
1707 i = UNW_REG_PRI_UNAT_GR;
1708 else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when
1709 > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
1710 i = UNW_REG_PRI_UNAT_MEM;
1711 else
1712 i = UNW_REG_PRI_UNAT_GR;
1713 uw_update_reg_address (context, fs, i);
1716 /* Compute the addresses of all registers saved in this frame. */
1717 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
1718 uw_update_reg_address (context, fs, i);
1720 /* Unwind BSP for the local registers allocated this frame. */
1721 /* ??? What to do with stored BSP or BSPSTORE registers. */
1722 if (fs->when_target > fs->curr.reg[UNW_REG_PFS].when)
1724 unsigned long pfs = *context->pfs_loc;
1725 unsigned long sol = (pfs >> 7) & 0x7f;
1726 context->bsp = (unsigned long)
1727 ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol);
1731 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1732 level will be the return address and the CFA. Note that CFA = SP+16. */
1734 #define uw_init_context(CONTEXT) \
1735 do { \
1736 /* ??? There is a whole lot o code in uw_install_context that \
1737 tries to avoid spilling the entire machine state here. We \
1738 should try to make that work again. */ \
1739 __builtin_unwind_init(); \
1740 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
1741 } while (0)
1743 static void
1744 uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
1746 void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
1747 /* Set psp to the caller's stack pointer. */
1748 void *psp = __builtin_dwarf_cfa () - 16;
1749 _Unwind_FrameState fs;
1751 /* Flush the register stack to memory so that we can access it. */
1752 __builtin_ia64_flushrs ();
1754 memset (context, 0, sizeof (struct _Unwind_Context));
1755 context->bsp = context->regstk_top = (unsigned long) bsp;
1756 context->psp = (unsigned long) psp;
1757 context->rp = (unsigned long) rp;
1758 asm ("mov %0 = sp" : "=r" (context->sp));
1759 asm ("mov %0 = pr" : "=r" (context->pr));
1760 context->pri_unat_loc = &context->initial_unat; /* ??? */
1761 /* ??? Get rnat. Don't we have to turn off the rse for that? */
1763 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1764 abort ();
1766 uw_update_context (context, &fs);
1769 /* Install (ie longjmp to) the contents of TARGET. */
1771 static void __attribute__((noreturn))
1772 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
1773 struct _Unwind_Context *target)
1775 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
1776 long i;
1778 /* Copy integer register data from the target context to a
1779 temporary buffer. Do this so that we can frob AR.UNAT
1780 to get the NaT bits for these registers set properly. */
1781 for (i = 4; i <= 7; ++i)
1783 char nat;
1784 void *t = target->ireg[i - 2].loc;
1785 if (t)
1787 unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0);
1788 ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f);
1789 /* Set p6 - p9. */
1790 ireg_pr |= 4L << i;
1794 /* The value in uc_bsp that we've computed is that for the
1795 target function. The value that we install below will be
1796 adjusted by the BR.RET instruction based on the contents
1797 of AR.PFS. So we must unadjust that here. */
1798 target->bsp = (unsigned long)
1799 ia64_rse_skip_regs ((unsigned long *)target->bsp,
1800 (*target->pfs_loc >> 7) & 0x7f);
1802 /* Provide assembly with the offsets into the _Unwind_Context. */
1803 asm volatile ("uc_rnat = %0"
1804 : : "i"(offsetof (struct _Unwind_Context, rnat)));
1805 asm volatile ("uc_bsp = %0"
1806 : : "i"(offsetof (struct _Unwind_Context, bsp)));
1807 asm volatile ("uc_psp = %0"
1808 : : "i"(offsetof (struct _Unwind_Context, psp)));
1809 asm volatile ("uc_rp = %0"
1810 : : "i"(offsetof (struct _Unwind_Context, rp)));
1811 asm volatile ("uc_pr = %0"
1812 : : "i"(offsetof (struct _Unwind_Context, pr)));
1813 asm volatile ("uc_gp = %0"
1814 : : "i"(offsetof (struct _Unwind_Context, gp)));
1815 asm volatile ("uc_pfs_loc = %0"
1816 : : "i"(offsetof (struct _Unwind_Context, pfs_loc)));
1817 asm volatile ("uc_unat_loc = %0"
1818 : : "i"(offsetof (struct _Unwind_Context, unat_loc)));
1819 asm volatile ("uc_lc_loc = %0"
1820 : : "i"(offsetof (struct _Unwind_Context, lc_loc)));
1821 asm volatile ("uc_fpsr_loc = %0"
1822 : : "i"(offsetof (struct _Unwind_Context, fpsr_loc)));
1823 asm volatile ("uc_eh_data = %0"
1824 : : "i"(offsetof (struct _Unwind_Context, eh_data)));
1825 asm volatile ("uc_br_loc = %0"
1826 : : "i"(offsetof (struct _Unwind_Context, br_loc)));
1827 asm volatile ("uc_fr_loc = %0"
1828 : : "i"(offsetof (struct _Unwind_Context, fr_loc)));
1830 asm volatile (
1831 /* Load up call-saved non-window integer registers from ireg_buf. */
1832 "add r20 = 8, %1 \n\t"
1833 "mov ar.unat = %2 \n\t"
1834 "mov pr = %3, 0x3c0 \n\t"
1835 ";; \n\t"
1836 "(p6) ld8.fill r4 = [%1] \n\t"
1837 "(p7) ld8.fill r5 = [r20] \n\t"
1838 "add r21 = uc_br_loc + 8, %0 \n\t"
1839 "adds %1 = 16, %1 \n\t"
1840 "adds r20 = 16, r20 \n\t"
1841 ";; \n\t"
1842 "(p8) ld8.fill r6 = [%1] \n\t"
1843 "(p9) ld8.fill r7 = [r20] \n\t"
1844 "add r20 = uc_br_loc, %0 \n\t"
1845 ";; \n\t"
1846 /* Load up call-saved branch registers. */
1847 "ld8 r22 = [r20], 16 \n\t"
1848 "ld8 r23 = [r21], 16 \n\t"
1849 ";; \n\t"
1850 "ld8 r24 = [r20], 16 \n\t"
1851 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 24)\n\t"
1852 ";; \n\t"
1853 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 32)\n\t"
1854 "ld8 r27 = [r21], 24 \n\t"
1855 "cmp.ne p6, p0 = r0, r22 \n\t"
1856 ";; \n\t"
1857 "ld8 r28 = [r20], 8 \n\t"
1858 "(p6) ld8 r22 = [r22] \n\t"
1859 "cmp.ne p7, p0 = r0, r23 \n\t"
1860 ";; \n\t"
1861 "(p7) ld8 r23 = [r23] \n\t"
1862 "cmp.ne p8, p0 = r0, r24 \n\t"
1863 ";; \n\t"
1864 "(p8) ld8 r24 = [r24] \n\t"
1865 "(p6) mov b1 = r22 \n\t"
1866 "cmp.ne p9, p0 = r0, r25 \n\t"
1867 ";; \n\t"
1868 "(p9) ld8 r25 = [r25] \n\t"
1869 "(p7) mov b2 = r23 \n\t"
1870 "cmp.ne p6, p0 = r0, r26 \n\t"
1871 ";; \n\t"
1872 "(p6) ld8 r26 = [r26] \n\t"
1873 "(p8) mov b3 = r24 \n\t"
1874 "cmp.ne p7, p0 = r0, r27 \n\t"
1875 ";; \n\t"
1876 /* Load up call-saved fp registers. */
1877 "(p7) ldf.fill f2 = [r27] \n\t"
1878 "(p9) mov b4 = r25 \n\t"
1879 "cmp.ne p8, p0 = r0, r28 \n\t"
1880 ";; \n\t"
1881 "(p8) ldf.fill f3 = [r28] \n\t"
1882 "(p6) mov b5 = r26 \n\t"
1883 ";; \n\t"
1884 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
1885 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
1886 ";; \n\t"
1887 "ld8 r22 = [r20], 16 \n\t"
1888 "ld8 r23 = [r21], 16 \n\t"
1889 ";; \n\t"
1890 "ld8 r24 = [r20], 16 \n\t"
1891 "ld8 r25 = [r21] \n\t"
1892 "cmp.ne p6, p0 = r0, r29 \n\t"
1893 ";; \n\t"
1894 "ld8 r26 = [r20], 8 \n\t"
1895 "(p6) ldf.fill f4 = [r29] \n\t"
1896 "cmp.ne p7, p0 = r0, r30 \n\t"
1897 ";; \n\t"
1898 "ld8 r27 = [r20], 8 \n\t"
1899 "(p7) ldf.fill f5 = [r30] \n\t"
1900 "cmp.ne p6, p0 = r0, r22 \n\t"
1901 ";; \n\t"
1902 "ld8 r28 = [r20], 8 \n\t"
1903 "(p6) ldf.fill f16 = [r22] \n\t"
1904 "cmp.ne p7, p0 = r0, r23 \n\t"
1905 ";; \n\t"
1906 "ld8 r29 = [r20], 8 \n\t"
1907 "(p7) ldf.fill f17 = [r23] \n\t"
1908 "cmp.ne p6, p0 = r0, r24 \n\t"
1909 ";; \n\t"
1910 "ld8 r22 = [r20], 8 \n\t"
1911 "(p6) ldf.fill f18 = [r24] \n\t"
1912 "cmp.ne p7, p0 = r0, r25 \n\t"
1913 ";; \n\t"
1914 "ld8 r23 = [r20], 8 \n\t"
1915 "(p7) ldf.fill f19 = [r25] \n\t"
1916 "cmp.ne p6, p0 = r0, r26 \n\t"
1917 ";; \n\t"
1918 "ld8 r24 = [r20], 8 \n\t"
1919 "(p6) ldf.fill f20 = [r26] \n\t"
1920 "cmp.ne p7, p0 = r0, r27 \n\t"
1921 ";; \n\t"
1922 "ld8 r25 = [r20], 8 \n\t"
1923 "(p7) ldf.fill f21 = [r27] \n\t"
1924 "cmp.ne p6, p0 = r0, r28 \n\t"
1925 ";; \n\t"
1926 "ld8 r26 = [r20], 8 \n\t"
1927 "(p6) ldf.fill f22 = [r28] \n\t"
1928 "cmp.ne p7, p0 = r0, r29 \n\t"
1929 ";; \n\t"
1930 "ld8 r28 = [r20], 8 \n\t"
1931 "(p7) ldf.fill f23 = [r29] \n\t"
1932 "cmp.ne p6, p0 = r0, r22 \n\t"
1933 ";; \n\t"
1934 "ld8 r29 = [r20], 8 \n\t"
1935 "(p6) ldf.fill f24 = [r22] \n\t"
1936 "cmp.ne p7, p0 = r0, r23 \n\t"
1937 ";; \n\t"
1938 "(p7) ldf.fill f25 = [r23] \n\t"
1939 "cmp.ne p6, p0 = r0, r24 \n\t"
1940 "cmp.ne p7, p0 = r0, r25 \n\t"
1941 ";; \n\t"
1942 "(p6) ldf.fill f26 = [r24] \n\t"
1943 "(p7) ldf.fill f27 = [r25] \n\t"
1944 "cmp.ne p6, p0 = r0, r26 \n\t"
1945 ";; \n\t"
1946 "(p6) ldf.fill f28 = [r26] \n\t"
1947 "cmp.ne p7, p0 = r0, r27 \n\t"
1948 "cmp.ne p6, p0 = r0, r28 \n\t"
1949 ";; \n\t"
1950 "(p7) ldf.fill f29 = [r27] \n\t"
1951 "(p6) ldf.fill f30 = [r28] \n\t"
1952 "cmp.ne p7, p0 = r0, r29 \n\t"
1953 ";; \n\t"
1954 "(p7) ldf.fill f31 = [r29] \n\t"
1955 "add r20 = uc_rnat, %0 \n\t"
1956 "add r21 = uc_bsp, %0 \n\t"
1957 ";; \n\t"
1958 /* Load the balance of the thread state from the context. */
1959 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
1960 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
1961 ";; \n\t"
1962 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
1963 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
1964 ";; \n\t"
1965 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
1966 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
1967 ";; \n\t"
1968 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
1969 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
1970 ";; \n\t"
1971 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
1972 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
1973 ";; \n\t"
1974 /* Load data for the exception handler. */
1975 "ld8 r15 = [r20], 16 \n\t"
1976 "ld8 r16 = [r21], 16 \n\t"
1977 ";; \n\t"
1978 "ld8 r17 = [r20] \n\t"
1979 "ld8 r18 = [r21] \n\t"
1980 ";; \n\t"
1981 /* Install the balance of the thread state loaded above. */
1982 "cmp.ne p6, p0 = r0, r25 \n\t"
1983 "cmp.ne p7, p0 = r0, r27 \n\t"
1984 ";; \n\t"
1985 "(p6) ld8 r25 = [r25] \n\t"
1986 "(p7) ld8 r27 = [r27] \n\t"
1987 ";; \n\t"
1988 "(p7) mov.m ar.unat = r27 \n\t"
1989 "(p6) mov.i ar.pfs = r25 \n\t"
1990 "cmp.ne p9, p0 = r0, r29 \n\t"
1991 ";; \n\t"
1992 "(p9) ld8 r29 = [r29] \n\t"
1993 "cmp.ne p6, p0 = r0, r30 \n\t"
1994 ";; \n\t"
1995 "(p6) ld8 r30 = [r30] \n\t"
1996 /* Don't clobber p6-p9, which are in use at present. */
1997 "mov pr = r28, ~0x3c0 \n\t"
1998 "(p9) mov.i ar.lc = r29 \n\t"
1999 ";; \n\t"
2000 "mov.m r25 = ar.rsc \n\t"
2001 "(p6) mov.i ar.fpsr = r30 \n\t"
2002 ";; \n\t"
2003 "and r25 = 0x1c, r25 \n\t"
2004 "mov b0 = r26 \n\t"
2005 ";; \n\t"
2006 "mov.m ar.rsc = r25 \n\t"
2007 ";; \n\t"
2008 /* This must be done before setting AR.BSPSTORE, otherwise
2009 AR.BSP will be initialized with a random displacement
2010 below the value we want, based on the current number of
2011 dirty stacked registers. */
2012 "loadrs \n\t"
2013 "invala \n\t"
2014 ";; \n\t"
2015 "mov.m ar.bspstore = r23 \n\t"
2016 ";; \n\t"
2017 "or r25 = 0x3, r25 \n\t"
2018 "mov.m ar.rnat = r22 \n\t"
2019 ";; \n\t"
2020 "mov.m ar.rsc = r25 \n\t"
2021 "mov sp = r24 \n\t"
2022 "br.ret.sptk.few b0"
2023 : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr)
2024 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2025 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2026 "r30", "r31");
2027 /* NOTREACHED */
2028 while (1);
2031 static inline _Unwind_Ptr
2032 uw_identify_context (struct _Unwind_Context *context)
2034 return _Unwind_GetIP (context);
2037 #include "unwind.inc"
2038 #endif