OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [ia64/] [unwind-ia64.c] - Blame information for rev 282

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.