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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [ia64/] [unwind-ia64.c] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* 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
/* Overwrite the return address for CONTEXT with VAL.  */
1708
 
1709
inline void
1710
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1711
{
1712
  context->rp = val;
1713
}
1714
 
1715
void *
1716
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1717
{
1718
  return context->lsda;
1719
}
1720
 
1721
_Unwind_Ptr
1722
_Unwind_GetRegionStart (struct _Unwind_Context *context)
1723
{
1724
  return context->region_start;
1725
}
1726
 
1727
void *
1728
_Unwind_FindEnclosingFunction (void *pc)
1729
{
1730
  struct unw_table_entry *ent;
1731
  unsigned long segment_base, gp;
1732
 
1733
  ent = _Unwind_FindTableEntry (pc, &segment_base, &gp);
1734
  if (ent == NULL)
1735
    return NULL;
1736
  else
1737
    return (void *)(segment_base + ent->start_offset);
1738
}
1739
 
1740
/* Get the value of the CFA as saved in CONTEXT.  In GCC/Dwarf2 parlance,
1741
   the CFA is the value of the stack pointer on entry; In IA-64 unwind
1742
   parlance, this is the PSP.  */
1743
 
1744
_Unwind_Word
1745
_Unwind_GetCFA (struct _Unwind_Context *context)
1746
{
1747
  return (_Unwind_Ptr) context->psp;
1748
}
1749
 
1750
/* Get the value of the Backing Store Pointer as saved in CONTEXT.  */
1751
 
1752
_Unwind_Word
1753
_Unwind_GetBSP (struct _Unwind_Context *context)
1754
{
1755
  return (_Unwind_Ptr) context->bsp;
1756
}
1757
 
1758
#ifdef MD_UNWIND_SUPPORT
1759
#include MD_UNWIND_SUPPORT
1760
#endif
1761
 
1762
static _Unwind_Reason_Code
1763
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1764
{
1765
  struct unw_table_entry *ent;
1766
  unsigned long *unw, header, length;
1767
  unsigned char *insn, *insn_end;
1768
  unsigned long segment_base;
1769
  struct unw_reg_info *r;
1770
 
1771
  memset (fs, 0, sizeof (*fs));
1772
  for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1773
    r->when = UNW_WHEN_NEVER;
1774
  context->lsda = 0;
1775
 
1776
  ent = _Unwind_FindTableEntry ((void *) context->rp,
1777
                                &segment_base, &context->gp);
1778
  if (ent == NULL)
1779
    {
1780
      /* Couldn't find unwind info for this function.  Try an
1781
         os-specific fallback mechanism.  This will necessarily
1782
         not provide a personality routine or LSDA.  */
1783
#ifdef MD_FALLBACK_FRAME_STATE_FOR
1784
      if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON)
1785
        return _URC_NO_REASON;
1786
 
1787
      /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1788
         handlers, and which keeps the return value in B0 does not need
1789
         an unwind table entry.
1790
 
1791
         This can only happen in the frame after unwinding through a signal
1792
         handler.  Avoid infinite looping by requiring that B0 != RP.
1793
         RP == 0 terminates the chain.  */
1794
      if (context->br_loc[0] && *context->br_loc[0] != context->rp
1795
          && context->rp != 0)
1796
        {
1797
          fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1798
          fs->curr.reg[UNW_REG_RP].when = -1;
1799
          fs->curr.reg[UNW_REG_RP].val = 0;
1800
          return _URC_NO_REASON;
1801
        }
1802
#endif
1803
      return _URC_END_OF_STACK;
1804
    }
1805
 
1806
  context->region_start = ent->start_offset + segment_base;
1807
  fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3
1808
                    + (context->rp & 15);
1809
 
1810
  unw = (unsigned long *) (ent->info_offset + segment_base);
1811
  header = *unw;
1812
  length = UNW_LENGTH (header);
1813
 
1814
  /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK.  */
1815
 
1816
  if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))
1817
    {
1818
      fs->personality =
1819
        *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1820
      context->lsda = unw + length + 2;
1821
    }
1822
 
1823
  insn = (unsigned char *) (unw + 1);
1824
  insn_end = (unsigned char *) (unw + 1 + length);
1825
  while (!fs->done && insn < insn_end)
1826
    insn = unw_decode (insn, fs->in_body, fs);
1827
 
1828
  free_label_states (fs->labeled_states);
1829
  free_state_stack (&fs->curr);
1830
 
1831
#ifdef ENABLE_MALLOC_CHECKING
1832
  if (reg_state_alloced || labeled_state_alloced)
1833
    abort ();
1834
#endif
1835
 
1836
  /* If we're in the epilogue, sp has been restored and all values
1837
     on the memory stack below psp also have been restored.  */
1838
  if (fs->when_target > fs->epilogue_start)
1839
    {
1840
      struct unw_reg_info *r;
1841
 
1842
      fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1843
      fs->curr.reg[UNW_REG_PSP].val = 0;
1844
      for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1845
        if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1846
            || r->where == UNW_WHERE_SPREL)
1847
          r->where = UNW_WHERE_NONE;
1848
    }
1849
 
1850
  /* If RP did't get saved, generate entry for the return link register.  */
1851
  if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target)
1852
    {
1853
      fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1854
      fs->curr.reg[UNW_REG_RP].when = -1;
1855
      fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg;
1856
    }
1857
 
1858
  return _URC_NO_REASON;
1859
}
1860
 
1861
static void
1862
uw_update_reg_address (struct _Unwind_Context *context,
1863
                       _Unwind_FrameState *fs,
1864
                       enum unw_register_index regno)
1865
{
1866
  struct unw_reg_info *r = fs->curr.reg + regno;
1867
  void *addr;
1868
  unsigned long rval;
1869
 
1870
  if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1871
    return;
1872
 
1873
  rval = r->val;
1874
  switch (r->where)
1875
    {
1876
    case UNW_WHERE_GR:
1877
      if (rval >= 32)
1878
        addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32);
1879
      else if (rval >= 2)
1880
        addr = context->ireg[rval - 2].loc;
1881
      else if (rval == 0)
1882
        {
1883
          static const unsigned long dummy;
1884
          addr = (void *) &dummy;
1885
        }
1886
      else
1887
        abort ();
1888
      break;
1889
 
1890
    case UNW_WHERE_FR:
1891
      if (rval >= 2 && rval < 32)
1892
        addr = context->fr_loc[rval - 2];
1893
      else
1894
        abort ();
1895
      break;
1896
 
1897
    case UNW_WHERE_BR:
1898
      /* Note that while RVAL can only be 1-5 from normal descriptors,
1899
         we can want to look at B0, B6 and B7 due to having manually unwound a
1900
         signal frame.  */
1901
      if (rval < 8)
1902
        addr = context->br_loc[rval];
1903
      else
1904
        abort ();
1905
      break;
1906
 
1907
    case UNW_WHERE_SPREL:
1908
      addr = (void *)(context->sp + rval);
1909
      break;
1910
 
1911
    case UNW_WHERE_PSPREL:
1912
      addr = (void *)(context->psp + rval);
1913
      break;
1914
 
1915
    default:
1916
      abort ();
1917
    }
1918
 
1919
  switch (regno)
1920
    {
1921
    case UNW_REG_R2 ... UNW_REG_R31:
1922
      context->ireg[regno - UNW_REG_R2].loc = addr;
1923
      switch (r->where)
1924
      {
1925
      case UNW_WHERE_GR:
1926
        if (rval >= 32)
1927
          {
1928
            context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1929
            context->ireg[regno - UNW_REG_R2].nat.off
1930
              = context->pri_unat_loc - (unsigned long *) addr;
1931
          }
1932
        else if (rval >= 2)
1933
          {
1934
            context->ireg[regno - UNW_REG_R2].nat
1935
              = context->ireg[rval - 2].nat;
1936
          }
1937
        else if (rval == 0)
1938
          {
1939
            context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1940
            context->ireg[regno - UNW_REG_R2].nat.off = 0;
1941
          }
1942
        else
1943
          abort ();
1944
        break;
1945
 
1946
      case UNW_WHERE_FR:
1947
        context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL;
1948
        context->ireg[regno - UNW_REG_R2].nat.off = 0;
1949
        break;
1950
 
1951
      case UNW_WHERE_BR:
1952
        context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1953
        context->ireg[regno - UNW_REG_R2].nat.off = 0;
1954
        break;
1955
 
1956
      case UNW_WHERE_PSPREL:
1957
      case UNW_WHERE_SPREL:
1958
        context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1959
        context->ireg[regno - UNW_REG_R2].nat.off
1960
          = context->pri_unat_loc - (unsigned long *) addr;
1961
        break;
1962
 
1963
      default:
1964
        abort ();
1965
      }
1966
      break;
1967
 
1968
    case UNW_REG_F2 ... UNW_REG_F31:
1969
      context->fr_loc[regno - UNW_REG_F2] = addr;
1970
      break;
1971
 
1972
    case UNW_REG_B1 ... UNW_REG_B5:
1973
      context->br_loc[regno - UNW_REG_B0] = addr;
1974
      break;
1975
 
1976
    case UNW_REG_BSP:
1977
      context->bsp_loc = addr;
1978
      break;
1979
    case UNW_REG_BSPSTORE:
1980
      context->bspstore_loc = addr;
1981
      break;
1982
    case UNW_REG_PFS:
1983
      context->pfs_loc = addr;
1984
      break;
1985
    case UNW_REG_RP:
1986
      context->rp = *(unsigned long *)addr;
1987
      break;
1988
    case UNW_REG_UNAT:
1989
      context->unat_loc = addr;
1990
      break;
1991
    case UNW_REG_PR:
1992
      context->pr = *(unsigned long *) addr;
1993
      break;
1994
    case UNW_REG_LC:
1995
      context->lc_loc = addr;
1996
      break;
1997
    case UNW_REG_FPSR:
1998
      context->fpsr_loc = addr;
1999
      break;
2000
 
2001
    case UNW_REG_PSP:
2002
      context->psp = *(unsigned long *)addr;
2003
      break;
2004
 
2005
    default:
2006
      abort ();
2007
    }
2008
}
2009
 
2010
static void
2011
uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2012
{
2013
  long i;
2014
 
2015
#ifdef MD_HANDLE_UNWABI
2016
  MD_HANDLE_UNWABI (context, fs);
2017
#endif
2018
 
2019
  context->sp = context->psp;
2020
 
2021
  /* First, set PSP.  Subsequent instructions may depend on this value.  */
2022
  if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
2023
    {
2024
      if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
2025
        context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val;
2026
      else
2027
        uw_update_reg_address (context, fs, UNW_REG_PSP);
2028
    }
2029
 
2030
  /* Determine the location of the primary UNaT.  */
2031
  {
2032
    int i;
2033
    if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2034
      i = UNW_REG_PRI_UNAT_MEM;
2035
    else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when)
2036
      i = UNW_REG_PRI_UNAT_GR;
2037
    else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when
2038
             > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2039
      i = UNW_REG_PRI_UNAT_MEM;
2040
    else
2041
      i = UNW_REG_PRI_UNAT_GR;
2042
    uw_update_reg_address (context, fs, i);
2043
  }
2044
 
2045
  /* Compute the addresses of all registers saved in this frame.  */
2046
  for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
2047
    uw_update_reg_address (context, fs, i);
2048
 
2049
  /* Unwind BSP for the local registers allocated this frame.  */
2050
  /* ??? What to do with stored BSP or BSPSTORE registers.  */
2051
  /* We assert that we are either at a call site, or we have
2052
     just unwound through a signal frame.  In either case
2053
     pfs_loc is valid.  */
2054
  if (!(fs -> no_reg_stack_frame))
2055
    {
2056
      unsigned long pfs = *context->pfs_loc;
2057
      unsigned long sol = (pfs >> 7) & 0x7f;
2058
      context->bsp = (unsigned long)
2059
        ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol);
2060
    }
2061
}
2062
 
2063
static void
2064
uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2065
{
2066
  uw_update_context (context, fs);
2067
}
2068
 
2069
/* Fill in CONTEXT for top-of-stack.  The only valid registers at this
2070
   level will be the return address and the CFA.  Note that CFA = SP+16.  */
2071
 
2072
#define uw_init_context(CONTEXT)                                        \
2073
  do {                                                                  \
2074
    /* ??? There is a whole lot o code in uw_install_context that       \
2075
       tries to avoid spilling the entire machine state here.  We       \
2076
       should try to make that work again.  */                          \
2077
    __builtin_unwind_init();                                            \
2078
    uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ());                 \
2079
  } while (0)
2080
 
2081
static void
2082
uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
2083
{
2084
  void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
2085
  /* Set psp to the caller's stack pointer.  */
2086
  void *psp = __builtin_dwarf_cfa () - 16;
2087
  _Unwind_FrameState fs;
2088
  unsigned long rnat, tmp1, tmp2;
2089
 
2090
  /* Flush the register stack to memory so that we can access it.
2091
     Get rse nat collection for the last incomplete rbs chunk of
2092
     registers at the same time.  For this RSE needs to be turned
2093
     into the mandatory only mode.  */
2094
  asm ("mov.m %1 = ar.rsc;;\n\t"
2095
       "and %2 = 0x1c, %1;;\n\t"
2096
       "mov.m ar.rsc = %2;;\n\t"
2097
       "flushrs;;\n\t"
2098
       "mov.m %0 = ar.rnat;;\n\t"
2099
       "mov.m ar.rsc = %1\n\t"
2100
       : "=r" (rnat), "=r" (tmp1), "=r" (tmp2));
2101
 
2102
  memset (context, 0, sizeof (struct _Unwind_Context));
2103
  context->bsp = (unsigned long) bsp;
2104
  /* Set context->regstk_top to lowest rbs address which will use
2105
     context->rnat collection.  */
2106
  context->regstk_top = context->bsp & ~0x1ffULL;
2107
  context->rnat = rnat;
2108
  context->psp = (unsigned long) psp;
2109
  context->rp = (unsigned long) rp;
2110
  asm ("mov %0 = sp" : "=r" (context->sp));
2111
  asm ("mov %0 = pr" : "=r" (context->pr));
2112
  context->pri_unat_loc = &context->initial_unat;       /* ??? */
2113
 
2114
  if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
2115
    abort ();
2116
 
2117
  uw_update_context (context, &fs);
2118
}
2119
 
2120
/* Install (i.e. longjmp to) the contents of TARGET.  */
2121
 
2122
static void __attribute__((noreturn))
2123
uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
2124
                    struct _Unwind_Context *target)
2125
{
2126
  unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
2127
  long i;
2128
 
2129
  /* Copy integer register data from the target context to a
2130
     temporary buffer.  Do this so that we can frob AR.UNAT
2131
     to get the NaT bits for these registers set properly.  */
2132
  for (i = 4; i <= 7; ++i)
2133
    {
2134
      char nat;
2135
      void *t = target->ireg[i - 2].loc;
2136
      if (t)
2137
        {
2138
          unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0);
2139
          ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f);
2140
          /* Set p6 - p9.  */
2141
          ireg_pr |= 4L << i;
2142
        }
2143
    }
2144
 
2145
  /* The value in uc_bsp that we've computed is that for the
2146
     target function.  The value that we install below will be
2147
     adjusted by the BR.RET instruction based on the contents
2148
     of AR.PFS.  So we must unadjust that here.  */
2149
  target->bsp = (unsigned long)
2150
    ia64_rse_skip_regs ((unsigned long *)target->bsp,
2151
                        (*target->pfs_loc >> 7) & 0x7f);
2152
 
2153
  if (target->bsp < target->regstk_top)
2154
    target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp);
2155
 
2156
  /* Provide assembly with the offsets into the _Unwind_Context.  */
2157
  asm volatile ("uc_rnat = %0"
2158
                : : "i"(offsetof (struct _Unwind_Context, rnat)));
2159
  asm volatile ("uc_bsp = %0"
2160
                : : "i"(offsetof (struct _Unwind_Context, bsp)));
2161
  asm volatile ("uc_psp = %0"
2162
                : : "i"(offsetof (struct _Unwind_Context, psp)));
2163
  asm volatile ("uc_rp = %0"
2164
                : : "i"(offsetof (struct _Unwind_Context, rp)));
2165
  asm volatile ("uc_pr = %0"
2166
                : : "i"(offsetof (struct _Unwind_Context, pr)));
2167
  asm volatile ("uc_gp = %0"
2168
                : : "i"(offsetof (struct _Unwind_Context, gp)));
2169
  asm volatile ("uc_pfs_loc = %0"
2170
                : : "i"(offsetof (struct _Unwind_Context, pfs_loc)));
2171
  asm volatile ("uc_unat_loc = %0"
2172
                : : "i"(offsetof (struct _Unwind_Context, unat_loc)));
2173
  asm volatile ("uc_lc_loc = %0"
2174
                : : "i"(offsetof (struct _Unwind_Context, lc_loc)));
2175
  asm volatile ("uc_fpsr_loc = %0"
2176
                : : "i"(offsetof (struct _Unwind_Context, fpsr_loc)));
2177
  asm volatile ("uc_eh_data = %0"
2178
                : : "i"(offsetof (struct _Unwind_Context, eh_data)));
2179
  asm volatile ("uc_br_loc = %0"
2180
                : : "i"(offsetof (struct _Unwind_Context, br_loc)));
2181
  asm volatile ("uc_fr_loc = %0"
2182
                : : "i"(offsetof (struct _Unwind_Context, fr_loc)));
2183
 
2184
  asm volatile (
2185
        /* Load up call-saved non-window integer registers from ireg_buf.  */
2186
        "add r20 = 8, %1                        \n\t"
2187
        "mov ar.unat = %2                       \n\t"
2188
        "mov pr = %3, 0x3c0                     \n\t"
2189
        ";;                                     \n\t"
2190
        "(p6) ld8.fill r4 = [%1]                \n\t"
2191
        "(p7) ld8.fill r5 = [r20]               \n\t"
2192
        "add r21 = uc_br_loc + 16, %0           \n\t"
2193
        "adds %1 = 16, %1                       \n\t"
2194
        "adds r20 = 16, r20                     \n\t"
2195
        ";;                                     \n\t"
2196
        "(p8) ld8.fill r6 = [%1]                \n\t"
2197
        "(p9) ld8.fill r7 = [r20]               \n\t"
2198
        "add r20 = uc_br_loc + 8, %0            \n\t"
2199
        ";;                                     \n\t"
2200
        /* Load up call-saved branch registers.  */
2201
        "ld8 r22 = [r20], 16                    \n\t"
2202
        "ld8 r23 = [r21], 16                    \n\t"
2203
        ";;                                     \n\t"
2204
        "ld8 r24 = [r20], 16                    \n\t"
2205
        "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
2206
        ";;                                     \n\t"
2207
        "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
2208
        "ld8 r27 = [r21], 24                    \n\t"
2209
        "cmp.ne p6, p0 = r0, r22                \n\t"
2210
        ";;                                     \n\t"
2211
        "ld8 r28 = [r20], 8                     \n\t"
2212
        "(p6) ld8 r22 = [r22]                   \n\t"
2213
        "cmp.ne p7, p0 = r0, r23                \n\t"
2214
        ";;                                     \n\t"
2215
        "(p7) ld8 r23 = [r23]                   \n\t"
2216
        "cmp.ne p8, p0 = r0, r24                \n\t"
2217
        ";;                                     \n\t"
2218
        "(p8) ld8 r24 = [r24]                   \n\t"
2219
        "(p6) mov b1 = r22                      \n\t"
2220
        "cmp.ne p9, p0 = r0, r25                \n\t"
2221
        ";;                                     \n\t"
2222
        "(p9) ld8 r25 = [r25]                   \n\t"
2223
        "(p7) mov b2 = r23                      \n\t"
2224
        "cmp.ne p6, p0 = r0, r26                \n\t"
2225
        ";;                                     \n\t"
2226
        "(p6) ld8 r26 = [r26]                   \n\t"
2227
        "(p8) mov b3 = r24                      \n\t"
2228
        "cmp.ne p7, p0 = r0, r27                \n\t"
2229
        ";;                                     \n\t"
2230
        /* Load up call-saved fp registers.  */
2231
        "(p7) ldf.fill f2 = [r27]               \n\t"
2232
        "(p9) mov b4 = r25                      \n\t"
2233
        "cmp.ne p8, p0 = r0, r28                \n\t"
2234
        ";;                                     \n\t"
2235
        "(p8) ldf.fill f3 = [r28]               \n\t"
2236
        "(p6) mov b5 = r26                      \n\t"
2237
        ";;                                     \n\t"
2238
        "ld8 r29 = [r20], 16*8 - 4*8            \n\t"
2239
        "ld8 r30 = [r21], 17*8 - 5*8            \n\t"
2240
        ";;                                     \n\t"
2241
        "ld8 r22 = [r20], 16                    \n\t"
2242
        "ld8 r23 = [r21], 16                    \n\t"
2243
        ";;                                     \n\t"
2244
        "ld8 r24 = [r20], 16                    \n\t"
2245
        "ld8 r25 = [r21]                        \n\t"
2246
        "cmp.ne p6, p0 = r0, r29                \n\t"
2247
        ";;                                     \n\t"
2248
        "ld8 r26 = [r20], 8                     \n\t"
2249
        "(p6) ldf.fill f4 = [r29]               \n\t"
2250
        "cmp.ne p7, p0 = r0, r30                \n\t"
2251
        ";;                                     \n\t"
2252
        "ld8 r27 = [r20], 8                     \n\t"
2253
        "(p7) ldf.fill f5 = [r30]               \n\t"
2254
        "cmp.ne p6, p0 = r0, r22                \n\t"
2255
        ";;                                     \n\t"
2256
        "ld8 r28 = [r20], 8                     \n\t"
2257
        "(p6) ldf.fill f16 = [r22]              \n\t"
2258
        "cmp.ne p7, p0 = r0, r23                \n\t"
2259
        ";;                                     \n\t"
2260
        "ld8 r29 = [r20], 8                     \n\t"
2261
        "(p7) ldf.fill f17 = [r23]              \n\t"
2262
        "cmp.ne p6, p0 = r0, r24                \n\t"
2263
        ";;                                     \n\t"
2264
        "ld8 r22 = [r20], 8                     \n\t"
2265
        "(p6) ldf.fill f18 = [r24]              \n\t"
2266
        "cmp.ne p7, p0 = r0, r25                \n\t"
2267
        ";;                                     \n\t"
2268
        "ld8 r23 = [r20], 8                     \n\t"
2269
        "(p7) ldf.fill f19 = [r25]              \n\t"
2270
        "cmp.ne p6, p0 = r0, r26                \n\t"
2271
        ";;                                     \n\t"
2272
        "ld8 r24 = [r20], 8                     \n\t"
2273
        "(p6) ldf.fill f20 = [r26]              \n\t"
2274
        "cmp.ne p7, p0 = r0, r27                \n\t"
2275
        ";;                                     \n\t"
2276
        "ld8 r25 = [r20], 8                     \n\t"
2277
        "(p7) ldf.fill f21 = [r27]              \n\t"
2278
        "cmp.ne p6, p0 = r0, r28                \n\t"
2279
        ";;                                     \n\t"
2280
        "ld8 r26 = [r20], 8                     \n\t"
2281
        "(p6) ldf.fill f22 = [r28]              \n\t"
2282
        "cmp.ne p7, p0 = r0, r29                \n\t"
2283
        ";;                                     \n\t"
2284
        "ld8 r27 = [r20], 8                     \n\t"
2285
        ";;                                     \n\t"
2286
        "ld8 r28 = [r20], 8                     \n\t"
2287
        "(p7) ldf.fill f23 = [r29]              \n\t"
2288
        "cmp.ne p6, p0 = r0, r22                \n\t"
2289
        ";;                                     \n\t"
2290
        "ld8 r29 = [r20], 8                     \n\t"
2291
        "(p6) ldf.fill f24 = [r22]              \n\t"
2292
        "cmp.ne p7, p0 = r0, r23                \n\t"
2293
        ";;                                     \n\t"
2294
        "(p7) ldf.fill f25 = [r23]              \n\t"
2295
        "cmp.ne p6, p0 = r0, r24                \n\t"
2296
        "cmp.ne p7, p0 = r0, r25                \n\t"
2297
        ";;                                     \n\t"
2298
        "(p6) ldf.fill f26 = [r24]              \n\t"
2299
        "(p7) ldf.fill f27 = [r25]              \n\t"
2300
        "cmp.ne p6, p0 = r0, r26                \n\t"
2301
        ";;                                     \n\t"
2302
        "(p6) ldf.fill f28 = [r26]              \n\t"
2303
        "cmp.ne p7, p0 = r0, r27                \n\t"
2304
        "cmp.ne p6, p0 = r0, r28                \n\t"
2305
        ";;                                     \n\t"
2306
        "(p7) ldf.fill f29 = [r27]              \n\t"
2307
        "(p6) ldf.fill f30 = [r28]              \n\t"
2308
        "cmp.ne p7, p0 = r0, r29                \n\t"
2309
        ";;                                     \n\t"
2310
        "(p7) ldf.fill f31 = [r29]              \n\t"
2311
        "add r20 = uc_rnat, %0                  \n\t"
2312
        "add r21 = uc_bsp, %0                   \n\t"
2313
        ";;                                     \n\t"
2314
        /* Load the balance of the thread state from the context.  */
2315
        "ld8 r22 = [r20], uc_psp - uc_rnat      \n\t"
2316
        "ld8 r23 = [r21], uc_gp - uc_bsp        \n\t"
2317
        ";;                                     \n\t"
2318
        "ld8 r24 = [r20], uc_pfs_loc - uc_psp   \n\t"
2319
        "ld8 r1 = [r21], uc_rp - uc_gp          \n\t"
2320
        ";;                                     \n\t"
2321
        "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2322
        "ld8 r26 = [r21], uc_pr - uc_rp         \n\t"
2323
        ";;                                     \n\t"
2324
        "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2325
        "ld8 r28 = [r21], uc_fpsr_loc - uc_pr   \n\t"
2326
        ";;                                     \n\t"
2327
        "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2328
        "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2329
        ";;                                     \n\t"
2330
        /* Load data for the exception handler.  */
2331
        "ld8 r15 = [r20], 16                    \n\t"
2332
        "ld8 r16 = [r21], 16                    \n\t"
2333
        ";;                                     \n\t"
2334
        "ld8 r17 = [r20]                        \n\t"
2335
        "ld8 r18 = [r21]                        \n\t"
2336
        ";;                                     \n\t"
2337
        /* Install the balance of the thread state loaded above.  */
2338
        "cmp.ne p6, p0 = r0, r25                \n\t"
2339
        "cmp.ne p7, p0 = r0, r27                \n\t"
2340
        ";;                                     \n\t"
2341
        "(p6) ld8 r25 = [r25]                   \n\t"
2342
        "(p7) ld8 r27 = [r27]                   \n\t"
2343
        ";;                                     \n\t"
2344
        "(p7) mov.m ar.unat = r27               \n\t"
2345
        "(p6) mov.i ar.pfs = r25                \n\t"
2346
        "cmp.ne p9, p0 = r0, r29                \n\t"
2347
        ";;                                     \n\t"
2348
        "(p9) ld8 r29 = [r29]                   \n\t"
2349
        "cmp.ne p6, p0 = r0, r30                \n\t"
2350
        ";;                                     \n\t"
2351
        "(p6) ld8 r30 = [r30]                   \n\t"
2352
        /* Don't clobber p6-p9, which are in use at present.  */
2353
        "mov pr = r28, ~0x3c0                   \n\t"
2354
        "(p9) mov.i ar.lc = r29                 \n\t"
2355
        ";;                                     \n\t"
2356
        "mov.m r25 = ar.rsc                     \n\t"
2357
        "(p6) mov.m ar.fpsr = r30               \n\t"
2358
        ";;                                     \n\t"
2359
        "and r29 = 0x1c, r25                    \n\t"
2360
        "mov b0 = r26                           \n\t"
2361
        ";;                                     \n\t"
2362
        "mov.m ar.rsc = r29                     \n\t"
2363
        ";;                                     \n\t"
2364
        /* This must be done before setting AR.BSPSTORE, otherwise
2365
           AR.BSP will be initialized with a random displacement
2366
           below the value we want, based on the current number of
2367
           dirty stacked registers.  */
2368
        "loadrs                                 \n\t"
2369
        "invala                                 \n\t"
2370
        ";;                                     \n\t"
2371
        "mov.m ar.bspstore = r23                \n\t"
2372
        ";;                                     \n\t"
2373
        "mov.m ar.rnat = r22                    \n\t"
2374
        ";;                                     \n\t"
2375
        "mov.m ar.rsc = r25                     \n\t"
2376
        "mov sp = r24                           \n\t"
2377
        "br.ret.sptk.few b0"
2378
        : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr)
2379
        : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2380
          "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2381
          "r30", "r31");
2382
  /* NOTREACHED */
2383
  while (1);
2384
}
2385
 
2386
static inline _Unwind_Ptr
2387
uw_identify_context (struct _Unwind_Context *context)
2388
{
2389
  return _Unwind_GetIP (context);
2390
}
2391
 
2392
#include "unwind.inc"
2393
 
2394
#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
2395
alias (_Unwind_Backtrace);
2396
alias (_Unwind_DeleteException);
2397
alias (_Unwind_FindEnclosingFunction);
2398
alias (_Unwind_ForcedUnwind);
2399
alias (_Unwind_GetBSP);
2400
alias (_Unwind_GetCFA);
2401
alias (_Unwind_GetGR);
2402
alias (_Unwind_GetIP);
2403
alias (_Unwind_GetLanguageSpecificData);
2404
alias (_Unwind_GetRegionStart);
2405
alias (_Unwind_RaiseException);
2406
alias (_Unwind_Resume);
2407
alias (_Unwind_Resume_or_Rethrow);
2408
alias (_Unwind_SetGR);
2409
alias (_Unwind_SetIP);
2410
#endif
2411
 
2412
#endif

powered by: WebSVN 2.1.0

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