1b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm/* libunwind - a platform-independent unwind library
23e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm   Copyright (C) 2001-2005 Hewlett-Packard Co
3b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
5b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmThis file is part of libunwind.
6b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
7b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining
8b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidma copy of this software and associated documentation files (the
9b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm"Software"), to deal in the Software without restriction, including
10b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish,
11b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to
12b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to
13b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmthe following conditions:
14b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
15b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmThe above copyright notice and this permission notice shall be
16b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmincluded in all copies or substantial portions of the Software.
17b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
18b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
26b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "offsets.h"
27b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "regs.h"
28b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "unwind_i.h"
29b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
30b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline ia64_loc_t
31b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmlinux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr)
32b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
33b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#if !defined(UNW_LOCAL_ONLY) || defined(__linux)
34b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  unw_word_t addr = c->sigcontext_addr, flags, tmp_addr;
35b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  int i;
36b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
37fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm  if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_SIGTRAMP
38fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      || ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_SIGTRAMP)
39b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
40b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      switch (reg)
41b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
42b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3:
43b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31:
44b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  /* Linux sigcontext contains the NaT bit of scratch register
45b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	     N in bit position N of the sc_nat member. */
46b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  *nat_bitnr = (reg - UNW_IA64_NAT);
47b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  addr += LINUX_SC_NAT_OFF;
48b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  break;
49b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
50b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_GR +  2 ... UNW_IA64_GR + 3:
51b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_GR +  8 ... UNW_IA64_GR + 31:
52b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  addr += LINUX_SC_GR_OFF + 8 * (reg - UNW_IA64_GR);
53b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  break;
54b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
55b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15:
56b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR);
57b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP);
58b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
59b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127:
60b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (ia64_get (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0),
61b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm			&flags) < 0)
62b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    return IA64_NULL_LOC;
63b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
64b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (!(flags & IA64_SC_FLAG_FPH_VALID))
65b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    {
66b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      /* initialize fph partition: */
67b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      tmp_addr = addr + LINUX_SC_FR_OFF + 32*16;
68b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      for (i = 32; i < 128; ++i, tmp_addr += 16)
69b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		if (ia64_putfp (c, IA64_LOC_ADDR (tmp_addr, 0),
70b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm				unw.read_only.f0) < 0)
71b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		  return IA64_NULL_LOC;
72b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      /* mark fph partition as valid: */
73b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      if (ia64_put (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0),
74b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm			    flags | IA64_SC_FLAG_FPH_VALID) < 0)
75b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		return IA64_NULL_LOC;
76b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    }
77b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
78b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR);
79b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP);
80b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
81b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_BR + 0: addr += LINUX_SC_BR_OFF + 0; break;
82b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_BR + 6: addr += LINUX_SC_BR_OFF + 6*8; break;
83b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_BR + 7: addr += LINUX_SC_BR_OFF + 7*8; break;
84b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_AR_RSC: addr += LINUX_SC_AR_RSC_OFF; break;
85b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_AR_CSD: addr += LINUX_SC_AR_CSD_OFF; break;
86b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_AR_SSD: addr += LINUX_SC_AR_SSD_OFF; break;
87b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break;
88b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
89b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	default:
90fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	  if (unw_is_fpreg (reg))
91fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    return IA64_FPREG_LOC (c, reg);
92fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	  else
93fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    return IA64_REG_LOC (c, reg);
94b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
95b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return IA64_LOC_ADDR (addr, 0);
96b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
97b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  else
98b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
99b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      int is_nat = 0;
100b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
101b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if ((unsigned) (reg - UNW_IA64_NAT) < 128)
102b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
103b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  is_nat = 1;
104b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  reg -= (UNW_IA64_NAT - UNW_IA64_GR);
105b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
106fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      if (ia64_get_abi_marker (c) == ABI_MARKER_LINUX_INTERRUPT)
107b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
108b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  switch (reg)
109b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    {
110b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_BR + 6 ... UNW_IA64_BR + 7:
111b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_PT_B6_OFF + 8 * (reg - (UNW_IA64_BR + 6));
112b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
113b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
114b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_CSD: addr += LINUX_PT_CSD_OFF; break;
115b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_SSD: addr += LINUX_PT_SSD_OFF; break;
116b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
117b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR +  8 ... UNW_IA64_GR + 11:
118b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8));
119b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
120b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
121fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_IP: addr += LINUX_PT_IIP_OFF; break;
122fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_CFM: addr += LINUX_PT_IFS_OFF; break;
123fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_AR_UNAT: addr += LINUX_PT_UNAT_OFF; break;
124fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_AR_PFS: addr += LINUX_PT_PFS_OFF; break;
125b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break;
126fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_AR_RNAT: addr += LINUX_PT_RNAT_OFF; break;
127fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_AR_BSPSTORE: addr += LINUX_PT_BSPSTORE_OFF; break;
128fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_PR: addr += LINUX_PT_PR_OFF; break;
129b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break;
130f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm
131f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    case UNW_IA64_GR + 1:
132f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      /* The saved r1 value is valid only in the frame in which
133f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		 it was saved; for everything else we need to look up
134f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		 the appropriate gp value.  */
135f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      if (c->sigcontext_addr != c->sp + 0x10)
136f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		return IA64_NULL_LOC;
137f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      addr += LINUX_PT_R1_OFF;
138f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      break;
139f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm
140fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_GR + 12: addr += LINUX_PT_R12_OFF; break;
141fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_GR + 13: addr += LINUX_PT_R13_OFF; break;
142fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_AR_FPSR: addr += LINUX_PT_FPSR_OFF; break;
143fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_GR + 15: addr += LINUX_PT_R15_OFF; break;
144fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	    case UNW_IA64_GR + 14: addr += LINUX_PT_R14_OFF; break;
145b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break;
146b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break;
147b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
148b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31:
149b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16));
150b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
151b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
152b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_CCV: addr += LINUX_PT_CCV_OFF; break;
153b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
154b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_FR + 6 ... UNW_IA64_FR + 11:
155b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6));
156b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP);
157b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
158b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    default:
159fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      if (unw_is_fpreg (reg))
160fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm		return IA64_FPREG_LOC (c, reg);
161fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      else
162fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm		return IA64_REG_LOC (c, reg);
163b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    }
164b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
165fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      else if (ia64_get_abi_marker (c) == ABI_MARKER_OLD_LINUX_INTERRUPT)
166b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
167b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  switch (reg)
168b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    {
169f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    case UNW_IA64_GR +  1:
170f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      /* The saved r1 value is valid only in the frame in which
171f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		 it was saved; for everything else we need to look up
172f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		 the appropriate gp value.  */
173f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      if (c->sigcontext_addr != c->sp + 0x10)
174f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm		return IA64_NULL_LOC;
175f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      addr += LINUX_OLD_PT_R1_OFF;
176f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      break;
177f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm
178f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    case UNW_IA64_GR +  2 ... UNW_IA64_GR + 3:
179f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	      addr += LINUX_OLD_PT_R2_OFF + 8 * (reg - (UNW_IA64_GR + 2));
180b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
181b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
182b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR +  8 ... UNW_IA64_GR + 11:
183b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_OLD_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8));
184b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
185b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
186b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31:
187b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_OLD_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16));
188b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      break;
189b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
190b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_FR + 6 ... UNW_IA64_FR + 9:
191b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      addr += LINUX_OLD_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6));
192b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP);
193b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
194b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_BR + 0: addr += LINUX_OLD_PT_B0_OFF; break;
195b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_BR + 6: addr += LINUX_OLD_PT_B6_OFF; break;
196b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_BR + 7: addr += LINUX_OLD_PT_B7_OFF; break;
197b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
198b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_RSC: addr += LINUX_OLD_PT_RSC_OFF; break;
199b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break;
200b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
201b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    default:
202fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      if (unw_is_fpreg (reg))
203fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm		return IA64_FPREG_LOC (c, reg);
204fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      else
205fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm		return IA64_REG_LOC (c, reg);
206b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    }
207b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
208b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (is_nat)
209b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
210b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  /* For Linux pt-regs structure, bit number is determined by
211b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	     the UNaT slot number (as determined by st8.spill) and the
212b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	     bits are saved wherever the (primary) UNaT was saved.  */
213b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  *nat_bitnr = ia64_unat_slot_num (addr);
214b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return c->loc[IA64_REG_PRI_UNAT_MEM];
215b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
216b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return IA64_LOC_ADDR (addr, 0);
217b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
218b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#endif
219b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  return IA64_NULL_LOC;
220b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
221b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
222b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline ia64_loc_t
223b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmhpux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr)
224b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
225b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#if !defined(UNW_LOCAL_ONLY) || defined(__hpux)
226b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  return IA64_LOC_UC_REG (reg, c->sigcontext_addr);
227b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#else
228b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  return IA64_NULL_LOC;
229b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#endif
230b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
231b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
232b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN ia64_loc_t
233b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmia64_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr)
234b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
235b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (c->sigcontext_addr)
236b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
237fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      if (ia64_get_abi (c) == ABI_LINUX)
238b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return linux_scratch_loc (c, reg, nat_bitnr);
239fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      else if (ia64_get_abi (c) ==  ABI_HPUX)
240b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return hpux_scratch_loc (c, reg, nat_bitnr);
241b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
242b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return IA64_NULL_LOC;
243b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
244b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  else
245b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    return IA64_REG_LOC (c, reg);
246b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
247b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
248b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline int
249b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmupdate_nat (struct cursor *c, ia64_loc_t nat_loc, unw_word_t mask,
250b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    unw_word_t *valp, int write)
251b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
252b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  unw_word_t nat_word;
253b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  int ret;
254b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
255b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  ret = ia64_get (c, nat_loc, &nat_word);
256b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (ret < 0)
257b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    return ret;
258b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
259b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (write)
260b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
261b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (*valp)
262b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	nat_word |= mask;
263b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
264b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	nat_word &= ~mask;
265b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      ret = ia64_put (c, nat_loc, nat_word);
266b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
267b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  else
268b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    *valp = (nat_word & mask) != 0;
269b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  return ret;
270b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
271b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
272b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic int
273b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmaccess_nat (struct cursor *c,
274b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    ia64_loc_t nat_loc, ia64_loc_t reg_loc, uint8_t nat_bitnr,
275b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    unw_word_t *valp, int write)
276b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
277b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  unw_word_t mask = 0;
278b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  unw_fpreg_t tmp;
279b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  int ret;
280b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
281b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (IA64_IS_FP_LOC (reg_loc))
282b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
283b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      /* NaT bit is saved as a NaTVal.  This happens when a general
284b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	 register is saved to a floating-point register.  */
285b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
286b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
287b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (*valp)
288b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    {
289fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      if (ia64_is_big_endian (c))
290b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		ret = ia64_putfp (c, reg_loc, unw.nat_val_be);
291b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      else
292b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		ret = ia64_putfp (c, reg_loc, unw.nat_val_le);
293b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    }
294b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  else
295b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    {
296fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      unw_word_t *src, *dst;
297b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      unw_fpreg_t tmp;
298b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
299b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      ret = ia64_getfp (c, reg_loc, &tmp);
300b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      if (ret < 0)
301b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		return ret;
302b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
303b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      /* Reset the exponent to 0x1003e so that the significand
304b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		 will be interpreted as an integer value.  */
305fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      src = (unw_word_t *) &unw.int_val_be;
306fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      dst = (unw_word_t *) &tmp;
307fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      if (!ia64_is_big_endian (c))
308fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm		++src, ++dst;
309fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	      *dst = *src;
310b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
311b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	      ret = ia64_putfp (c, reg_loc, tmp);
312b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    }
313b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
314b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
315b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
316b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  ret = ia64_getfp (c, reg_loc, &tmp);
317b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (ret < 0)
318b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    return ret;
319b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
320fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm	  if (ia64_is_big_endian (c))
321b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    *valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0);
322b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  else
323b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    *valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0);
324b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
325b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return ret;
326b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
327b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
328b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if ((IA64_IS_REG_LOC (nat_loc)
329b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm       && (unsigned) (IA64_GET_REG (nat_loc) - UNW_IA64_NAT) < 128)
330b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      || IA64_IS_UC_LOC (reg_loc))
331b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
332b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
333b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return ia64_put (c, nat_loc, *valp);
334b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
335b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return ia64_get (c, nat_loc, valp);
336b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
337b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
338b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (IA64_IS_NULL_LOC (nat_loc))
339b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
340b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      /* NaT bit is not saved. This happens if a general register is
341b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	 saved to a branch register.  Since the NaT bit gets lost, we
342b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	 need to drop it here, too.  Note that if the NaT bit had been
343b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	 set when the save occurred, it would have caused a NaT
344b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	 consumption fault.  */
345b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
346b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
347b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (*valp)
348b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    return -UNW_EBADREG;	/* can't set NaT bit */
349b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
350b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
351b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	*valp = 0;
352b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
353b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
354b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
355b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  mask = (unw_word_t) 1 << nat_bitnr;
356b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  return update_nat (c, nat_loc, mask, valp, write);
357b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
358b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
359b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN int
360b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmtdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
361b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		 int write)
362b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
363b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  ia64_loc_t loc, reg_loc, nat_loc;
364cf2a44ca4934c5c5a91959240d48b37937730c4bhp.com!davidm  unw_word_t mask, val;
365b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  uint8_t nat_bitnr;
366399f120c96dca0ec383e265888d826d8b75d5d0fhp.com!davidm  int ret;
367b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
368b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  switch (reg)
369b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
370b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      /* frame registers: */
371b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
372b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BSP:
373b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
37436a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm	c->bsp = *valp;
37536a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm      else
37636a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm	*valp = c->bsp;
377b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
378b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
379b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_REG_SP:
380b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
38136a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm	c->sp = *valp;
38236a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm      else
38336a0275014ed7d918cb64db26220668d2034b4dahp.com!davidm	*valp = c->sp;
384b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
385b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
386b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_REG_IP:
387b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
388b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
389b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  c->ip = *valp;	/* also update the IP cache */
390b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  if (c->pi_valid && (*valp < c->pi.start_ip || *valp >= c->pi.end_ip))
391b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    c->pi_valid = 0;	/* new IP outside of current proc */
392b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
393b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = c->loc[IA64_REG_IP];
394b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
395b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
396b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      /* preserved registers: */
397b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
398b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7:
399b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))];
400b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
401b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
402b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7:
403b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))];
404b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))];
405b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)];
406b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return access_nat (c, loc, reg_loc, nat_bitnr, valp, write);
407b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
408b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_BSP:	loc = c->loc[IA64_REG_BSP]; break;
409b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_BSPSTORE:	loc = c->loc[IA64_REG_BSPSTORE]; break;
410b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_PFS:	loc = c->loc[IA64_REG_PFS]; break;
411b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_RNAT:	loc = c->loc[IA64_REG_RNAT]; break;
412b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_UNAT:	loc = c->loc[IA64_REG_UNAT]; break;
413b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_LC:	loc = c->loc[IA64_REG_LC]; break;
414b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_FPSR:	loc = c->loc[IA64_REG_FPSR]; break;
415b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 1:	loc = c->loc[IA64_REG_B1]; break;
416b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 2:	loc = c->loc[IA64_REG_B2]; break;
417b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 3:	loc = c->loc[IA64_REG_B3]; break;
418b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 4:	loc = c->loc[IA64_REG_B4]; break;
419b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 5:	loc = c->loc[IA64_REG_B5]; break;
420b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
421b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_CFM:
422b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
423b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	c->cfm = *valp;	/* also update the CFM cache */
424b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = c->cfm_loc;
425b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
426b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
427b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_PR:
428a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm      /*
429a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm       * Note: broad-side access to the predicates is NOT rotated
430a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm       * (i.e., it is done as if CFM.rrb.pr == 0.
431a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm       */
432b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
433b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
434b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  c->pr = *valp;		/* update the predicate cache */
435a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm	  return ia64_put (c, c->loc[IA64_REG_PR], *valp);
436b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
437b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
438a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm	return ia64_get (c, c->loc[IA64_REG_PR], valp);
439b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
440b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127:	/* stacked reg */
441b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      reg = rotate_gr (c, reg - UNW_IA64_GR);
442b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (reg < 0)
443b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EBADREG;
444b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      ret = ia64_get_stacked (c, reg, &loc, NULL);
445b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (ret < 0)
446b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return ret;
447b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
448b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
449b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127:	/* stacked reg */
450b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      reg = rotate_gr (c, reg - UNW_IA64_NAT);
451b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (reg < 0)
452b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EBADREG;
453b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      ret = ia64_get_stacked (c, reg, &loc, &nat_loc);
454b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (ret < 0)
455b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return ret;
456b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      assert (!IA64_IS_REG_LOC (loc));
4573e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm      mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc));
458b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return update_nat (c, nat_loc, mask, valp, write);
459b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
460b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_EC:
4618a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm      if ((ret = ia64_get (c, c->ec_loc, &val)) < 0)
4628a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm	return ret;
4638a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm
464b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
465b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
4668a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm	  val = ((val & ~((unw_word_t) 0x3f << 52)) | ((*valp & 0x3f) << 52));
4678a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm	  return ia64_put (c, c->ec_loc, val);
468b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
469b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
470b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
4718a1e0a2bcd7c2d5bdd7afe7e8e3641719d1914adhp.com!davidm	  *valp = (val >> 52) & 0x3f;
472b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return 0;
473b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
474b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
475b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      /* scratch & special registers: */
476b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
477b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR + 0:
478b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
479b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EREADONLYREG;
480b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      *valp = 0;
481b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
482b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
483b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_NAT + 0:
484b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
485b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EREADONLYREG;
486b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      *valp = 0;
487b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
488b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
489f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm    case UNW_IA64_NAT + 1:
490b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3:
491b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31:
492b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = ia64_scratch_loc (c, reg, &nat_bitnr);
493f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm      if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_NAT + 1)
494f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	{
495f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  /* access to GP */
496f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  if (write)
497f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    return -UNW_EREADONLYREG;
498f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  *valp = 0;
499f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  return 0;
500f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	}
501b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc)
502b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	    || IA64_IS_FP_LOC (loc)))
503cf2a44ca4934c5c5a91959240d48b37937730c4bhp.com!davidm	/* We're dealing with a NaT bit stored in memory.  */
504cf2a44ca4934c5c5a91959240d48b37937730c4bhp.com!davidm	return update_nat(c, loc, (unw_word_t) 1 << nat_bitnr, valp, write);
505b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
506b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
507b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18:
508b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      mask = 1 << (reg - (UNW_IA64_GR + 15));
509b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
510b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
511b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp;
512b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  c->eh_valid_mask |= mask;
513b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return 0;
514b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
515b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else if ((c->eh_valid_mask & mask) != 0)
516b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	{
5173e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm	  *valp = c->eh_args[reg - (UNW_IA64_GR + 15)];
518b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	  return 0;
519b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	}
520b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
521b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	loc = ia64_scratch_loc (c, reg, NULL);
522b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
523b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
524f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm    case UNW_IA64_GR +  1:				/* global pointer */
525b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR +  2 ... UNW_IA64_GR + 3:
526b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR +  8 ... UNW_IA64_GR + 14:
527b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31:
528b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 0:
529b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 6:
530b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_BR + 7:
531b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_RSC:
532b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_CSD:
533b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_SSD:
534b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_AR_CCV:
535b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = ia64_scratch_loc (c, reg, NULL);
536f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm      if (IA64_IS_NULL_LOC (loc) && reg == UNW_IA64_GR + 1)
537f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	{
538f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  /* access to GP */
539f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  if (write)
540f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    return -UNW_EREADONLYREG;
541f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm
542f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  /* ensure c->pi is up-to-date: */
543f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  if ((ret = ia64_make_proc_info (c)) < 0)
544f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	    return ret;
545f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  *valp = c->pi.gp;
546f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	  return 0;
547f5de64f9f7637d43fc473f9b301ce69278b04952hp.com!davidm	}
548b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
549b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
550b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    default:
551b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      Debug (1, "bad register number %d\n", reg);
552b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return -UNW_EBADREG;
553b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
554b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
555b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (write)
556399f120c96dca0ec383e265888d826d8b75d5d0fhp.com!davidm    return ia64_put (c, loc, *valp);
557b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  else
558b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    return ia64_get (c, loc, valp);
559b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
560b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
561b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN int
562b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmtdep_access_fpreg (struct cursor *c, int reg, unw_fpreg_t *valp,
563b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm		   int write)
564b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{
565b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  ia64_loc_t loc;
566b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
567b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  switch (reg)
568b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    {
569b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 0:
570b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
571b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EREADONLYREG;
572b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      *valp = unw.read_only.f0;
573b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
574b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
575b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 1:
576b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      if (write)
577b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	return -UNW_EREADONLYREG;
578b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
579fa2871946af3c3d696efacbbc529d834020d8b67hp.com!davidm      if (ia64_is_big_endian (c))
580b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	*valp = unw.read_only.f1_be;
581b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      else
582b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm	*valp = unw.read_only.f1_le;
583b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return 0;
584b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
585b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break;
586b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break;
587b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break;
588b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break;
589b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
590b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31:
591b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))];
592b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
593b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
594b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15:
595b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = ia64_scratch_loc (c, reg, NULL);
596b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
597b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
598b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127:
599b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR;
600b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      loc = ia64_scratch_loc (c, reg, NULL);
601b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      break;
602b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
603b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    default:
604b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      Debug (1, "bad register number %d\n", reg);
605b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm      return -UNW_EBADREG;
606b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    }
607b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm
608b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  if (write)
609b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    return ia64_putfp (c, loc, *valp);
610b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm  else
611b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm    return ia64_getfp (c, loc, valp);
612b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm}
613