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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [ia64/] [unwind-ia64.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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