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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [ia64/] [unwind-ia64.c] - Blame information for rev 734

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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