]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/ia64/unwind-ia64.c
Makefile.in (cs-tconfig.h): Don't depend on $(CONFIG_H) or except.h.
[thirdparty/gcc.git] / gcc / config / ia64 / unwind-ia64.c
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>
7
8 This file is part of GNU CC.
9
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.
14
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.
19
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. */
24
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. */
31
32
33 #include "tconfig.h"
34 #include "tsystem.h"
35 #include "unwind.h"
36 #include "unwind-ia64.h"
37
38 #ifndef __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)
45
46 enum unw_application_register
47 {
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
58 };
59
60 enum unw_register_index
61 {
62 /* Primary UNAT. */
63 UNW_REG_PRI_UNAT_GR,
64 UNW_REG_PRI_UNAT_MEM,
65
66 /* Memory Stack. */
67 UNW_REG_PSP, /* previous memory stack pointer */
68
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,
76
77 /* Special preserved registers. */
78 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
79
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,
85
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,
91
92 /* Branch registers. */
93 UNW_REG_B0, UNW_REG_B1,
94 UNW_REG_B5 = UNW_REG_B1 + 4,
95
96 UNW_NUM_REGS
97 };
98
99 enum unw_where
100 {
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) */
107
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 */
112 };
113
114 #define UNW_WHEN_NEVER 0x7fffffff
115
116 struct unw_reg_info
117 {
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 */
121 };
122
123 typedef struct unw_state_record
124 {
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? */
129
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;
139
140 unsigned char gr_save_loc; /* next general register to use for saving */
141 unsigned char return_link_reg; /* branch register for return link */
142
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;
148
149 _Unwind_Personality_Fn personality;
150
151 } _Unwind_FrameState;
152
153 enum unw_nat_type
154 {
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 */
159 };
160
161 struct unw_stack
162 {
163 unsigned long limit;
164 unsigned long top;
165 };
166
167 struct _Unwind_Context
168 {
169 /* Initial frame info. */
170 unsigned long rnat; /* rse nat collection */
171 unsigned long regstk_top; /* bsp for first frame */
172
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 */
180
181 unsigned long region_start; /* start of unwind region */
182 unsigned long gp; /* global pointer value */
183 void *lsda; /* language specific data area */
184
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;
193
194 unsigned long eh_data[4];
195
196 struct unw_ireg
197 {
198 unsigned long *loc;
199 struct unw_ireg_nat
200 {
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 */
205
206 unsigned long *br_loc[7];
207 void *fr_loc[32 - 2];
208
209 /* ??? We initially point pri_unat_loc here. The entire NAT bit
210 logic needs work. */
211 unsigned long initial_unat;
212 };
213
214 typedef unsigned long unw_word;
215
216 /* Implicit register save order. See section 11.4.2.3 Rules for Using
217 Unwind Descriptors, rule 3. */
218
219 static unsigned char const save_order[] =
220 {
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
223 };
224
225 \f
226 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
227
228 /* Unwind decoder routines */
229
230 static void
231 push (struct unw_state_record *sr)
232 {
233 struct unw_reg_state *rs;
234
235 rs = malloc (sizeof (struct unw_reg_state));
236 memcpy (rs, &sr->curr, sizeof (*rs));
237 rs->next = sr->stack;
238 sr->stack = rs;
239 }
240
241 static void
242 pop (struct unw_state_record *sr)
243 {
244 struct unw_reg_state *rs;
245
246 rs = sr->stack;
247 sr->stack = rs->next;
248 free (rs);
249 }
250
251 static enum unw_register_index __attribute__((const))
252 decode_abreg (unsigned char abreg, int memory)
253 {
254 switch (abreg)
255 {
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 ();
273 }
274 }
275
276 static void
277 set_reg (struct unw_reg_info *reg, enum unw_where where,
278 int when, unsigned long val)
279 {
280 reg->val = val;
281 reg->where = where;
282 if (reg->when == UNW_WHEN_NEVER)
283 reg->when = when;
284 }
285
286 static void
287 alloc_spill_area (unsigned long *offp, unsigned long regsize,
288 struct unw_reg_info *lo, struct unw_reg_info *hi)
289 {
290 struct unw_reg_info *reg;
291
292 for (reg = hi; reg >= lo; --reg)
293 {
294 if (reg->where == UNW_WHERE_SPILL_HOME)
295 {
296 reg->where = UNW_WHERE_PSPREL;
297 reg->val = 0x10 - *offp;
298 *offp += regsize;
299 }
300 }
301 }
302
303 static inline void
304 spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim,
305 unw_word t)
306 {
307 struct unw_reg_info *reg;
308
309 for (reg = *regp; reg <= lim; ++reg)
310 {
311 if (reg->where == UNW_WHERE_SPILL_HOME)
312 {
313 reg->when = t;
314 *regp = reg + 1;
315 return;
316 }
317 }
318 /* Excess spill. */
319 abort ();
320 }
321
322 static void
323 finish_prologue (struct unw_state_record *sr)
324 {
325 struct unw_reg_info *reg;
326 unsigned long off;
327 int i;
328
329 /* First, resolve implicit register save locations
330 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
331
332 for (i = 0; i < (int) sizeof(save_order); ++i)
333 {
334 reg = sr->curr.reg + save_order[i];
335 if (reg->where == UNW_WHERE_GR_SAVE)
336 {
337 reg->where = UNW_WHERE_GR;
338 reg->val = sr->gr_save_loc++;
339 }
340 }
341
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)
346 {
347 static unsigned char const limit[3] = {
348 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
349 };
350
351 unsigned char kind, mask = 0, *cp = sr->imask;
352 int t;
353 struct unw_reg_info *(regs[3]);
354
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;
358
359 for (t = 0; t < sr->region_len; ++t)
360 {
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);
367 }
368 }
369
370 /* Next, lay out the memory stack spill area. */
371 if (sr->any_spills)
372 {
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);
380 }
381 }
382
383 /*
384 * Region header descriptors.
385 */
386
387 static void
388 desc_prologue (int body, unw_word rlen, unsigned char mask,
389 unsigned char grsave, struct unw_state_record *sr)
390 {
391 int i;
392
393 if (!(sr->in_body || sr->first_region))
394 finish_prologue(sr);
395 sr->first_region = 0;
396
397 /* Check if we're done. */
398 if (body && sr->when_target < sr->region_start + sr->region_len)
399 {
400 sr->done = 1;
401 return;
402 }
403
404 for (i = 0; i < sr->epilogue_count; ++i)
405 pop(sr);
406 sr->epilogue_count = 0;
407 sr->epilogue_start = UNW_WHEN_NEVER;
408
409 if (!body)
410 push(sr);
411
412 sr->region_start += sr->region_len;
413 sr->region_len = rlen;
414 sr->in_body = body;
415
416 if (!body)
417 {
418 for (i = 0; i < 4; ++i)
419 {
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;
424 }
425 sr->gr_save_loc = grsave;
426 sr->any_spills = 0;
427 sr->imask = 0;
428 sr->spill_offset = 0x10; /* default to psp+16 */
429 }
430 }
431
432 /*
433 * Prologue descriptors.
434 */
435
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)))
440 {
441 /* Anything to do? */
442 }
443
444 static inline void
445 desc_br_gr (unsigned char brmask, unsigned char gr,
446 struct unw_state_record *sr)
447 {
448 int i;
449
450 for (i = 0; i < 5; ++i)
451 {
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;
456 }
457 }
458
459 static inline void
460 desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
461 {
462 int i;
463
464 for (i = 0; i < 5; ++i)
465 {
466 if (brmask & 1)
467 {
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;
471 }
472 brmask >>= 1;
473 }
474 }
475
476 static inline void
477 desc_frgr_mem (unsigned char grmask, unw_word frmask,
478 struct unw_state_record *sr)
479 {
480 int i;
481
482 for (i = 0; i < 4; ++i)
483 {
484 if ((grmask & 1) != 0)
485 {
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;
489 }
490 grmask >>= 1;
491 }
492 for (i = 0; i < 20; ++i)
493 {
494 if ((frmask & 1) != 0)
495 {
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;
499 }
500 frmask >>= 1;
501 }
502 }
503
504 static inline void
505 desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
506 {
507 int i;
508
509 for (i = 0; i < 4; ++i)
510 {
511 if ((frmask & 1) != 0)
512 {
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;
516 }
517 frmask >>= 1;
518 }
519 }
520
521 static inline void
522 desc_gr_gr (unsigned char grmask, unsigned char gr,
523 struct unw_state_record *sr)
524 {
525 int i;
526
527 for (i = 0; i < 4; ++i)
528 {
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;
533 }
534 }
535
536 static inline void
537 desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
538 {
539 int i;
540
541 for (i = 0; i < 4; ++i)
542 {
543 if ((grmask & 1) != 0)
544 {
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;
548 }
549 grmask >>= 1;
550 }
551 }
552
553 static inline void
554 desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
555 {
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);
558 }
559
560 static inline void
561 desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
562 {
563 sr->curr.reg[UNW_REG_PSP].when
564 = sr->region_start + MIN ((int)t, sr->region_len - 1);
565 }
566
567 static inline void
568 desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
569 {
570 set_reg (sr->curr.reg + reg, UNW_WHERE_GR,
571 sr->region_start + sr->region_len - 1, dst);
572 }
573
574 static inline void
575 desc_reg_psprel (unsigned char reg, unw_word pspoff,
576 struct unw_state_record *sr)
577 {
578 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL,
579 sr->region_start + sr->region_len - 1,
580 0x10 - 4*pspoff);
581 }
582
583 static inline void
584 desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
585 {
586 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL,
587 sr->region_start + sr->region_len - 1,
588 4*spoff);
589 }
590
591 static inline void
592 desc_rp_br (unsigned char dst, struct unw_state_record *sr)
593 {
594 sr->return_link_reg = dst;
595 }
596
597 static inline void
598 desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
599 {
600 struct unw_reg_info *reg = sr->curr.reg + regnum;
601
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);
605 }
606
607 static inline void
608 desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
609 {
610 sr->spill_offset = 0x10 - 4*pspoff;
611 }
612
613 static inline unsigned char *
614 desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
615 {
616 sr->imask = imaskp;
617 return imaskp + (2*sr->region_len + 7)/8;
618 }
619
620 /*
621 * Body descriptors.
622 */
623 static inline void
624 desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
625 {
626 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
627 sr->epilogue_count = ecount + 1;
628 }
629
630 static inline void
631 desc_copy_state (unw_word label, struct unw_state_record *sr)
632 {
633 struct unw_reg_state *rs;
634
635 for (rs = sr->reg_state_list; rs; rs = rs->next)
636 {
637 if (rs->label == label)
638 {
639 memcpy (&sr->curr, rs, sizeof(sr->curr));
640 return;
641 }
642 }
643 abort ();
644 }
645
646 static inline void
647 desc_label_state (unw_word label, struct unw_state_record *sr)
648 {
649 struct unw_reg_state *rs;
650
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;
656 }
657
658 /*
659 * General descriptors.
660 */
661
662 static inline int
663 desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
664 {
665 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1))
666 return 0;
667 if (qp > 0)
668 {
669 if ((sr->pr_val & (1UL << qp)) == 0)
670 return 0;
671 sr->pr_mask |= (1UL << qp);
672 }
673 return 1;
674 }
675
676 static inline void
677 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
678 struct unw_state_record *sr)
679 {
680 struct unw_reg_info *r;
681
682 if (! desc_is_active (qp, t, sr))
683 return;
684
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;
689 }
690
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)
695 {
696 enum unw_where where = UNW_WHERE_GR;
697 struct unw_reg_info *r;
698
699 if (! desc_is_active (qp, t, sr))
700 return;
701
702 if (x)
703 where = UNW_WHERE_BR;
704 else if (ytreg & 0x80)
705 where = UNW_WHERE_FR;
706
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;
711 }
712
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)
716 {
717 struct unw_reg_info *r;
718
719 if (! desc_is_active (qp, t, sr))
720 return;
721
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;
726 }
727
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)
731 {
732 struct unw_reg_info *r;
733
734 if (! desc_is_active (qp, t, sr))
735 return;
736
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;
741 }
742
743 \f
744 #define UNW_DEC_BAD_CODE(code) abort ();
745
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)
749
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))
772
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)
777
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)
787
788 \f
789 /*
790 * Generic IA-64 unwind info decoder.
791 *
792 * This file is used both by the Linux kernel and objdump. Please keep
793 * the copies of this file in sync.
794 *
795 * You need to customize the decoder by defining the following
796 * macros/constants before including this file:
797 *
798 * Types:
799 * unw_word Unsigned integer type with at least 64 bits
800 *
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
812 *
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)
848 */
849
850 static unw_word
851 unw_decode_uleb128 (unsigned char **dpp)
852 {
853 unsigned shift = 0;
854 unw_word byte, result = 0;
855 unsigned char *bp = *dpp;
856
857 while (1)
858 {
859 byte = *bp++;
860 result |= (byte & 0x7f) << shift;
861 if ((byte & 0x80) == 0)
862 break;
863 shift += 7;
864 }
865 *dpp = bp;
866 return result;
867 }
868
869 static unsigned char *
870 unw_decode_x1 (unsigned char *dp,
871 unsigned char code __attribute__((unused)),
872 void *arg)
873 {
874 unsigned char byte1, abreg;
875 unw_word t, off;
876
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;
886 }
887
888 static unsigned char *
889 unw_decode_x2 (unsigned char *dp,
890 unsigned char code __attribute__((unused)),
891 void *arg)
892 {
893 unsigned char byte1, byte2, abreg, x, ytreg;
894 unw_word t;
895
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;
906 }
907
908 static unsigned char *
909 unw_decode_x3 (unsigned char *dp,
910 unsigned char code __attribute__((unused)),
911 void *arg)
912 {
913 unsigned char byte1, byte2, abreg, qp;
914 unw_word t, off;
915
916 byte1 = *dp++; byte2 = *dp++;
917 t = unw_decode_uleb128 (&dp);
918 off = unw_decode_uleb128 (&dp);
919
920 qp = (byte1 & 0x3f);
921 abreg = (byte2 & 0x7f);
922
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;
928 }
929
930 static unsigned char *
931 unw_decode_x4 (unsigned char *dp,
932 unsigned char code __attribute__((unused)),
933 void *arg)
934 {
935 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
936 unw_word t;
937
938 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
939 t = unw_decode_uleb128 (&dp);
940
941 qp = (byte1 & 0x3f);
942 abreg = (byte2 & 0x7f);
943 x = (byte2 >> 7) & 1;
944 ytreg = byte3;
945
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;
951 }
952
953 static unsigned char *
954 unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
955 {
956 int body = (code & 0x20) != 0;
957 unw_word rlen;
958
959 rlen = (code & 0x1f);
960 UNW_DEC_PROLOGUE(R1, body, rlen, arg);
961 return dp;
962 }
963
964 static unsigned char *
965 unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
966 {
967 unsigned char byte1, mask, grsave;
968 unw_word rlen;
969
970 byte1 = *dp++;
971
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;
977 }
978
979 static unsigned char *
980 unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
981 {
982 unw_word rlen;
983
984 rlen = unw_decode_uleb128 (&dp);
985 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
986 return dp;
987 }
988
989 static unsigned char *
990 unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
991 {
992 unsigned char brmask = (code & 0x1f);
993
994 UNW_DEC_BR_MEM(P1, brmask, arg);
995 return dp;
996 }
997
998 static unsigned char *
999 unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
1000 {
1001 if ((code & 0x10) == 0)
1002 {
1003 unsigned char byte1 = *dp++;
1004
1005 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
1006 (byte1 & 0x7f), arg);
1007 }
1008 else if ((code & 0x08) == 0)
1009 {
1010 unsigned char byte1 = *dp++, r, dst;
1011
1012 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1013 dst = (byte1 & 0x7f);
1014 switch (r)
1015 {
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;
1029 }
1030 }
1031 else if ((code & 0x7) == 0)
1032 UNW_DEC_SPILL_MASK(P4, dp, arg);
1033 else if ((code & 0x7) == 1)
1034 {
1035 unw_word grmask, frmask, byte1, byte2, byte3;
1036
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);
1041 }
1042 else
1043 UNW_DEC_BAD_CODE(code);
1044 return dp;
1045 }
1046
1047 static unsigned char *
1048 unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
1049 {
1050 int gregs = (code & 0x10) != 0;
1051 unsigned char mask = (code & 0x0f);
1052
1053 if (gregs)
1054 UNW_DEC_GR_MEM(P6, mask, arg);
1055 else
1056 UNW_DEC_FR_MEM(P6, mask, arg);
1057 return dp;
1058 }
1059
1060 static unsigned char *
1061 unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
1062 {
1063 unsigned char r, byte1, byte2;
1064 unw_word t, size;
1065
1066 if ((code & 0x10) == 0)
1067 {
1068 r = (code & 0xf);
1069 t = unw_decode_uleb128 (&dp);
1070 switch (r)
1071 {
1072 case 0:
1073 size = unw_decode_uleb128 (&dp);
1074 UNW_DEC_MEM_STACK_F(P7, t, size, arg);
1075 break;
1076
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;
1093 }
1094 }
1095 else
1096 {
1097 switch (code & 0xf)
1098 {
1099 case 0x0: /* p8 */
1100 {
1101 r = *dp++;
1102 t = unw_decode_uleb128 (&dp);
1103 switch (r)
1104 {
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;
1125 }
1126 }
1127 break;
1128
1129 case 0x1:
1130 byte1 = *dp++; byte2 = *dp++;
1131 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
1132 break;
1133
1134 case 0xf: /* p10 */
1135 byte1 = *dp++; byte2 = *dp++;
1136 UNW_DEC_ABI(P10, byte1, byte2, arg);
1137 break;
1138
1139 case 0x9:
1140 return unw_decode_x1 (dp, code, arg);
1141
1142 case 0xa:
1143 return unw_decode_x2 (dp, code, arg);
1144
1145 case 0xb:
1146 return unw_decode_x3 (dp, code, arg);
1147
1148 case 0xc:
1149 return unw_decode_x4 (dp, code, arg);
1150
1151 default:
1152 UNW_DEC_BAD_CODE(code);
1153 break;
1154 }
1155 }
1156 return dp;
1157 }
1158
1159 static unsigned char *
1160 unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
1161 {
1162 unw_word label = (code & 0x1f);
1163
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;
1169 }
1170
1171 static unsigned char *
1172 unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
1173 {
1174 unw_word t;
1175
1176 t = unw_decode_uleb128 (&dp);
1177 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
1178 return dp;
1179 }
1180
1181 static unsigned char *
1182 unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
1183 {
1184 unw_word t, ecount, label;
1185
1186 if ((code & 0x10) == 0)
1187 {
1188 t = unw_decode_uleb128 (&dp);
1189 ecount = unw_decode_uleb128 (&dp);
1190 UNW_DEC_EPILOGUE(B3, t, ecount, arg);
1191 }
1192 else if ((code & 0x07) == 0)
1193 {
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);
1199 }
1200 else
1201 switch (code & 0x7)
1202 {
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;
1208 }
1209 return dp;
1210 }
1211
1212 typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
1213
1214 static unw_decoder unw_decode_table[2][8] =
1215 {
1216 /* prologue table: */
1217 {
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
1226 },
1227 {
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
1236 }
1237 };
1238
1239 /*
1240 * Decode one descriptor and return address of next descriptor.
1241 */
1242 static inline unsigned char *
1243 unw_decode (unsigned char *dp, int inside_body, void *arg)
1244 {
1245 unw_decoder decoder;
1246 unsigned char code;
1247
1248 code = *dp++;
1249 decoder = unw_decode_table[inside_body][code >> 5];
1250 dp = (*decoder) (dp, code, arg);
1251 return dp;
1252 }
1253
1254 \f
1255 /* RSE helper functions. */
1256
1257 static inline unsigned long
1258 ia64_rse_slot_num (unsigned long *addr)
1259 {
1260 return (((unsigned long) addr) >> 3) & 0x3f;
1261 }
1262
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)
1266 {
1267 return ia64_rse_slot_num (addr) == 0x3f;
1268 }
1269
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)
1274 {
1275 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
1276 }
1277
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)
1283 {
1284 unsigned long slots = (bsp - bspstore);
1285
1286 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40;
1287 }
1288
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)
1293 {
1294 long delta = ia64_rse_slot_num (addr) + num_regs;
1295
1296 if (num_regs < 0)
1297 delta -= 0x3e;
1298 return addr + num_regs + delta/0x3f;
1299 }
1300
1301 \f
1302 /* Unwind accessors. */
1303
1304 static void
1305 unw_access_gr (struct _Unwind_Context *info, int regnum,
1306 unsigned long *val, char *nat, int write)
1307 {
1308 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat;
1309 struct unw_ireg *ireg;
1310
1311 if ((unsigned) regnum - 1 >= 127)
1312 abort ();
1313
1314 if (regnum < 1)
1315 {
1316 nat_addr = addr = &dummy_nat;
1317 dummy_nat = 0;
1318 }
1319 else if (regnum < 32)
1320 {
1321 /* Access a non-stacked register. */
1322 ireg = &info->ireg[regnum - 2];
1323 addr = ireg->loc;
1324 if (addr)
1325 {
1326 nat_addr = addr + ireg->nat.off;
1327 switch (ireg->nat.type)
1328 {
1329 case UNW_NAT_VAL:
1330 /* Simulate getf.sig/setf.sig. */
1331 if (write)
1332 {
1333 if (*nat)
1334 {
1335 /* Write NaTVal and be done with it. */
1336 addr[0] = 0;
1337 addr[1] = 0x1fffe;
1338 return;
1339 }
1340 addr[1] = 0x1003e;
1341 }
1342 else if (addr[0] == 0 && addr[1] == 0x1ffe)
1343 {
1344 /* Return NaT and be done with it. */
1345 *val = 0;
1346 *nat = 1;
1347 return;
1348 }
1349 /* FALLTHRU */
1350
1351 case UNW_NAT_NONE:
1352 dummy_nat = 0;
1353 nat_addr = &dummy_nat;
1354 break;
1355
1356 case UNW_NAT_MEMSTK:
1357 nat_mask = 1UL << ((long) addr & 0x1f8)/8;
1358 break;
1359
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;
1366 }
1367 }
1368 }
1369 else
1370 {
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);
1377 }
1378
1379 if (write)
1380 {
1381 *addr = *val;
1382 if (*nat)
1383 *nat_addr |= nat_mask;
1384 else
1385 *nat_addr &= ~nat_mask;
1386 }
1387 else
1388 {
1389 *val = *addr;
1390 *nat = (*nat_addr & nat_mask) != 0;
1391 }
1392 }
1393 \f
1394 /* Get the value of register REG as saved in CONTEXT. */
1395
1396 _Unwind_Word
1397 _Unwind_GetGR (struct _Unwind_Context *context, int index)
1398 {
1399 _Unwind_Word ret;
1400 char nat;
1401
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);
1408
1409 return ret;
1410 }
1411
1412 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1413
1414 void
1415 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
1416 {
1417 char nat = 0;
1418
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);
1425 }
1426
1427 /* Retrieve the return address for CONTEXT. */
1428
1429 inline _Unwind_Ptr
1430 _Unwind_GetIP (struct _Unwind_Context *context)
1431 {
1432 return context->rp;
1433 }
1434
1435 /* Overwrite the return address for CONTEXT with VAL. */
1436
1437 inline void
1438 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1439 {
1440 context->rp = val;
1441 }
1442
1443 void *
1444 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1445 {
1446 return context->lsda;
1447 }
1448
1449 _Unwind_Ptr
1450 _Unwind_GetRegionStart (struct _Unwind_Context *context)
1451 {
1452 return context->region_start;
1453 }
1454
1455 \f
1456 static _Unwind_Reason_Code
1457 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1458 {
1459 struct unw_table_entry *ent;
1460 unsigned long *unw, header, length;
1461 unsigned char *insn, *insn_end;
1462 unsigned long segment_base;
1463
1464 memset (fs, 0, sizeof (*fs));
1465 context->lsda = 0;
1466
1467 ent = _Unwind_FindTableEntry ((void *) context->rp,
1468 &segment_base, &context->gp);
1469 if (ent == NULL)
1470 {
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);
1476
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.
1480
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)
1484 {
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;
1489 }
1490
1491 return _URC_END_OF_STACK;
1492 success:
1493 return _URC_NO_REASON;
1494 #else
1495 return _URC_END_OF_STACK;
1496 #endif
1497 }
1498
1499 context->region_start = ent->start_offset + segment_base;
1500 fs->when_target = (context->rp - context->region_start) / 16 * 3;
1501
1502 unw = (unsigned long *) (ent->info_offset + segment_base);
1503 header = *unw;
1504 length = UNW_LENGTH (header);
1505
1506 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */
1507
1508 if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))
1509 {
1510 fs->personality =
1511 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1512 context->lsda = unw + length + 2;
1513 }
1514
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);
1519
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)
1523 {
1524 struct unw_reg_info *r;
1525
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;
1532 }
1533
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)
1536 {
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;
1540 }
1541
1542 return _URC_NO_REASON;
1543 }
1544
1545 static void
1546 uw_update_reg_address (struct _Unwind_Context *context,
1547 _Unwind_FrameState *fs,
1548 enum unw_register_index regno)
1549 {
1550 struct unw_reg_info *r = fs->curr.reg + regno;
1551 void *addr;
1552 unsigned long rval;
1553
1554 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1555 return;
1556
1557 rval = r->val;
1558 switch (r->where)
1559 {
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;
1568
1569 case UNW_WHERE_FR:
1570 if (rval >= 2 && rval < 32)
1571 addr = context->fr_loc[rval - 2];
1572 else
1573 abort ();
1574 break;
1575
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;
1585
1586 case UNW_WHERE_SPREL:
1587 addr = (void *)(context->sp + rval);
1588 break;
1589
1590 case UNW_WHERE_PSPREL:
1591 addr = (void *)(context->psp + rval);
1592 break;
1593
1594 default:
1595 abort ();
1596 }
1597
1598 switch (regno)
1599 {
1600 case UNW_REG_R2 ... UNW_REG_R31:
1601 context->ireg[regno - UNW_REG_R2].loc = addr;
1602 switch (r->where)
1603 {
1604 case UNW_WHERE_GR:
1605 if (rval >= 32)
1606 {
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;
1610 }
1611 else if (rval >= 2)
1612 {
1613 context->ireg[regno - UNW_REG_R2].nat
1614 = context->ireg[rval - 2].nat;
1615 }
1616 else
1617 abort ();
1618 break;
1619
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;
1624
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;
1629
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;
1636
1637 default:
1638 abort ();
1639 }
1640 break;
1641
1642 case UNW_REG_F2 ... UNW_REG_F31:
1643 context->fr_loc[regno - UNW_REG_F2] = addr;
1644 break;
1645
1646 case UNW_REG_B1 ... UNW_REG_B5:
1647 context->br_loc[regno - UNW_REG_B0] = addr;
1648 break;
1649
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;
1674
1675 case UNW_REG_PSP:
1676 context->psp = *(unsigned long *)addr;
1677 break;
1678
1679 case UNW_REG_RNAT:
1680 case UNW_NUM_REGS:
1681 abort ();
1682 }
1683 }
1684
1685 static void
1686 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1687 {
1688 long i;
1689
1690 context->sp = context->psp;
1691
1692 /* First, set PSP. Subsequent instructions may depend on this value. */
1693 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
1694 {
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);
1699 }
1700
1701 /* Determine the location of the primary UNaT. */
1702 {
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);
1714 }
1715
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);
1719
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)
1723 {
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);
1728 }
1729 }
1730
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. */
1733
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)
1742
1743 static void
1744 uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
1745 {
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;
1750
1751 /* Flush the register stack to memory so that we can access it. */
1752 __builtin_ia64_flushrs ();
1753
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? */
1762
1763 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1764 abort ();
1765
1766 uw_update_context (context, &fs);
1767 }
1768
1769 /* Install (ie longjmp to) the contents of TARGET. */
1770
1771 static void __attribute__((noreturn))
1772 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
1773 struct _Unwind_Context *target)
1774 {
1775 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
1776 long i;
1777
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)
1782 {
1783 char nat;
1784 void *t = target->ireg[i - 2].loc;
1785 if (t)
1786 {
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;
1791 }
1792 }
1793
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);
1801
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)));
1829
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);
2029 }
2030
2031 static inline _Unwind_Ptr
2032 uw_identify_context (struct _Unwind_Context *context)
2033 {
2034 return _Unwind_GetIP (context);
2035 }
2036
2037 #include "unwind.inc"
2038 #endif