1/* DWARF2 EH unwinding support for Alpha VMS.
2   Copyright (C) 2004 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to
18the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19Boston, MA 02110-1301, USA.  */
20
21#include <pdscdef.h>
22
23#define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
24
25static _Unwind_Reason_Code
26alpha_fallback_frame_state (struct _Unwind_Context *context,
27			    _Unwind_FrameState *fs)
28{
29  PDSCDEF *pv = *((PDSCDEF **) context->reg [29]);
30
31  if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */
32    pv = *(PDSCDEF **) pv;
33
34  if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK))
35    {
36      int i, j;
37
38      fs->cfa_offset = pv->pdsc$l_size;
39      fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
40      fs->retaddr_column = 26;
41      fs->cfa_how = CFA_REG_OFFSET;
42      fs->regs.reg[27].loc.offset = -pv->pdsc$l_size;
43      fs->regs.reg[27].how = REG_SAVED_OFFSET;
44      fs->regs.reg[26].loc.offset
45	= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset);
46      fs->regs.reg[26].how = REG_SAVED_OFFSET;
47
48      for (i = 0, j = 0; i < 32; i++)
49	if (1<<i & pv->pdsc$l_ireg_mask)
50	  {
51	    fs->regs.reg[i].loc.offset
52	      = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j);
53	    fs->regs.reg[i].how = REG_SAVED_OFFSET;
54	  }
55
56      return _URC_NO_REASON;
57    }
58  else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER))
59    {
60      fs->cfa_offset = pv->pdsc$l_size;
61      fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
62      fs->retaddr_column = 26;
63      fs->cfa_how = CFA_REG_OFFSET;
64      fs->regs.reg[26].loc.reg = pv->pdsc$b_save_ra;
65      fs->regs.reg[26].how = REG_SAVED_REG;
66      fs->regs.reg[29].loc.reg = pv->pdsc$b_save_fp;
67      fs->regs.reg[29].how = REG_SAVED_REG;
68
69      return _URC_NO_REASON;
70    }
71  return _URC_END_OF_STACK;
72}
73