xref: /openbsd-src/gnu/usr.bin/binutils/gdb/ia64-tdep.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Target-dependent code for the IA-64 for GDB, the GNU debugger.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4b725ae77Skettenis    Foundation, Inc.
5b725ae77Skettenis 
6b725ae77Skettenis    This file is part of GDB.
7b725ae77Skettenis 
8b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis    it under the terms of the GNU General Public License as published by
10b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis    (at your option) any later version.
12b725ae77Skettenis 
13b725ae77Skettenis    This program is distributed in the hope that it will be useful,
14b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16b725ae77Skettenis    GNU General Public License for more details.
17b725ae77Skettenis 
18b725ae77Skettenis    You should have received a copy of the GNU General Public License
19b725ae77Skettenis    along with this program; if not, write to the Free Software
20b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
22b725ae77Skettenis 
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "inferior.h"
25b725ae77Skettenis #include "gdbcore.h"
26b725ae77Skettenis #include "arch-utils.h"
27b725ae77Skettenis #include "floatformat.h"
28b725ae77Skettenis #include "regcache.h"
29b725ae77Skettenis #include "reggroups.h"
30b725ae77Skettenis #include "frame.h"
31b725ae77Skettenis #include "frame-base.h"
32b725ae77Skettenis #include "frame-unwind.h"
33b725ae77Skettenis #include "doublest.h"
34b725ae77Skettenis #include "value.h"
35b725ae77Skettenis #include "gdb_assert.h"
36b725ae77Skettenis #include "objfiles.h"
37b725ae77Skettenis #include "elf/common.h"		/* for DT_PLTGOT value */
38b725ae77Skettenis #include "elf-bfd.h"
39b725ae77Skettenis #include "dis-asm.h"
40*11efff7fSkettenis #include "infcall.h"
41b725ae77Skettenis #include "ia64-tdep.h"
42b725ae77Skettenis 
43b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
44*11efff7fSkettenis #include "elf/ia64.h"           /* for PT_IA_64_UNWIND value */
45b725ae77Skettenis #include "libunwind-frame.h"
46b725ae77Skettenis #include "libunwind-ia64.h"
47b725ae77Skettenis #endif
48b725ae77Skettenis 
49b725ae77Skettenis /* Hook for determining the global pointer when calling functions in
50b725ae77Skettenis    the inferior under AIX.  The initialization code in ia64-aix-nat.c
51b725ae77Skettenis    sets this hook to the address of a function which will find the
52b725ae77Skettenis    global pointer for a given address.
53b725ae77Skettenis 
54b725ae77Skettenis    The generic code which uses the dynamic section in the inferior for
55b725ae77Skettenis    finding the global pointer is not of much use on AIX since the
56b725ae77Skettenis    values obtained from the inferior have not been relocated.  */
57b725ae77Skettenis 
58b725ae77Skettenis CORE_ADDR (*native_find_global_pointer) (CORE_ADDR) = 0;
59b725ae77Skettenis 
60b725ae77Skettenis /* An enumeration of the different IA-64 instruction types.  */
61b725ae77Skettenis 
62b725ae77Skettenis typedef enum instruction_type
63b725ae77Skettenis {
64b725ae77Skettenis   A,			/* Integer ALU ;    I-unit or M-unit */
65b725ae77Skettenis   I,			/* Non-ALU integer; I-unit */
66b725ae77Skettenis   M,			/* Memory ;         M-unit */
67b725ae77Skettenis   F,			/* Floating-point ; F-unit */
68b725ae77Skettenis   B,			/* Branch ;         B-unit */
69b725ae77Skettenis   L,			/* Extended (L+X) ; I-unit */
70b725ae77Skettenis   X,			/* Extended (L+X) ; I-unit */
71b725ae77Skettenis   undefined		/* undefined or reserved */
72b725ae77Skettenis } instruction_type;
73b725ae77Skettenis 
74b725ae77Skettenis /* We represent IA-64 PC addresses as the value of the instruction
75b725ae77Skettenis    pointer or'd with some bit combination in the low nibble which
76b725ae77Skettenis    represents the slot number in the bundle addressed by the
77b725ae77Skettenis    instruction pointer.  The problem is that the Linux kernel
78b725ae77Skettenis    multiplies its slot numbers (for exceptions) by one while the
79b725ae77Skettenis    disassembler multiplies its slot numbers by 6.  In addition, I've
80b725ae77Skettenis    heard it said that the simulator uses 1 as the multiplier.
81b725ae77Skettenis 
82b725ae77Skettenis    I've fixed the disassembler so that the bytes_per_line field will
83b725ae77Skettenis    be the slot multiplier.  If bytes_per_line comes in as zero, it
84b725ae77Skettenis    is set to six (which is how it was set up initially). -- objdump
85b725ae77Skettenis    displays pretty disassembly dumps with this value.  For our purposes,
86b725ae77Skettenis    we'll set bytes_per_line to SLOT_MULTIPLIER. This is okay since we
87b725ae77Skettenis    never want to also display the raw bytes the way objdump does. */
88b725ae77Skettenis 
89b725ae77Skettenis #define SLOT_MULTIPLIER 1
90b725ae77Skettenis 
91b725ae77Skettenis /* Length in bytes of an instruction bundle */
92b725ae77Skettenis 
93b725ae77Skettenis #define BUNDLE_LEN 16
94b725ae77Skettenis 
95b725ae77Skettenis static gdbarch_init_ftype ia64_gdbarch_init;
96b725ae77Skettenis 
97b725ae77Skettenis static gdbarch_register_name_ftype ia64_register_name;
98b725ae77Skettenis static gdbarch_register_type_ftype ia64_register_type;
99b725ae77Skettenis static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
100b725ae77Skettenis static gdbarch_skip_prologue_ftype ia64_skip_prologue;
101b725ae77Skettenis static gdbarch_extract_return_value_ftype ia64_extract_return_value;
102b725ae77Skettenis static struct type *is_float_or_hfa_type (struct type *t);
103b725ae77Skettenis 
104b725ae77Skettenis static struct type *builtin_type_ia64_ext;
105b725ae77Skettenis 
106b725ae77Skettenis #define NUM_IA64_RAW_REGS 462
107b725ae77Skettenis 
108b725ae77Skettenis static int sp_regnum = IA64_GR12_REGNUM;
109b725ae77Skettenis static int fp_regnum = IA64_VFP_REGNUM;
110b725ae77Skettenis static int lr_regnum = IA64_VRAP_REGNUM;
111b725ae77Skettenis 
112b725ae77Skettenis /* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because
113b725ae77Skettenis    they may not be accessible via the ptrace register get/set interfaces.  */
114b725ae77Skettenis enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM,
115b725ae77Skettenis 		   V127_REGNUM = V32_REGNUM + 95,
116b725ae77Skettenis 		   VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
117b725ae77Skettenis 
118b725ae77Skettenis /* Array of register names; There should be ia64_num_regs strings in
119b725ae77Skettenis    the initializer.  */
120b725ae77Skettenis 
121b725ae77Skettenis static char *ia64_register_names[] =
122b725ae77Skettenis { "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
123b725ae77Skettenis   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
124b725ae77Skettenis   "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",
125b725ae77Skettenis   "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",
126b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
127b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
128b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
129b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
130b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
131b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
132b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
133b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
134b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
135b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
136b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
137b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
138b725ae77Skettenis 
139b725ae77Skettenis   "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
140b725ae77Skettenis   "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
141b725ae77Skettenis   "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
142b725ae77Skettenis   "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
143b725ae77Skettenis   "f32",  "f33",  "f34",  "f35",  "f36",  "f37",  "f38",  "f39",
144b725ae77Skettenis   "f40",  "f41",  "f42",  "f43",  "f44",  "f45",  "f46",  "f47",
145b725ae77Skettenis   "f48",  "f49",  "f50",  "f51",  "f52",  "f53",  "f54",  "f55",
146b725ae77Skettenis   "f56",  "f57",  "f58",  "f59",  "f60",  "f61",  "f62",  "f63",
147b725ae77Skettenis   "f64",  "f65",  "f66",  "f67",  "f68",  "f69",  "f70",  "f71",
148b725ae77Skettenis   "f72",  "f73",  "f74",  "f75",  "f76",  "f77",  "f78",  "f79",
149b725ae77Skettenis   "f80",  "f81",  "f82",  "f83",  "f84",  "f85",  "f86",  "f87",
150b725ae77Skettenis   "f88",  "f89",  "f90",  "f91",  "f92",  "f93",  "f94",  "f95",
151b725ae77Skettenis   "f96",  "f97",  "f98",  "f99",  "f100", "f101", "f102", "f103",
152b725ae77Skettenis   "f104", "f105", "f106", "f107", "f108", "f109", "f110", "f111",
153b725ae77Skettenis   "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119",
154b725ae77Skettenis   "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127",
155b725ae77Skettenis 
156b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
157b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
158b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
159b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
160b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
161b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
162b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
163b725ae77Skettenis   "",     "",     "",     "",     "",     "",     "",     "",
164b725ae77Skettenis 
165b725ae77Skettenis   "b0",   "b1",   "b2",   "b3",   "b4",   "b5",   "b6",   "b7",
166b725ae77Skettenis 
167b725ae77Skettenis   "vfp", "vrap",
168b725ae77Skettenis 
169b725ae77Skettenis   "pr", "ip", "psr", "cfm",
170b725ae77Skettenis 
171b725ae77Skettenis   "kr0",   "kr1",   "kr2",   "kr3",   "kr4",   "kr5",   "kr6",   "kr7",
172b725ae77Skettenis   "", "", "", "", "", "", "", "",
173b725ae77Skettenis   "rsc", "bsp", "bspstore", "rnat",
174b725ae77Skettenis   "", "fcr", "", "",
175b725ae77Skettenis   "eflag", "csd", "ssd", "cflg", "fsr", "fir", "fdr",  "",
176b725ae77Skettenis   "ccv", "", "", "", "unat", "", "", "",
177b725ae77Skettenis   "fpsr", "", "", "", "itc",
178b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
179b725ae77Skettenis   "", "", "", "", "", "", "", "", "",
180b725ae77Skettenis   "pfs", "lc", "ec",
181b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
182b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
183b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
184b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
185b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
186b725ae77Skettenis   "", "", "", "", "", "", "", "", "", "",
187b725ae77Skettenis   "",
188b725ae77Skettenis   "nat0",  "nat1",  "nat2",  "nat3",  "nat4",  "nat5",  "nat6",  "nat7",
189b725ae77Skettenis   "nat8",  "nat9",  "nat10", "nat11", "nat12", "nat13", "nat14", "nat15",
190b725ae77Skettenis   "nat16", "nat17", "nat18", "nat19", "nat20", "nat21", "nat22", "nat23",
191b725ae77Skettenis   "nat24", "nat25", "nat26", "nat27", "nat28", "nat29", "nat30", "nat31",
192b725ae77Skettenis   "nat32", "nat33", "nat34", "nat35", "nat36", "nat37", "nat38", "nat39",
193b725ae77Skettenis   "nat40", "nat41", "nat42", "nat43", "nat44", "nat45", "nat46", "nat47",
194b725ae77Skettenis   "nat48", "nat49", "nat50", "nat51", "nat52", "nat53", "nat54", "nat55",
195b725ae77Skettenis   "nat56", "nat57", "nat58", "nat59", "nat60", "nat61", "nat62", "nat63",
196b725ae77Skettenis   "nat64", "nat65", "nat66", "nat67", "nat68", "nat69", "nat70", "nat71",
197b725ae77Skettenis   "nat72", "nat73", "nat74", "nat75", "nat76", "nat77", "nat78", "nat79",
198b725ae77Skettenis   "nat80", "nat81", "nat82", "nat83", "nat84", "nat85", "nat86", "nat87",
199b725ae77Skettenis   "nat88", "nat89", "nat90", "nat91", "nat92", "nat93", "nat94", "nat95",
200b725ae77Skettenis   "nat96", "nat97", "nat98", "nat99", "nat100","nat101","nat102","nat103",
201b725ae77Skettenis   "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111",
202b725ae77Skettenis   "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119",
203b725ae77Skettenis   "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127",
204b725ae77Skettenis 
205b725ae77Skettenis   "bof",
206b725ae77Skettenis 
207b725ae77Skettenis   "r32",  "r33",  "r34",  "r35",  "r36",  "r37",  "r38",  "r39",
208b725ae77Skettenis   "r40",  "r41",  "r42",  "r43",  "r44",  "r45",  "r46",  "r47",
209b725ae77Skettenis   "r48",  "r49",  "r50",  "r51",  "r52",  "r53",  "r54",  "r55",
210b725ae77Skettenis   "r56",  "r57",  "r58",  "r59",  "r60",  "r61",  "r62",  "r63",
211b725ae77Skettenis   "r64",  "r65",  "r66",  "r67",  "r68",  "r69",  "r70",  "r71",
212b725ae77Skettenis   "r72",  "r73",  "r74",  "r75",  "r76",  "r77",  "r78",  "r79",
213b725ae77Skettenis   "r80",  "r81",  "r82",  "r83",  "r84",  "r85",  "r86",  "r87",
214b725ae77Skettenis   "r88",  "r89",  "r90",  "r91",  "r92",  "r93",  "r94",  "r95",
215b725ae77Skettenis   "r96",  "r97",  "r98",  "r99",  "r100", "r101", "r102", "r103",
216b725ae77Skettenis   "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111",
217b725ae77Skettenis   "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119",
218b725ae77Skettenis   "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127",
219b725ae77Skettenis 
220b725ae77Skettenis   "p0",   "p1",   "p2",   "p3",   "p4",   "p5",   "p6",   "p7",
221b725ae77Skettenis   "p8",   "p9",   "p10",  "p11",  "p12",  "p13",  "p14",  "p15",
222b725ae77Skettenis   "p16",  "p17",  "p18",  "p19",  "p20",  "p21",  "p22",  "p23",
223b725ae77Skettenis   "p24",  "p25",  "p26",  "p27",  "p28",  "p29",  "p30",  "p31",
224b725ae77Skettenis   "p32",  "p33",  "p34",  "p35",  "p36",  "p37",  "p38",  "p39",
225b725ae77Skettenis   "p40",  "p41",  "p42",  "p43",  "p44",  "p45",  "p46",  "p47",
226b725ae77Skettenis   "p48",  "p49",  "p50",  "p51",  "p52",  "p53",  "p54",  "p55",
227b725ae77Skettenis   "p56",  "p57",  "p58",  "p59",  "p60",  "p61",  "p62",  "p63",
228b725ae77Skettenis };
229b725ae77Skettenis 
230b725ae77Skettenis struct ia64_frame_cache
231b725ae77Skettenis {
232b725ae77Skettenis   CORE_ADDR base;       /* frame pointer base for frame */
233b725ae77Skettenis   CORE_ADDR pc;		/* function start pc for frame */
234b725ae77Skettenis   CORE_ADDR saved_sp;	/* stack pointer for frame */
235b725ae77Skettenis   CORE_ADDR bsp;	/* points at r32 for the current frame */
236b725ae77Skettenis   CORE_ADDR cfm;	/* cfm value for current frame */
237b725ae77Skettenis   CORE_ADDR prev_cfm;   /* cfm value for previous frame */
238b725ae77Skettenis   int   frameless;
239b725ae77Skettenis   int   sof;		/* Size of frame  (decoded from cfm value) */
240b725ae77Skettenis   int	sol;		/* Size of locals (decoded from cfm value) */
241b725ae77Skettenis   int	sor;		/* Number of rotating registers. (decoded from cfm value) */
242b725ae77Skettenis   CORE_ADDR after_prologue;
243b725ae77Skettenis   /* Address of first instruction after the last
244b725ae77Skettenis      prologue instruction;  Note that there may
245b725ae77Skettenis      be instructions from the function's body
246b725ae77Skettenis      intermingled with the prologue. */
247b725ae77Skettenis   int mem_stack_frame_size;
248b725ae77Skettenis   /* Size of the memory stack frame (may be zero),
249b725ae77Skettenis      or -1 if it has not been determined yet. */
250b725ae77Skettenis   int	fp_reg;		/* Register number (if any) used a frame pointer
251b725ae77Skettenis 			   for this frame.  0 if no register is being used
252b725ae77Skettenis 			   as the frame pointer. */
253b725ae77Skettenis 
254b725ae77Skettenis   /* Saved registers.  */
255b725ae77Skettenis   CORE_ADDR saved_regs[NUM_IA64_RAW_REGS];
256b725ae77Skettenis 
257b725ae77Skettenis };
258b725ae77Skettenis 
259b725ae77Skettenis struct gdbarch_tdep
260b725ae77Skettenis   {
261b725ae77Skettenis     CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
262b725ae77Skettenis     			/* OS specific function which, given a frame address
263b725ae77Skettenis 			   and register number, returns the offset to the
264b725ae77Skettenis 			   given register from the start of the frame. */
265b725ae77Skettenis     CORE_ADDR (*find_global_pointer) (CORE_ADDR);
266b725ae77Skettenis   };
267b725ae77Skettenis 
268b725ae77Skettenis #define SIGCONTEXT_REGISTER_ADDRESS \
269b725ae77Skettenis   (gdbarch_tdep (current_gdbarch)->sigcontext_register_address)
270b725ae77Skettenis #define FIND_GLOBAL_POINTER \
271b725ae77Skettenis   (gdbarch_tdep (current_gdbarch)->find_global_pointer)
272b725ae77Skettenis 
273b725ae77Skettenis int
ia64_register_reggroup_p(struct gdbarch * gdbarch,int regnum,struct reggroup * group)274b725ae77Skettenis ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
275b725ae77Skettenis 			  struct reggroup *group)
276b725ae77Skettenis {
277b725ae77Skettenis   int vector_p;
278b725ae77Skettenis   int float_p;
279b725ae77Skettenis   int raw_p;
280b725ae77Skettenis   if (group == all_reggroup)
281b725ae77Skettenis     return 1;
282b725ae77Skettenis   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
283b725ae77Skettenis   float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
284b725ae77Skettenis   raw_p = regnum < NUM_IA64_RAW_REGS;
285b725ae77Skettenis   if (group == float_reggroup)
286b725ae77Skettenis     return float_p;
287b725ae77Skettenis   if (group == vector_reggroup)
288b725ae77Skettenis     return vector_p;
289b725ae77Skettenis   if (group == general_reggroup)
290b725ae77Skettenis     return (!vector_p && !float_p);
291b725ae77Skettenis   if (group == save_reggroup || group == restore_reggroup)
292b725ae77Skettenis     return raw_p;
293b725ae77Skettenis   return 0;
294b725ae77Skettenis }
295b725ae77Skettenis 
296b725ae77Skettenis static const char *
ia64_register_name(int reg)297b725ae77Skettenis ia64_register_name (int reg)
298b725ae77Skettenis {
299b725ae77Skettenis   return ia64_register_names[reg];
300b725ae77Skettenis }
301b725ae77Skettenis 
302b725ae77Skettenis struct type *
ia64_register_type(struct gdbarch * arch,int reg)303b725ae77Skettenis ia64_register_type (struct gdbarch *arch, int reg)
304b725ae77Skettenis {
305b725ae77Skettenis   if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
306b725ae77Skettenis     return builtin_type_ia64_ext;
307b725ae77Skettenis   else
308b725ae77Skettenis     return builtin_type_long;
309b725ae77Skettenis }
310b725ae77Skettenis 
311b725ae77Skettenis static int
ia64_dwarf_reg_to_regnum(int reg)312b725ae77Skettenis ia64_dwarf_reg_to_regnum (int reg)
313b725ae77Skettenis {
314b725ae77Skettenis   if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM)
315b725ae77Skettenis     return V32_REGNUM + (reg - IA64_GR32_REGNUM);
316b725ae77Skettenis   return reg;
317b725ae77Skettenis }
318b725ae77Skettenis 
319b725ae77Skettenis static int
floatformat_valid(const struct floatformat * fmt,const char * from)320b725ae77Skettenis floatformat_valid (const struct floatformat *fmt, const char *from)
321b725ae77Skettenis {
322b725ae77Skettenis   return 1;
323b725ae77Skettenis }
324b725ae77Skettenis 
325b725ae77Skettenis const struct floatformat floatformat_ia64_ext =
326b725ae77Skettenis {
327b725ae77Skettenis   floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
328b725ae77Skettenis   floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
329b725ae77Skettenis };
330b725ae77Skettenis 
331b725ae77Skettenis 
332b725ae77Skettenis /* Extract ``len'' bits from an instruction bundle starting at
333b725ae77Skettenis    bit ``from''.  */
334b725ae77Skettenis 
335b725ae77Skettenis static long long
extract_bit_field(char * bundle,int from,int len)336b725ae77Skettenis extract_bit_field (char *bundle, int from, int len)
337b725ae77Skettenis {
338b725ae77Skettenis   long long result = 0LL;
339b725ae77Skettenis   int to = from + len;
340b725ae77Skettenis   int from_byte = from / 8;
341b725ae77Skettenis   int to_byte = to / 8;
342b725ae77Skettenis   unsigned char *b = (unsigned char *) bundle;
343b725ae77Skettenis   unsigned char c;
344b725ae77Skettenis   int lshift;
345b725ae77Skettenis   int i;
346b725ae77Skettenis 
347b725ae77Skettenis   c = b[from_byte];
348b725ae77Skettenis   if (from_byte == to_byte)
349b725ae77Skettenis     c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
350b725ae77Skettenis   result = c >> (from % 8);
351b725ae77Skettenis   lshift = 8 - (from % 8);
352b725ae77Skettenis 
353b725ae77Skettenis   for (i = from_byte+1; i < to_byte; i++)
354b725ae77Skettenis     {
355b725ae77Skettenis       result |= ((long long) b[i]) << lshift;
356b725ae77Skettenis       lshift += 8;
357b725ae77Skettenis     }
358b725ae77Skettenis 
359b725ae77Skettenis   if (from_byte < to_byte && (to % 8 != 0))
360b725ae77Skettenis     {
361b725ae77Skettenis       c = b[to_byte];
362b725ae77Skettenis       c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
363b725ae77Skettenis       result |= ((long long) c) << lshift;
364b725ae77Skettenis     }
365b725ae77Skettenis 
366b725ae77Skettenis   return result;
367b725ae77Skettenis }
368b725ae77Skettenis 
369b725ae77Skettenis /* Replace the specified bits in an instruction bundle */
370b725ae77Skettenis 
371b725ae77Skettenis static void
replace_bit_field(char * bundle,long long val,int from,int len)372b725ae77Skettenis replace_bit_field (char *bundle, long long val, int from, int len)
373b725ae77Skettenis {
374b725ae77Skettenis   int to = from + len;
375b725ae77Skettenis   int from_byte = from / 8;
376b725ae77Skettenis   int to_byte = to / 8;
377b725ae77Skettenis   unsigned char *b = (unsigned char *) bundle;
378b725ae77Skettenis   unsigned char c;
379b725ae77Skettenis 
380b725ae77Skettenis   if (from_byte == to_byte)
381b725ae77Skettenis     {
382b725ae77Skettenis       unsigned char left, right;
383b725ae77Skettenis       c = b[from_byte];
384b725ae77Skettenis       left = (c >> (to % 8)) << (to % 8);
385b725ae77Skettenis       right = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
386b725ae77Skettenis       c = (unsigned char) (val & 0xff);
387b725ae77Skettenis       c = (unsigned char) (c << (from % 8 + 8 - to % 8)) >> (8 - to % 8);
388b725ae77Skettenis       c |= right | left;
389b725ae77Skettenis       b[from_byte] = c;
390b725ae77Skettenis     }
391b725ae77Skettenis   else
392b725ae77Skettenis     {
393b725ae77Skettenis       int i;
394b725ae77Skettenis       c = b[from_byte];
395b725ae77Skettenis       c = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
396b725ae77Skettenis       c = c | (val << (from % 8));
397b725ae77Skettenis       b[from_byte] = c;
398b725ae77Skettenis       val >>= 8 - from % 8;
399b725ae77Skettenis 
400b725ae77Skettenis       for (i = from_byte+1; i < to_byte; i++)
401b725ae77Skettenis 	{
402b725ae77Skettenis 	  c = val & 0xff;
403b725ae77Skettenis 	  val >>= 8;
404b725ae77Skettenis 	  b[i] = c;
405b725ae77Skettenis 	}
406b725ae77Skettenis 
407b725ae77Skettenis       if (to % 8 != 0)
408b725ae77Skettenis 	{
409b725ae77Skettenis 	  unsigned char cv = (unsigned char) val;
410b725ae77Skettenis 	  c = b[to_byte];
411b725ae77Skettenis 	  c = c >> (to % 8) << (to % 8);
412b725ae77Skettenis 	  c |= ((unsigned char) (cv << (8 - to % 8))) >> (8 - to % 8);
413b725ae77Skettenis 	  b[to_byte] = c;
414b725ae77Skettenis 	}
415b725ae77Skettenis     }
416b725ae77Skettenis }
417b725ae77Skettenis 
418b725ae77Skettenis /* Return the contents of slot N (for N = 0, 1, or 2) in
419b725ae77Skettenis    and instruction bundle */
420b725ae77Skettenis 
421b725ae77Skettenis static long long
slotN_contents(char * bundle,int slotnum)422b725ae77Skettenis slotN_contents (char *bundle, int slotnum)
423b725ae77Skettenis {
424b725ae77Skettenis   return extract_bit_field (bundle, 5+41*slotnum, 41);
425b725ae77Skettenis }
426b725ae77Skettenis 
427b725ae77Skettenis /* Store an instruction in an instruction bundle */
428b725ae77Skettenis 
429b725ae77Skettenis static void
replace_slotN_contents(char * bundle,long long instr,int slotnum)430b725ae77Skettenis replace_slotN_contents (char *bundle, long long instr, int slotnum)
431b725ae77Skettenis {
432b725ae77Skettenis   replace_bit_field (bundle, instr, 5+41*slotnum, 41);
433b725ae77Skettenis }
434b725ae77Skettenis 
435b725ae77Skettenis static enum instruction_type template_encoding_table[32][3] =
436b725ae77Skettenis {
437b725ae77Skettenis   { M, I, I },				/* 00 */
438b725ae77Skettenis   { M, I, I },				/* 01 */
439b725ae77Skettenis   { M, I, I },				/* 02 */
440b725ae77Skettenis   { M, I, I },				/* 03 */
441b725ae77Skettenis   { M, L, X },				/* 04 */
442b725ae77Skettenis   { M, L, X },				/* 05 */
443b725ae77Skettenis   { undefined, undefined, undefined },  /* 06 */
444b725ae77Skettenis   { undefined, undefined, undefined },  /* 07 */
445b725ae77Skettenis   { M, M, I },				/* 08 */
446b725ae77Skettenis   { M, M, I },				/* 09 */
447b725ae77Skettenis   { M, M, I },				/* 0A */
448b725ae77Skettenis   { M, M, I },				/* 0B */
449b725ae77Skettenis   { M, F, I },				/* 0C */
450b725ae77Skettenis   { M, F, I },				/* 0D */
451b725ae77Skettenis   { M, M, F },				/* 0E */
452b725ae77Skettenis   { M, M, F },				/* 0F */
453b725ae77Skettenis   { M, I, B },				/* 10 */
454b725ae77Skettenis   { M, I, B },				/* 11 */
455b725ae77Skettenis   { M, B, B },				/* 12 */
456b725ae77Skettenis   { M, B, B },				/* 13 */
457b725ae77Skettenis   { undefined, undefined, undefined },  /* 14 */
458b725ae77Skettenis   { undefined, undefined, undefined },  /* 15 */
459b725ae77Skettenis   { B, B, B },				/* 16 */
460b725ae77Skettenis   { B, B, B },				/* 17 */
461b725ae77Skettenis   { M, M, B },				/* 18 */
462b725ae77Skettenis   { M, M, B },				/* 19 */
463b725ae77Skettenis   { undefined, undefined, undefined },  /* 1A */
464b725ae77Skettenis   { undefined, undefined, undefined },  /* 1B */
465b725ae77Skettenis   { M, F, B },				/* 1C */
466b725ae77Skettenis   { M, F, B },				/* 1D */
467b725ae77Skettenis   { undefined, undefined, undefined },  /* 1E */
468b725ae77Skettenis   { undefined, undefined, undefined },  /* 1F */
469b725ae77Skettenis };
470b725ae77Skettenis 
471b725ae77Skettenis /* Fetch and (partially) decode an instruction at ADDR and return the
472b725ae77Skettenis    address of the next instruction to fetch.  */
473b725ae77Skettenis 
474b725ae77Skettenis static CORE_ADDR
fetch_instruction(CORE_ADDR addr,instruction_type * it,long long * instr)475b725ae77Skettenis fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
476b725ae77Skettenis {
477b725ae77Skettenis   char bundle[BUNDLE_LEN];
478b725ae77Skettenis   int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
479b725ae77Skettenis   long long template;
480b725ae77Skettenis   int val;
481b725ae77Skettenis 
482b725ae77Skettenis   /* Warn about slot numbers greater than 2.  We used to generate
483b725ae77Skettenis      an error here on the assumption that the user entered an invalid
484b725ae77Skettenis      address.  But, sometimes GDB itself requests an invalid address.
485b725ae77Skettenis      This can (easily) happen when execution stops in a function for
486b725ae77Skettenis      which there are no symbols.  The prologue scanner will attempt to
487b725ae77Skettenis      find the beginning of the function - if the nearest symbol
488b725ae77Skettenis      happens to not be aligned on a bundle boundary (16 bytes), the
489b725ae77Skettenis      resulting starting address will cause GDB to think that the slot
490b725ae77Skettenis      number is too large.
491b725ae77Skettenis 
492b725ae77Skettenis      So we warn about it and set the slot number to zero.  It is
493b725ae77Skettenis      not necessarily a fatal condition, particularly if debugging
494b725ae77Skettenis      at the assembly language level.  */
495b725ae77Skettenis   if (slotnum > 2)
496b725ae77Skettenis     {
497b725ae77Skettenis       warning ("Can't fetch instructions for slot numbers greater than 2.\n"
498b725ae77Skettenis 	       "Using slot 0 instead");
499b725ae77Skettenis       slotnum = 0;
500b725ae77Skettenis     }
501b725ae77Skettenis 
502b725ae77Skettenis   addr &= ~0x0f;
503b725ae77Skettenis 
504b725ae77Skettenis   val = target_read_memory (addr, bundle, BUNDLE_LEN);
505b725ae77Skettenis 
506b725ae77Skettenis   if (val != 0)
507b725ae77Skettenis     return 0;
508b725ae77Skettenis 
509b725ae77Skettenis   *instr = slotN_contents (bundle, slotnum);
510b725ae77Skettenis   template = extract_bit_field (bundle, 0, 5);
511b725ae77Skettenis   *it = template_encoding_table[(int)template][slotnum];
512b725ae77Skettenis 
513b725ae77Skettenis   if (slotnum == 2 || (slotnum == 1 && *it == L))
514b725ae77Skettenis     addr += 16;
515b725ae77Skettenis   else
516b725ae77Skettenis     addr += (slotnum + 1) * SLOT_MULTIPLIER;
517b725ae77Skettenis 
518b725ae77Skettenis   return addr;
519b725ae77Skettenis }
520b725ae77Skettenis 
521b725ae77Skettenis /* There are 5 different break instructions (break.i, break.b,
522b725ae77Skettenis    break.m, break.f, and break.x), but they all have the same
523b725ae77Skettenis    encoding.  (The five bit template in the low five bits of the
524b725ae77Skettenis    instruction bundle distinguishes one from another.)
525b725ae77Skettenis 
526b725ae77Skettenis    The runtime architecture manual specifies that break instructions
527b725ae77Skettenis    used for debugging purposes must have the upper two bits of the 21
528b725ae77Skettenis    bit immediate set to a 0 and a 1 respectively.  A breakpoint
529b725ae77Skettenis    instruction encodes the most significant bit of its 21 bit
530b725ae77Skettenis    immediate at bit 36 of the 41 bit instruction.  The penultimate msb
531b725ae77Skettenis    is at bit 25 which leads to the pattern below.
532b725ae77Skettenis 
533b725ae77Skettenis    Originally, I had this set up to do, e.g, a "break.i 0x80000"  But
534b725ae77Skettenis    it turns out that 0x80000 was used as the syscall break in the early
535b725ae77Skettenis    simulators.  So I changed the pattern slightly to do "break.i 0x080001"
536b725ae77Skettenis    instead.  But that didn't work either (I later found out that this
537b725ae77Skettenis    pattern was used by the simulator that I was using.)  So I ended up
538b725ae77Skettenis    using the pattern seen below. */
539b725ae77Skettenis 
540b725ae77Skettenis #if 0
541b725ae77Skettenis #define IA64_BREAKPOINT 0x00002000040LL
542b725ae77Skettenis #endif
543b725ae77Skettenis #define IA64_BREAKPOINT 0x00003333300LL
544b725ae77Skettenis 
545b725ae77Skettenis static int
ia64_memory_insert_breakpoint(CORE_ADDR addr,char * contents_cache)546b725ae77Skettenis ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
547b725ae77Skettenis {
548b725ae77Skettenis   char bundle[BUNDLE_LEN];
549b725ae77Skettenis   int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
550b725ae77Skettenis   long long instr;
551b725ae77Skettenis   int val;
552b725ae77Skettenis   int template;
553b725ae77Skettenis 
554b725ae77Skettenis   if (slotnum > 2)
555b725ae77Skettenis     error("Can't insert breakpoint for slot numbers greater than 2.");
556b725ae77Skettenis 
557b725ae77Skettenis   addr &= ~0x0f;
558b725ae77Skettenis 
559b725ae77Skettenis   val = target_read_memory (addr, bundle, BUNDLE_LEN);
560b725ae77Skettenis 
561b725ae77Skettenis   /* Check for L type instruction in 2nd slot, if present then
562b725ae77Skettenis      bump up the slot number to the 3rd slot */
563b725ae77Skettenis   template = extract_bit_field (bundle, 0, 5);
564b725ae77Skettenis   if (slotnum == 1 && template_encoding_table[template][1] == L)
565b725ae77Skettenis     {
566b725ae77Skettenis       slotnum = 2;
567b725ae77Skettenis     }
568b725ae77Skettenis 
569b725ae77Skettenis   instr = slotN_contents (bundle, slotnum);
570b725ae77Skettenis   memcpy(contents_cache, &instr, sizeof(instr));
571b725ae77Skettenis   replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
572b725ae77Skettenis   if (val == 0)
573b725ae77Skettenis     target_write_memory (addr, bundle, BUNDLE_LEN);
574b725ae77Skettenis 
575b725ae77Skettenis   return val;
576b725ae77Skettenis }
577b725ae77Skettenis 
578b725ae77Skettenis static int
ia64_memory_remove_breakpoint(CORE_ADDR addr,char * contents_cache)579b725ae77Skettenis ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
580b725ae77Skettenis {
581b725ae77Skettenis   char bundle[BUNDLE_LEN];
582b725ae77Skettenis   int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
583b725ae77Skettenis   long long instr;
584b725ae77Skettenis   int val;
585b725ae77Skettenis   int template;
586b725ae77Skettenis 
587b725ae77Skettenis   addr &= ~0x0f;
588b725ae77Skettenis 
589b725ae77Skettenis   val = target_read_memory (addr, bundle, BUNDLE_LEN);
590b725ae77Skettenis 
591b725ae77Skettenis   /* Check for L type instruction in 2nd slot, if present then
592b725ae77Skettenis      bump up the slot number to the 3rd slot */
593b725ae77Skettenis   template = extract_bit_field (bundle, 0, 5);
594b725ae77Skettenis   if (slotnum == 1 && template_encoding_table[template][1] == L)
595b725ae77Skettenis     {
596b725ae77Skettenis       slotnum = 2;
597b725ae77Skettenis     }
598b725ae77Skettenis 
599b725ae77Skettenis   memcpy (&instr, contents_cache, sizeof instr);
600b725ae77Skettenis   replace_slotN_contents (bundle, instr, slotnum);
601b725ae77Skettenis   if (val == 0)
602b725ae77Skettenis     target_write_memory (addr, bundle, BUNDLE_LEN);
603b725ae77Skettenis 
604b725ae77Skettenis   return val;
605b725ae77Skettenis }
606b725ae77Skettenis 
607b725ae77Skettenis /* We don't really want to use this, but remote.c needs to call it in order
608b725ae77Skettenis    to figure out if Z-packets are supported or not.  Oh, well. */
609b725ae77Skettenis const unsigned char *
ia64_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)610b725ae77Skettenis ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
611b725ae77Skettenis {
612b725ae77Skettenis   static unsigned char breakpoint[] =
613b725ae77Skettenis     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
614b725ae77Skettenis   *lenptr = sizeof (breakpoint);
615b725ae77Skettenis #if 0
616b725ae77Skettenis   *pcptr &= ~0x0f;
617b725ae77Skettenis #endif
618b725ae77Skettenis   return breakpoint;
619b725ae77Skettenis }
620b725ae77Skettenis 
621b725ae77Skettenis static CORE_ADDR
ia64_read_pc(ptid_t ptid)622b725ae77Skettenis ia64_read_pc (ptid_t ptid)
623b725ae77Skettenis {
624b725ae77Skettenis   CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
625b725ae77Skettenis   CORE_ADDR pc_value   = read_register_pid (IA64_IP_REGNUM, ptid);
626b725ae77Skettenis   int slot_num = (psr_value >> 41) & 3;
627b725ae77Skettenis 
628b725ae77Skettenis   return pc_value | (slot_num * SLOT_MULTIPLIER);
629b725ae77Skettenis }
630b725ae77Skettenis 
631b725ae77Skettenis void
ia64_write_pc(CORE_ADDR new_pc,ptid_t ptid)632b725ae77Skettenis ia64_write_pc (CORE_ADDR new_pc, ptid_t ptid)
633b725ae77Skettenis {
634b725ae77Skettenis   int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
635b725ae77Skettenis   CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
636b725ae77Skettenis   psr_value &= ~(3LL << 41);
637b725ae77Skettenis   psr_value |= (CORE_ADDR)(slot_num & 0x3) << 41;
638b725ae77Skettenis 
639b725ae77Skettenis   new_pc &= ~0xfLL;
640b725ae77Skettenis 
641b725ae77Skettenis   write_register_pid (IA64_PSR_REGNUM, psr_value, ptid);
642b725ae77Skettenis   write_register_pid (IA64_IP_REGNUM, new_pc, ptid);
643b725ae77Skettenis }
644b725ae77Skettenis 
645b725ae77Skettenis #define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
646b725ae77Skettenis 
647b725ae77Skettenis /* Returns the address of the slot that's NSLOTS slots away from
648b725ae77Skettenis    the address ADDR. NSLOTS may be positive or negative. */
649b725ae77Skettenis static CORE_ADDR
rse_address_add(CORE_ADDR addr,int nslots)650b725ae77Skettenis rse_address_add(CORE_ADDR addr, int nslots)
651b725ae77Skettenis {
652b725ae77Skettenis   CORE_ADDR new_addr;
653b725ae77Skettenis   int mandatory_nat_slots = nslots / 63;
654b725ae77Skettenis   int direction = nslots < 0 ? -1 : 1;
655b725ae77Skettenis 
656b725ae77Skettenis   new_addr = addr + 8 * (nslots + mandatory_nat_slots);
657b725ae77Skettenis 
658b725ae77Skettenis   if ((new_addr >> 9)  != ((addr + 8 * 64 * mandatory_nat_slots) >> 9))
659b725ae77Skettenis     new_addr += 8 * direction;
660b725ae77Skettenis 
661b725ae77Skettenis   if (IS_NaT_COLLECTION_ADDR(new_addr))
662b725ae77Skettenis     new_addr += 8 * direction;
663b725ae77Skettenis 
664b725ae77Skettenis   return new_addr;
665b725ae77Skettenis }
666b725ae77Skettenis 
667b725ae77Skettenis static void
ia64_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,void * buf)668b725ae77Skettenis ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
669b725ae77Skettenis                            int regnum, void *buf)
670b725ae77Skettenis {
671b725ae77Skettenis   if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
672b725ae77Skettenis     {
673b725ae77Skettenis       ULONGEST bsp;
674b725ae77Skettenis       ULONGEST cfm;
675b725ae77Skettenis       CORE_ADDR reg;
676b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
677b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
678b725ae77Skettenis 
679b725ae77Skettenis       /* The bsp points at the end of the register frame so we
680b725ae77Skettenis 	 subtract the size of frame from it to get start of register frame.  */
681b725ae77Skettenis       bsp = rse_address_add (bsp, -(cfm & 0x7f));
682b725ae77Skettenis 
683b725ae77Skettenis       if ((cfm & 0x7f) > regnum - V32_REGNUM)
684b725ae77Skettenis 	{
685b725ae77Skettenis 	  ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
686b725ae77Skettenis 	  reg = read_memory_integer ((CORE_ADDR)reg_addr, 8);
687b725ae77Skettenis 	  store_unsigned_integer (buf, register_size (current_gdbarch, regnum), reg);
688b725ae77Skettenis 	}
689b725ae77Skettenis       else
690b725ae77Skettenis 	store_unsigned_integer (buf, register_size (current_gdbarch, regnum), 0);
691b725ae77Skettenis     }
692b725ae77Skettenis   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
693b725ae77Skettenis     {
694b725ae77Skettenis       ULONGEST unatN_val;
695b725ae77Skettenis       ULONGEST unat;
696b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
697b725ae77Skettenis       unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
698b725ae77Skettenis       store_unsigned_integer (buf, register_size (current_gdbarch, regnum), unatN_val);
699b725ae77Skettenis     }
700b725ae77Skettenis   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
701b725ae77Skettenis     {
702b725ae77Skettenis       ULONGEST natN_val = 0;
703b725ae77Skettenis       ULONGEST bsp;
704b725ae77Skettenis       ULONGEST cfm;
705b725ae77Skettenis       CORE_ADDR gr_addr = 0;
706b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
707b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
708b725ae77Skettenis 
709b725ae77Skettenis       /* The bsp points at the end of the register frame so we
710b725ae77Skettenis 	 subtract the size of frame from it to get start of register frame.  */
711b725ae77Skettenis       bsp = rse_address_add (bsp, -(cfm & 0x7f));
712b725ae77Skettenis 
713b725ae77Skettenis       if ((cfm & 0x7f) > regnum - V32_REGNUM)
714b725ae77Skettenis 	gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
715b725ae77Skettenis 
716b725ae77Skettenis       if (gr_addr != 0)
717b725ae77Skettenis 	{
718b725ae77Skettenis 	  /* Compute address of nat collection bits.  */
719b725ae77Skettenis 	  CORE_ADDR nat_addr = gr_addr | 0x1f8;
720b725ae77Skettenis 	  CORE_ADDR nat_collection;
721b725ae77Skettenis 	  int nat_bit;
722b725ae77Skettenis 	  /* If our nat collection address is bigger than bsp, we have to get
723b725ae77Skettenis 	     the nat collection from rnat.  Otherwise, we fetch the nat
724b725ae77Skettenis 	     collection from the computed address.  */
725b725ae77Skettenis 	  if (nat_addr >= bsp)
726b725ae77Skettenis 	    regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
727b725ae77Skettenis 	  else
728b725ae77Skettenis 	    nat_collection = read_memory_integer (nat_addr, 8);
729b725ae77Skettenis 	  nat_bit = (gr_addr >> 3) & 0x3f;
730b725ae77Skettenis 	  natN_val = (nat_collection >> nat_bit) & 1;
731b725ae77Skettenis 	}
732b725ae77Skettenis 
733b725ae77Skettenis       store_unsigned_integer (buf, register_size (current_gdbarch, regnum), natN_val);
734b725ae77Skettenis     }
735b725ae77Skettenis   else if (regnum == VBOF_REGNUM)
736b725ae77Skettenis     {
737b725ae77Skettenis       /* A virtual register frame start is provided for user convenience.
738b725ae77Skettenis          It can be calculated as the bsp - sof (sizeof frame). */
739b725ae77Skettenis       ULONGEST bsp, vbsp;
740b725ae77Skettenis       ULONGEST cfm;
741b725ae77Skettenis       CORE_ADDR reg;
742b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
743b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
744b725ae77Skettenis 
745b725ae77Skettenis       /* The bsp points at the end of the register frame so we
746b725ae77Skettenis 	 subtract the size of frame from it to get beginning of frame.  */
747b725ae77Skettenis       vbsp = rse_address_add (bsp, -(cfm & 0x7f));
748b725ae77Skettenis       store_unsigned_integer (buf, register_size (current_gdbarch, regnum), vbsp);
749b725ae77Skettenis     }
750b725ae77Skettenis   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
751b725ae77Skettenis     {
752b725ae77Skettenis       ULONGEST pr;
753b725ae77Skettenis       ULONGEST cfm;
754b725ae77Skettenis       ULONGEST prN_val;
755b725ae77Skettenis       CORE_ADDR reg;
756b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
757b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
758b725ae77Skettenis 
759b725ae77Skettenis       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
760b725ae77Skettenis 	{
761b725ae77Skettenis 	  /* Fetch predicate register rename base from current frame
762b725ae77Skettenis 	     marker for this frame. */
763b725ae77Skettenis 	  int rrb_pr = (cfm >> 32) & 0x3f;
764b725ae77Skettenis 
765b725ae77Skettenis 	  /* Adjust the register number to account for register rotation. */
766b725ae77Skettenis 	  regnum = VP16_REGNUM
767b725ae77Skettenis 	         + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
768b725ae77Skettenis 	}
769b725ae77Skettenis       prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
770b725ae77Skettenis       store_unsigned_integer (buf, register_size (current_gdbarch, regnum), prN_val);
771b725ae77Skettenis     }
772b725ae77Skettenis   else
773b725ae77Skettenis     memset (buf, 0, register_size (current_gdbarch, regnum));
774b725ae77Skettenis }
775b725ae77Skettenis 
776b725ae77Skettenis static void
ia64_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,const void * buf)777b725ae77Skettenis ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
778b725ae77Skettenis 			    int regnum, const void *buf)
779b725ae77Skettenis {
780b725ae77Skettenis   if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
781b725ae77Skettenis     {
782b725ae77Skettenis       ULONGEST bsp;
783b725ae77Skettenis       ULONGEST cfm;
784b725ae77Skettenis       CORE_ADDR reg;
785b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
786b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
787b725ae77Skettenis 
788b725ae77Skettenis       bsp = rse_address_add (bsp, -(cfm & 0x7f));
789b725ae77Skettenis 
790b725ae77Skettenis       if ((cfm & 0x7f) > regnum - V32_REGNUM)
791b725ae77Skettenis 	{
792b725ae77Skettenis 	  ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
793b725ae77Skettenis 	  write_memory (reg_addr, (void *)buf, 8);
794b725ae77Skettenis 	}
795b725ae77Skettenis     }
796b725ae77Skettenis   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
797b725ae77Skettenis     {
798b725ae77Skettenis       ULONGEST unatN_val, unat, unatN_mask;
799b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
800b725ae77Skettenis       unatN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
801b725ae77Skettenis       unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
802b725ae77Skettenis       if (unatN_val == 0)
803b725ae77Skettenis 	unat &= ~unatN_mask;
804b725ae77Skettenis       else if (unatN_val == 1)
805b725ae77Skettenis 	unat |= unatN_mask;
806b725ae77Skettenis       regcache_cooked_write_unsigned (regcache, IA64_UNAT_REGNUM, unat);
807b725ae77Skettenis     }
808b725ae77Skettenis   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
809b725ae77Skettenis     {
810b725ae77Skettenis       ULONGEST natN_val;
811b725ae77Skettenis       ULONGEST bsp;
812b725ae77Skettenis       ULONGEST cfm;
813b725ae77Skettenis       CORE_ADDR gr_addr = 0;
814b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
815b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
816b725ae77Skettenis 
817b725ae77Skettenis       /* The bsp points at the end of the register frame so we
818b725ae77Skettenis 	 subtract the size of frame from it to get start of register frame.  */
819b725ae77Skettenis       bsp = rse_address_add (bsp, -(cfm & 0x7f));
820b725ae77Skettenis 
821b725ae77Skettenis       if ((cfm & 0x7f) > regnum - V32_REGNUM)
822b725ae77Skettenis 	gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
823b725ae77Skettenis 
824b725ae77Skettenis       natN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
825b725ae77Skettenis 
826b725ae77Skettenis       if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
827b725ae77Skettenis 	{
828b725ae77Skettenis 	  /* Compute address of nat collection bits.  */
829b725ae77Skettenis 	  CORE_ADDR nat_addr = gr_addr | 0x1f8;
830b725ae77Skettenis 	  CORE_ADDR nat_collection;
831b725ae77Skettenis 	  int natN_bit = (gr_addr >> 3) & 0x3f;
832b725ae77Skettenis 	  ULONGEST natN_mask = (1LL << natN_bit);
833b725ae77Skettenis 	  /* If our nat collection address is bigger than bsp, we have to get
834b725ae77Skettenis 	     the nat collection from rnat.  Otherwise, we fetch the nat
835b725ae77Skettenis 	     collection from the computed address.  */
836b725ae77Skettenis 	  if (nat_addr >= bsp)
837b725ae77Skettenis 	    {
838b725ae77Skettenis 	      regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
839b725ae77Skettenis 	      if (natN_val)
840b725ae77Skettenis 		nat_collection |= natN_mask;
841b725ae77Skettenis 	      else
842b725ae77Skettenis 		nat_collection &= ~natN_mask;
843b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM, nat_collection);
844b725ae77Skettenis 	    }
845b725ae77Skettenis 	  else
846b725ae77Skettenis 	    {
847b725ae77Skettenis 	      char nat_buf[8];
848b725ae77Skettenis 	      nat_collection = read_memory_integer (nat_addr, 8);
849b725ae77Skettenis 	      if (natN_val)
850b725ae77Skettenis 		nat_collection |= natN_mask;
851b725ae77Skettenis 	      else
852b725ae77Skettenis 		nat_collection &= ~natN_mask;
853b725ae77Skettenis 	      store_unsigned_integer (nat_buf, register_size (current_gdbarch, regnum), nat_collection);
854b725ae77Skettenis 	      write_memory (nat_addr, nat_buf, 8);
855b725ae77Skettenis 	    }
856b725ae77Skettenis 	}
857b725ae77Skettenis     }
858b725ae77Skettenis   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
859b725ae77Skettenis     {
860b725ae77Skettenis       ULONGEST pr;
861b725ae77Skettenis       ULONGEST cfm;
862b725ae77Skettenis       ULONGEST prN_val;
863b725ae77Skettenis       ULONGEST prN_mask;
864b725ae77Skettenis 
865b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
866b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
867b725ae77Skettenis 
868b725ae77Skettenis       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
869b725ae77Skettenis 	{
870b725ae77Skettenis 	  /* Fetch predicate register rename base from current frame
871b725ae77Skettenis 	     marker for this frame. */
872b725ae77Skettenis 	  int rrb_pr = (cfm >> 32) & 0x3f;
873b725ae77Skettenis 
874b725ae77Skettenis 	  /* Adjust the register number to account for register rotation. */
875b725ae77Skettenis 	  regnum = VP16_REGNUM
876b725ae77Skettenis 	         + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
877b725ae77Skettenis 	}
878b725ae77Skettenis       prN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
879b725ae77Skettenis       prN_mask = (1LL << (regnum - VP0_REGNUM));
880b725ae77Skettenis       if (prN_val == 0)
881b725ae77Skettenis 	pr &= ~prN_mask;
882b725ae77Skettenis       else if (prN_val == 1)
883b725ae77Skettenis 	pr |= prN_mask;
884b725ae77Skettenis       regcache_cooked_write_unsigned (regcache, IA64_PR_REGNUM, pr);
885b725ae77Skettenis     }
886b725ae77Skettenis }
887b725ae77Skettenis 
888b725ae77Skettenis /* The ia64 needs to convert between various ieee floating-point formats
889b725ae77Skettenis    and the special ia64 floating point register format.  */
890b725ae77Skettenis 
891b725ae77Skettenis static int
ia64_convert_register_p(int regno,struct type * type)892b725ae77Skettenis ia64_convert_register_p (int regno, struct type *type)
893b725ae77Skettenis {
894b725ae77Skettenis   return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM);
895b725ae77Skettenis }
896b725ae77Skettenis 
897b725ae77Skettenis static void
ia64_register_to_value(struct frame_info * frame,int regnum,struct type * valtype,void * out)898b725ae77Skettenis ia64_register_to_value (struct frame_info *frame, int regnum,
899b725ae77Skettenis                          struct type *valtype, void *out)
900b725ae77Skettenis {
901b725ae77Skettenis   char in[MAX_REGISTER_SIZE];
902b725ae77Skettenis   frame_register_read (frame, regnum, in);
903b725ae77Skettenis   convert_typed_floating (in, builtin_type_ia64_ext, out, valtype);
904b725ae77Skettenis }
905b725ae77Skettenis 
906b725ae77Skettenis static void
ia64_value_to_register(struct frame_info * frame,int regnum,struct type * valtype,const void * in)907b725ae77Skettenis ia64_value_to_register (struct frame_info *frame, int regnum,
908b725ae77Skettenis                          struct type *valtype, const void *in)
909b725ae77Skettenis {
910b725ae77Skettenis   char out[MAX_REGISTER_SIZE];
911b725ae77Skettenis   convert_typed_floating (in, valtype, out, builtin_type_ia64_ext);
912b725ae77Skettenis   put_frame_register (frame, regnum, out);
913b725ae77Skettenis }
914b725ae77Skettenis 
915b725ae77Skettenis 
916b725ae77Skettenis /* Limit the number of skipped non-prologue instructions since examining
917b725ae77Skettenis    of the prologue is expensive.  */
918b725ae77Skettenis static int max_skip_non_prologue_insns = 40;
919b725ae77Skettenis 
920b725ae77Skettenis /* Given PC representing the starting address of a function, and
921b725ae77Skettenis    LIM_PC which is the (sloppy) limit to which to scan when looking
922b725ae77Skettenis    for a prologue, attempt to further refine this limit by using
923b725ae77Skettenis    the line data in the symbol table.  If successful, a better guess
924b725ae77Skettenis    on where the prologue ends is returned, otherwise the previous
925b725ae77Skettenis    value of lim_pc is returned.  TRUST_LIMIT is a pointer to a flag
926b725ae77Skettenis    which will be set to indicate whether the returned limit may be
927b725ae77Skettenis    used with no further scanning in the event that the function is
928b725ae77Skettenis    frameless.  */
929b725ae77Skettenis 
930b725ae77Skettenis /* FIXME: cagney/2004-02-14: This function and logic have largely been
931b725ae77Skettenis    superseded by skip_prologue_using_sal.  */
932b725ae77Skettenis 
933b725ae77Skettenis static CORE_ADDR
refine_prologue_limit(CORE_ADDR pc,CORE_ADDR lim_pc,int * trust_limit)934b725ae77Skettenis refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
935b725ae77Skettenis {
936b725ae77Skettenis   struct symtab_and_line prologue_sal;
937b725ae77Skettenis   CORE_ADDR start_pc = pc;
938b725ae77Skettenis 
939b725ae77Skettenis   /* Start off not trusting the limit.  */
940b725ae77Skettenis   *trust_limit = 0;
941b725ae77Skettenis 
942b725ae77Skettenis   prologue_sal = find_pc_line (pc, 0);
943b725ae77Skettenis   if (prologue_sal.line != 0)
944b725ae77Skettenis     {
945b725ae77Skettenis       int i;
946b725ae77Skettenis       CORE_ADDR addr = prologue_sal.end;
947b725ae77Skettenis 
948b725ae77Skettenis       /* Handle the case in which compiler's optimizer/scheduler
949b725ae77Skettenis          has moved instructions into the prologue.  We scan ahead
950b725ae77Skettenis 	 in the function looking for address ranges whose corresponding
951b725ae77Skettenis 	 line number is less than or equal to the first one that we
952b725ae77Skettenis 	 found for the function.  (It can be less than when the
953b725ae77Skettenis 	 scheduler puts a body instruction before the first prologue
954b725ae77Skettenis 	 instruction.)  */
955b725ae77Skettenis       for (i = 2 * max_skip_non_prologue_insns;
956b725ae77Skettenis            i > 0 && (lim_pc == 0 || addr < lim_pc);
957b725ae77Skettenis 	   i--)
958b725ae77Skettenis         {
959b725ae77Skettenis 	  struct symtab_and_line sal;
960b725ae77Skettenis 
961b725ae77Skettenis 	  sal = find_pc_line (addr, 0);
962b725ae77Skettenis 	  if (sal.line == 0)
963b725ae77Skettenis 	    break;
964b725ae77Skettenis 	  if (sal.line <= prologue_sal.line
965b725ae77Skettenis 	      && sal.symtab == prologue_sal.symtab)
966b725ae77Skettenis 	    {
967b725ae77Skettenis 	      prologue_sal = sal;
968b725ae77Skettenis 	    }
969b725ae77Skettenis 	  addr = sal.end;
970b725ae77Skettenis 	}
971b725ae77Skettenis 
972b725ae77Skettenis       if (lim_pc == 0 || prologue_sal.end < lim_pc)
973b725ae77Skettenis 	{
974b725ae77Skettenis 	  lim_pc = prologue_sal.end;
975b725ae77Skettenis 	  if (start_pc == get_pc_function_start (lim_pc))
976b725ae77Skettenis 	    *trust_limit = 1;
977b725ae77Skettenis 	}
978b725ae77Skettenis     }
979b725ae77Skettenis   return lim_pc;
980b725ae77Skettenis }
981b725ae77Skettenis 
982b725ae77Skettenis #define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
983b725ae77Skettenis   || (8 <= (_regnum_) && (_regnum_) <= 11) \
984b725ae77Skettenis   || (14 <= (_regnum_) && (_regnum_) <= 31))
985b725ae77Skettenis #define imm9(_instr_) \
986b725ae77Skettenis   ( ((((_instr_) & 0x01000000000LL) ? -1 : 0) << 8) \
987b725ae77Skettenis    | (((_instr_) & 0x00008000000LL) >> 20) \
988b725ae77Skettenis    | (((_instr_) & 0x00000001fc0LL) >> 6))
989b725ae77Skettenis 
990b725ae77Skettenis /* Allocate and initialize a frame cache.  */
991b725ae77Skettenis 
992b725ae77Skettenis static struct ia64_frame_cache *
ia64_alloc_frame_cache(void)993b725ae77Skettenis ia64_alloc_frame_cache (void)
994b725ae77Skettenis {
995b725ae77Skettenis   struct ia64_frame_cache *cache;
996b725ae77Skettenis   int i;
997b725ae77Skettenis 
998b725ae77Skettenis   cache = FRAME_OBSTACK_ZALLOC (struct ia64_frame_cache);
999b725ae77Skettenis 
1000b725ae77Skettenis   /* Base address.  */
1001b725ae77Skettenis   cache->base = 0;
1002b725ae77Skettenis   cache->pc = 0;
1003b725ae77Skettenis   cache->cfm = 0;
1004b725ae77Skettenis   cache->prev_cfm = 0;
1005b725ae77Skettenis   cache->sof = 0;
1006b725ae77Skettenis   cache->sol = 0;
1007b725ae77Skettenis   cache->sor = 0;
1008b725ae77Skettenis   cache->bsp = 0;
1009b725ae77Skettenis   cache->fp_reg = 0;
1010b725ae77Skettenis   cache->frameless = 1;
1011b725ae77Skettenis 
1012b725ae77Skettenis   for (i = 0; i < NUM_IA64_RAW_REGS; i++)
1013b725ae77Skettenis     cache->saved_regs[i] = 0;
1014b725ae77Skettenis 
1015b725ae77Skettenis   return cache;
1016b725ae77Skettenis }
1017b725ae77Skettenis 
1018b725ae77Skettenis static CORE_ADDR
examine_prologue(CORE_ADDR pc,CORE_ADDR lim_pc,struct frame_info * next_frame,struct ia64_frame_cache * cache)1019b725ae77Skettenis examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame, struct ia64_frame_cache *cache)
1020b725ae77Skettenis {
1021b725ae77Skettenis   CORE_ADDR next_pc;
1022b725ae77Skettenis   CORE_ADDR last_prologue_pc = pc;
1023b725ae77Skettenis   instruction_type it;
1024b725ae77Skettenis   long long instr;
1025b725ae77Skettenis   int cfm_reg  = 0;
1026b725ae77Skettenis   int ret_reg  = 0;
1027b725ae77Skettenis   int fp_reg   = 0;
1028b725ae77Skettenis   int unat_save_reg = 0;
1029b725ae77Skettenis   int pr_save_reg = 0;
1030b725ae77Skettenis   int mem_stack_frame_size = 0;
1031b725ae77Skettenis   int spill_reg   = 0;
1032b725ae77Skettenis   CORE_ADDR spill_addr = 0;
1033b725ae77Skettenis   char instores[8];
1034b725ae77Skettenis   char infpstores[8];
1035b725ae77Skettenis   char reg_contents[256];
1036b725ae77Skettenis   int trust_limit;
1037b725ae77Skettenis   int frameless = 1;
1038b725ae77Skettenis   int i;
1039b725ae77Skettenis   CORE_ADDR addr;
1040b725ae77Skettenis   char buf[8];
1041b725ae77Skettenis   CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
1042b725ae77Skettenis 
1043b725ae77Skettenis   memset (instores, 0, sizeof instores);
1044b725ae77Skettenis   memset (infpstores, 0, sizeof infpstores);
1045b725ae77Skettenis   memset (reg_contents, 0, sizeof reg_contents);
1046b725ae77Skettenis 
1047b725ae77Skettenis   if (cache->after_prologue != 0
1048b725ae77Skettenis       && cache->after_prologue <= lim_pc)
1049b725ae77Skettenis     return cache->after_prologue;
1050b725ae77Skettenis 
1051b725ae77Skettenis   lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
1052b725ae77Skettenis   next_pc = fetch_instruction (pc, &it, &instr);
1053b725ae77Skettenis 
1054b725ae77Skettenis   /* We want to check if we have a recognizable function start before we
1055b725ae77Skettenis      look ahead for a prologue.  */
1056b725ae77Skettenis   if (pc < lim_pc && next_pc
1057b725ae77Skettenis       && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
1058b725ae77Skettenis     {
1059b725ae77Skettenis       /* alloc - start of a regular function.  */
1060b725ae77Skettenis       int sor = (int) ((instr & 0x00078000000LL) >> 27);
1061b725ae77Skettenis       int sol = (int) ((instr & 0x00007f00000LL) >> 20);
1062b725ae77Skettenis       int sof = (int) ((instr & 0x000000fe000LL) >> 13);
1063b725ae77Skettenis       int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1064b725ae77Skettenis 
1065b725ae77Skettenis       /* Verify that the current cfm matches what we think is the
1066b725ae77Skettenis 	 function start.  If we have somehow jumped within a function,
1067b725ae77Skettenis 	 we do not want to interpret the prologue and calculate the
1068b725ae77Skettenis 	 addresses of various registers such as the return address.
1069b725ae77Skettenis 	 We will instead treat the frame as frameless. */
1070b725ae77Skettenis       if (!next_frame ||
1071b725ae77Skettenis 	  (sof == (cache->cfm & 0x7f) &&
1072b725ae77Skettenis 	   sol == ((cache->cfm >> 7) & 0x7f)))
1073b725ae77Skettenis 	frameless = 0;
1074b725ae77Skettenis 
1075b725ae77Skettenis       cfm_reg = rN;
1076b725ae77Skettenis       last_prologue_pc = next_pc;
1077b725ae77Skettenis       pc = next_pc;
1078b725ae77Skettenis     }
1079b725ae77Skettenis   else
1080b725ae77Skettenis     {
1081b725ae77Skettenis       /* Look for a leaf routine.  */
1082b725ae77Skettenis       if (pc < lim_pc && next_pc
1083b725ae77Skettenis 	  && (it == I || it == M)
1084b725ae77Skettenis           && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
1085b725ae77Skettenis 	{
1086b725ae77Skettenis 	  /* adds rN = imm14, rM   (or mov rN, rM  when imm14 is 0) */
1087b725ae77Skettenis 	  int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
1088b725ae77Skettenis 	                   | ((instr & 0x001f8000000LL) >> 20)
1089b725ae77Skettenis 		           | ((instr & 0x000000fe000LL) >> 13));
1090b725ae77Skettenis 	  int rM = (int) ((instr & 0x00007f00000LL) >> 20);
1091b725ae77Skettenis 	  int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1092b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1093b725ae77Skettenis 	  if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
1094b725ae77Skettenis 	    {
1095b725ae77Skettenis 	      /* mov r2, r12 - beginning of leaf routine */
1096b725ae77Skettenis 	      fp_reg = rN;
1097b725ae77Skettenis 	      last_prologue_pc = next_pc;
1098b725ae77Skettenis 	    }
1099b725ae77Skettenis 	}
1100b725ae77Skettenis 
1101b725ae77Skettenis       /* If we don't recognize a regular function or leaf routine, we are
1102b725ae77Skettenis 	 done.  */
1103b725ae77Skettenis       if (!fp_reg)
1104b725ae77Skettenis 	{
1105b725ae77Skettenis 	  pc = lim_pc;
1106b725ae77Skettenis 	  if (trust_limit)
1107b725ae77Skettenis 	    last_prologue_pc = lim_pc;
1108b725ae77Skettenis 	}
1109b725ae77Skettenis     }
1110b725ae77Skettenis 
1111b725ae77Skettenis   /* Loop, looking for prologue instructions, keeping track of
1112b725ae77Skettenis      where preserved registers were spilled. */
1113b725ae77Skettenis   while (pc < lim_pc)
1114b725ae77Skettenis     {
1115b725ae77Skettenis       next_pc = fetch_instruction (pc, &it, &instr);
1116b725ae77Skettenis       if (next_pc == 0)
1117b725ae77Skettenis 	break;
1118b725ae77Skettenis 
1119*11efff7fSkettenis       if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
1120b725ae77Skettenis 	{
1121b725ae77Skettenis 	  /* Exit loop upon hitting a non-nop branch instruction. */
1122b725ae77Skettenis 	  if (trust_limit)
1123b725ae77Skettenis 	    lim_pc = pc;
1124b725ae77Skettenis 	  break;
1125b725ae77Skettenis 	}
1126b725ae77Skettenis       else if (((instr & 0x3fLL) != 0LL) &&
1127b725ae77Skettenis 	       (frameless || ret_reg != 0))
1128b725ae77Skettenis 	{
1129b725ae77Skettenis 	  /* Exit loop upon hitting a predicated instruction if
1130b725ae77Skettenis 	     we already have the return register or if we are frameless.  */
1131b725ae77Skettenis 	  if (trust_limit)
1132b725ae77Skettenis 	    lim_pc = pc;
1133b725ae77Skettenis 	  break;
1134b725ae77Skettenis 	}
1135b725ae77Skettenis       else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
1136b725ae77Skettenis         {
1137b725ae77Skettenis 	  /* Move from BR */
1138b725ae77Skettenis 	  int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
1139b725ae77Skettenis 	  int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1140b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003f);
1141b725ae77Skettenis 
1142b725ae77Skettenis 	  if (qp == 0 && b2 == 0 && rN >= 32 && ret_reg == 0)
1143b725ae77Skettenis 	    {
1144b725ae77Skettenis 	      ret_reg = rN;
1145b725ae77Skettenis 	      last_prologue_pc = next_pc;
1146b725ae77Skettenis 	    }
1147b725ae77Skettenis 	}
1148b725ae77Skettenis       else if ((it == I || it == M)
1149b725ae77Skettenis           && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
1150b725ae77Skettenis 	{
1151b725ae77Skettenis 	  /* adds rN = imm14, rM   (or mov rN, rM  when imm14 is 0) */
1152b725ae77Skettenis 	  int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
1153b725ae77Skettenis 	                   | ((instr & 0x001f8000000LL) >> 20)
1154b725ae77Skettenis 		           | ((instr & 0x000000fe000LL) >> 13));
1155b725ae77Skettenis 	  int rM = (int) ((instr & 0x00007f00000LL) >> 20);
1156b725ae77Skettenis 	  int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1157b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1158b725ae77Skettenis 
1159b725ae77Skettenis 	  if (qp == 0 && rN >= 32 && imm == 0 && rM == 12 && fp_reg == 0)
1160b725ae77Skettenis 	    {
1161b725ae77Skettenis 	      /* mov rN, r12 */
1162b725ae77Skettenis 	      fp_reg = rN;
1163b725ae77Skettenis 	      last_prologue_pc = next_pc;
1164b725ae77Skettenis 	    }
1165b725ae77Skettenis 	  else if (qp == 0 && rN == 12 && rM == 12)
1166b725ae77Skettenis 	    {
1167b725ae77Skettenis 	      /* adds r12, -mem_stack_frame_size, r12 */
1168b725ae77Skettenis 	      mem_stack_frame_size -= imm;
1169b725ae77Skettenis 	      last_prologue_pc = next_pc;
1170b725ae77Skettenis 	    }
1171b725ae77Skettenis 	  else if (qp == 0 && rN == 2
1172b725ae77Skettenis 	        && ((rM == fp_reg && fp_reg != 0) || rM == 12))
1173b725ae77Skettenis 	    {
1174b725ae77Skettenis 	      char buf[MAX_REGISTER_SIZE];
1175b725ae77Skettenis 	      CORE_ADDR saved_sp = 0;
1176b725ae77Skettenis 	      /* adds r2, spilloffset, rFramePointer
1177b725ae77Skettenis 	           or
1178b725ae77Skettenis 		 adds r2, spilloffset, r12
1179b725ae77Skettenis 
1180b725ae77Skettenis 	         Get ready for stf.spill or st8.spill instructions.
1181b725ae77Skettenis 		 The address to start spilling at is loaded into r2.
1182b725ae77Skettenis 		 FIXME:  Why r2?  That's what gcc currently uses; it
1183b725ae77Skettenis 		 could well be different for other compilers.  */
1184b725ae77Skettenis 
1185b725ae77Skettenis 	      /* Hmm... whether or not this will work will depend on
1186b725ae77Skettenis 	         where the pc is.  If it's still early in the prologue
1187b725ae77Skettenis 		 this'll be wrong.  FIXME */
1188b725ae77Skettenis 	      if (next_frame)
1189b725ae77Skettenis 		{
1190b725ae77Skettenis 		  frame_unwind_register (next_frame, sp_regnum, buf);
1191b725ae77Skettenis 		  saved_sp = extract_unsigned_integer (buf, 8);
1192b725ae77Skettenis 		}
1193b725ae77Skettenis 	      spill_addr  = saved_sp
1194b725ae77Skettenis 	                  + (rM == 12 ? 0 : mem_stack_frame_size)
1195b725ae77Skettenis 			  + imm;
1196b725ae77Skettenis 	      spill_reg   = rN;
1197b725ae77Skettenis 	      last_prologue_pc = next_pc;
1198b725ae77Skettenis 	    }
1199b725ae77Skettenis 	  else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] &&
1200b725ae77Skettenis 		   rN < 256 && imm == 0)
1201b725ae77Skettenis 	    {
1202b725ae77Skettenis 	      /* mov rN, rM where rM is an input register */
1203b725ae77Skettenis 	      reg_contents[rN] = rM;
1204b725ae77Skettenis 	      last_prologue_pc = next_pc;
1205b725ae77Skettenis 	    }
1206b725ae77Skettenis 	  else if (frameless && qp == 0 && rN == fp_reg && imm == 0 &&
1207b725ae77Skettenis 		   rM == 2)
1208b725ae77Skettenis 	    {
1209b725ae77Skettenis 	      /* mov r12, r2 */
1210b725ae77Skettenis 	      last_prologue_pc = next_pc;
1211b725ae77Skettenis 	      break;
1212b725ae77Skettenis 	    }
1213b725ae77Skettenis 	}
1214b725ae77Skettenis       else if (it == M
1215b725ae77Skettenis             && (   ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
1216b725ae77Skettenis                 || ((instr & 0x1ffc8000000LL) == 0x0cec0000000LL) ))
1217b725ae77Skettenis 	{
1218b725ae77Skettenis 	  /* stf.spill [rN] = fM, imm9
1219b725ae77Skettenis 	     or
1220b725ae77Skettenis 	     stf.spill [rN] = fM  */
1221b725ae77Skettenis 
1222b725ae77Skettenis 	  int imm = imm9(instr);
1223b725ae77Skettenis 	  int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1224b725ae77Skettenis 	  int fM = (int) ((instr & 0x000000fe000LL) >> 13);
1225b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1226b725ae77Skettenis 	  if (qp == 0 && rN == spill_reg && spill_addr != 0
1227b725ae77Skettenis 	      && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31)))
1228b725ae77Skettenis 	    {
1229b725ae77Skettenis 	      cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
1230b725ae77Skettenis 
1231*11efff7fSkettenis               if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
1232b725ae77Skettenis 		spill_addr += imm;
1233b725ae77Skettenis 	      else
1234b725ae77Skettenis 		spill_addr = 0;		/* last one; must be done */
1235b725ae77Skettenis 	      last_prologue_pc = next_pc;
1236b725ae77Skettenis 	    }
1237b725ae77Skettenis 	}
1238b725ae77Skettenis       else if ((it == M && ((instr & 0x1eff8000000LL) == 0x02110000000LL))
1239b725ae77Skettenis             || (it == I && ((instr & 0x1eff8000000LL) == 0x00050000000LL)) )
1240b725ae77Skettenis 	{
1241b725ae77Skettenis 	  /* mov.m rN = arM
1242b725ae77Skettenis 	       or
1243b725ae77Skettenis 	     mov.i rN = arM */
1244b725ae77Skettenis 
1245b725ae77Skettenis 	  int arM = (int) ((instr & 0x00007f00000LL) >> 20);
1246b725ae77Skettenis 	  int rN  = (int) ((instr & 0x00000001fc0LL) >> 6);
1247b725ae77Skettenis 	  int qp  = (int) (instr & 0x0000000003fLL);
1248b725ae77Skettenis 	  if (qp == 0 && isScratch (rN) && arM == 36 /* ar.unat */)
1249b725ae77Skettenis 	    {
1250b725ae77Skettenis 	      /* We have something like "mov.m r3 = ar.unat".  Remember the
1251b725ae77Skettenis 		 r3 (or whatever) and watch for a store of this register... */
1252b725ae77Skettenis 	      unat_save_reg = rN;
1253b725ae77Skettenis 	      last_prologue_pc = next_pc;
1254b725ae77Skettenis 	    }
1255b725ae77Skettenis 	}
1256b725ae77Skettenis       else if (it == I && ((instr & 0x1eff8000000LL) == 0x00198000000LL))
1257b725ae77Skettenis 	{
1258b725ae77Skettenis 	  /* mov rN = pr */
1259b725ae77Skettenis 	  int rN  = (int) ((instr & 0x00000001fc0LL) >> 6);
1260b725ae77Skettenis 	  int qp  = (int) (instr & 0x0000000003fLL);
1261b725ae77Skettenis 	  if (qp == 0 && isScratch (rN))
1262b725ae77Skettenis 	    {
1263b725ae77Skettenis 	      pr_save_reg = rN;
1264b725ae77Skettenis 	      last_prologue_pc = next_pc;
1265b725ae77Skettenis 	    }
1266b725ae77Skettenis 	}
1267b725ae77Skettenis       else if (it == M
1268b725ae77Skettenis             && (   ((instr & 0x1ffc8000000LL) == 0x08cc0000000LL)
1269b725ae77Skettenis 	        || ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)))
1270b725ae77Skettenis 	{
1271b725ae77Skettenis 	  /* st8 [rN] = rM
1272b725ae77Skettenis 	      or
1273b725ae77Skettenis 	     st8 [rN] = rM, imm9 */
1274b725ae77Skettenis 	  int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1275b725ae77Skettenis 	  int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1276b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1277b725ae77Skettenis 	  int indirect = rM < 256 ? reg_contents[rM] : 0;
1278b725ae77Skettenis 	  if (qp == 0 && rN == spill_reg && spill_addr != 0
1279b725ae77Skettenis 	      && (rM == unat_save_reg || rM == pr_save_reg))
1280b725ae77Skettenis 	    {
1281b725ae77Skettenis 	      /* We've found a spill of either the UNAT register or the PR
1282b725ae77Skettenis 	         register.  (Well, not exactly; what we've actually found is
1283b725ae77Skettenis 		 a spill of the register that UNAT or PR was moved to).
1284b725ae77Skettenis 		 Record that fact and move on... */
1285b725ae77Skettenis 	      if (rM == unat_save_reg)
1286b725ae77Skettenis 		{
1287b725ae77Skettenis 		  /* Track UNAT register */
1288b725ae77Skettenis 		  cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
1289b725ae77Skettenis 		  unat_save_reg = 0;
1290b725ae77Skettenis 		}
1291b725ae77Skettenis 	      else
1292b725ae77Skettenis 	        {
1293b725ae77Skettenis 		  /* Track PR register */
1294b725ae77Skettenis 		  cache->saved_regs[IA64_PR_REGNUM] = spill_addr;
1295b725ae77Skettenis 		  pr_save_reg = 0;
1296b725ae77Skettenis 		}
1297b725ae77Skettenis 	      if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)
1298b725ae77Skettenis 		/* st8 [rN] = rM, imm9 */
1299b725ae77Skettenis 		spill_addr += imm9(instr);
1300b725ae77Skettenis 	      else
1301b725ae77Skettenis 		spill_addr = 0;		/* must be done spilling */
1302b725ae77Skettenis 	      last_prologue_pc = next_pc;
1303b725ae77Skettenis 	    }
1304b725ae77Skettenis 	  else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
1305b725ae77Skettenis 	    {
1306b725ae77Skettenis 	      /* Allow up to one store of each input register. */
1307b725ae77Skettenis 	      instores[rM-32] = 1;
1308b725ae77Skettenis 	      last_prologue_pc = next_pc;
1309b725ae77Skettenis 	    }
1310b725ae77Skettenis 	  else if (qp == 0 && 32 <= indirect && indirect < 40 &&
1311b725ae77Skettenis 		   !instores[indirect-32])
1312b725ae77Skettenis 	    {
1313b725ae77Skettenis 	      /* Allow an indirect store of an input register.  */
1314b725ae77Skettenis 	      instores[indirect-32] = 1;
1315b725ae77Skettenis 	      last_prologue_pc = next_pc;
1316b725ae77Skettenis 	    }
1317b725ae77Skettenis 	}
1318b725ae77Skettenis       else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
1319b725ae77Skettenis 	{
1320b725ae77Skettenis 	  /* One of
1321b725ae77Skettenis 	       st1 [rN] = rM
1322b725ae77Skettenis 	       st2 [rN] = rM
1323b725ae77Skettenis 	       st4 [rN] = rM
1324b725ae77Skettenis 	       st8 [rN] = rM
1325b725ae77Skettenis 	     Note that the st8 case is handled in the clause above.
1326b725ae77Skettenis 
1327b725ae77Skettenis 	     Advance over stores of input registers. One store per input
1328b725ae77Skettenis 	     register is permitted. */
1329b725ae77Skettenis 	  int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1330b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1331b725ae77Skettenis 	  int indirect = rM < 256 ? reg_contents[rM] : 0;
1332b725ae77Skettenis 	  if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
1333b725ae77Skettenis 	    {
1334b725ae77Skettenis 	      instores[rM-32] = 1;
1335b725ae77Skettenis 	      last_prologue_pc = next_pc;
1336b725ae77Skettenis 	    }
1337b725ae77Skettenis 	  else if (qp == 0 && 32 <= indirect && indirect < 40 &&
1338b725ae77Skettenis 		   !instores[indirect-32])
1339b725ae77Skettenis 	    {
1340b725ae77Skettenis 	      /* Allow an indirect store of an input register.  */
1341b725ae77Skettenis 	      instores[indirect-32] = 1;
1342b725ae77Skettenis 	      last_prologue_pc = next_pc;
1343b725ae77Skettenis 	    }
1344b725ae77Skettenis 	}
1345b725ae77Skettenis       else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
1346b725ae77Skettenis         {
1347b725ae77Skettenis 	  /* Either
1348b725ae77Skettenis 	       stfs [rN] = fM
1349b725ae77Skettenis 	     or
1350b725ae77Skettenis 	       stfd [rN] = fM
1351b725ae77Skettenis 
1352b725ae77Skettenis 	     Advance over stores of floating point input registers.  Again
1353b725ae77Skettenis 	     one store per register is permitted */
1354b725ae77Skettenis 	  int fM = (int) ((instr & 0x000000fe000LL) >> 13);
1355b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1356b725ae77Skettenis 	  if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
1357b725ae77Skettenis 	    {
1358b725ae77Skettenis 	      infpstores[fM-8] = 1;
1359b725ae77Skettenis 	      last_prologue_pc = next_pc;
1360b725ae77Skettenis 	    }
1361b725ae77Skettenis 	}
1362b725ae77Skettenis       else if (it == M
1363b725ae77Skettenis             && (   ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
1364b725ae77Skettenis 	        || ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)))
1365b725ae77Skettenis 	{
1366b725ae77Skettenis 	  /* st8.spill [rN] = rM
1367b725ae77Skettenis 	       or
1368b725ae77Skettenis 	     st8.spill [rN] = rM, imm9 */
1369b725ae77Skettenis 	  int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1370b725ae77Skettenis 	  int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1371b725ae77Skettenis 	  int qp = (int) (instr & 0x0000000003fLL);
1372b725ae77Skettenis 	  if (qp == 0 && rN == spill_reg && 4 <= rM && rM <= 7)
1373b725ae77Skettenis 	    {
1374b725ae77Skettenis 	      /* We've found a spill of one of the preserved general purpose
1375b725ae77Skettenis 	         regs.  Record the spill address and advance the spill
1376b725ae77Skettenis 		 register if appropriate. */
1377b725ae77Skettenis 	      cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
1378b725ae77Skettenis 	      if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
1379b725ae77Skettenis 	        /* st8.spill [rN] = rM, imm9 */
1380b725ae77Skettenis 		spill_addr += imm9(instr);
1381b725ae77Skettenis 	      else
1382b725ae77Skettenis 		spill_addr = 0;		/* Done spilling */
1383b725ae77Skettenis 	      last_prologue_pc = next_pc;
1384b725ae77Skettenis 	    }
1385b725ae77Skettenis 	}
1386b725ae77Skettenis 
1387b725ae77Skettenis       pc = next_pc;
1388b725ae77Skettenis     }
1389b725ae77Skettenis 
1390b725ae77Skettenis   /* If not frameless and we aren't called by skip_prologue, then we need to calculate
1391b725ae77Skettenis      registers for the previous frame which will be needed later.  */
1392b725ae77Skettenis 
1393b725ae77Skettenis   if (!frameless && next_frame)
1394b725ae77Skettenis     {
1395b725ae77Skettenis       /* Extract the size of the rotating portion of the stack
1396b725ae77Skettenis 	 frame and the register rename base from the current
1397b725ae77Skettenis 	 frame marker. */
1398b725ae77Skettenis       cfm = cache->cfm;
1399b725ae77Skettenis       sor = cache->sor;
1400b725ae77Skettenis       sof = cache->sof;
1401b725ae77Skettenis       sol = cache->sol;
1402b725ae77Skettenis       rrb_gr = (cfm >> 18) & 0x7f;
1403b725ae77Skettenis 
1404b725ae77Skettenis       /* Find the bof (beginning of frame).  */
1405b725ae77Skettenis       bof = rse_address_add (cache->bsp, -sof);
1406b725ae77Skettenis 
1407b725ae77Skettenis       for (i = 0, addr = bof;
1408b725ae77Skettenis 	   i < sof;
1409b725ae77Skettenis 	   i++, addr += 8)
1410b725ae77Skettenis 	{
1411b725ae77Skettenis 	  if (IS_NaT_COLLECTION_ADDR (addr))
1412b725ae77Skettenis 	    {
1413b725ae77Skettenis 	      addr += 8;
1414b725ae77Skettenis 	    }
1415b725ae77Skettenis 	  if (i+32 == cfm_reg)
1416b725ae77Skettenis 	    cache->saved_regs[IA64_CFM_REGNUM] = addr;
1417b725ae77Skettenis 	  if (i+32 == ret_reg)
1418b725ae77Skettenis 	    cache->saved_regs[IA64_VRAP_REGNUM] = addr;
1419b725ae77Skettenis 	  if (i+32 == fp_reg)
1420b725ae77Skettenis 	    cache->saved_regs[IA64_VFP_REGNUM] = addr;
1421b725ae77Skettenis 	}
1422b725ae77Skettenis 
1423b725ae77Skettenis       /* For the previous argument registers we require the previous bof.
1424b725ae77Skettenis 	 If we can't find the previous cfm, then we can do nothing.  */
1425b725ae77Skettenis       cfm = 0;
1426b725ae77Skettenis       if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
1427b725ae77Skettenis 	{
1428b725ae77Skettenis 	  cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
1429b725ae77Skettenis 	}
1430b725ae77Skettenis       else if (cfm_reg != 0)
1431b725ae77Skettenis 	{
1432b725ae77Skettenis 	  frame_unwind_register (next_frame, cfm_reg, buf);
1433b725ae77Skettenis 	  cfm = extract_unsigned_integer (buf, 8);
1434b725ae77Skettenis 	}
1435b725ae77Skettenis       cache->prev_cfm = cfm;
1436b725ae77Skettenis 
1437b725ae77Skettenis       if (cfm != 0)
1438b725ae77Skettenis 	{
1439b725ae77Skettenis 	  sor = ((cfm >> 14) & 0xf) * 8;
1440b725ae77Skettenis 	  sof = (cfm & 0x7f);
1441b725ae77Skettenis 	  sol = (cfm >> 7) & 0x7f;
1442b725ae77Skettenis 	  rrb_gr = (cfm >> 18) & 0x7f;
1443b725ae77Skettenis 
1444b725ae77Skettenis 	  /* The previous bof only requires subtraction of the sol (size of locals)
1445b725ae77Skettenis 	     due to the overlap between output and input of subsequent frames.  */
1446b725ae77Skettenis 	  bof = rse_address_add (bof, -sol);
1447b725ae77Skettenis 
1448b725ae77Skettenis 	  for (i = 0, addr = bof;
1449b725ae77Skettenis 	       i < sof;
1450b725ae77Skettenis 	       i++, addr += 8)
1451b725ae77Skettenis 	    {
1452b725ae77Skettenis 	      if (IS_NaT_COLLECTION_ADDR (addr))
1453b725ae77Skettenis 		{
1454b725ae77Skettenis 		  addr += 8;
1455b725ae77Skettenis 		}
1456b725ae77Skettenis 	      if (i < sor)
1457b725ae77Skettenis 		cache->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)]
1458b725ae77Skettenis 		  = addr;
1459b725ae77Skettenis 	      else
1460b725ae77Skettenis 		cache->saved_regs[IA64_GR32_REGNUM + i] = addr;
1461b725ae77Skettenis 	    }
1462b725ae77Skettenis 
1463b725ae77Skettenis 	}
1464b725ae77Skettenis     }
1465b725ae77Skettenis 
1466b725ae77Skettenis   /* Try and trust the lim_pc value whenever possible.  */
1467b725ae77Skettenis   if (trust_limit && lim_pc >= last_prologue_pc)
1468b725ae77Skettenis     last_prologue_pc = lim_pc;
1469b725ae77Skettenis 
1470b725ae77Skettenis   cache->frameless = frameless;
1471b725ae77Skettenis   cache->after_prologue = last_prologue_pc;
1472b725ae77Skettenis   cache->mem_stack_frame_size = mem_stack_frame_size;
1473b725ae77Skettenis   cache->fp_reg = fp_reg;
1474b725ae77Skettenis 
1475b725ae77Skettenis   return last_prologue_pc;
1476b725ae77Skettenis }
1477b725ae77Skettenis 
1478b725ae77Skettenis CORE_ADDR
ia64_skip_prologue(CORE_ADDR pc)1479b725ae77Skettenis ia64_skip_prologue (CORE_ADDR pc)
1480b725ae77Skettenis {
1481b725ae77Skettenis   struct ia64_frame_cache cache;
1482b725ae77Skettenis   cache.base = 0;
1483b725ae77Skettenis   cache.after_prologue = 0;
1484b725ae77Skettenis   cache.cfm = 0;
1485b725ae77Skettenis   cache.bsp = 0;
1486b725ae77Skettenis 
1487b725ae77Skettenis   /* Call examine_prologue with - as third argument since we don't have a next frame pointer to send.  */
1488b725ae77Skettenis   return examine_prologue (pc, pc+1024, 0, &cache);
1489b725ae77Skettenis }
1490b725ae77Skettenis 
1491b725ae77Skettenis 
1492b725ae77Skettenis /* Normal frames.  */
1493b725ae77Skettenis 
1494b725ae77Skettenis static struct ia64_frame_cache *
ia64_frame_cache(struct frame_info * next_frame,void ** this_cache)1495b725ae77Skettenis ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
1496b725ae77Skettenis {
1497b725ae77Skettenis   struct ia64_frame_cache *cache;
1498b725ae77Skettenis   char buf[8];
1499b725ae77Skettenis   CORE_ADDR cfm, sof, sol, bsp, psr;
1500b725ae77Skettenis   int i;
1501b725ae77Skettenis 
1502b725ae77Skettenis   if (*this_cache)
1503b725ae77Skettenis     return *this_cache;
1504b725ae77Skettenis 
1505b725ae77Skettenis   cache = ia64_alloc_frame_cache ();
1506b725ae77Skettenis   *this_cache = cache;
1507b725ae77Skettenis 
1508b725ae77Skettenis   frame_unwind_register (next_frame, sp_regnum, buf);
1509b725ae77Skettenis   cache->saved_sp = extract_unsigned_integer (buf, 8);
1510b725ae77Skettenis 
1511b725ae77Skettenis   /* We always want the bsp to point to the end of frame.
1512b725ae77Skettenis      This way, we can always get the beginning of frame (bof)
1513b725ae77Skettenis      by subtracting frame size.  */
1514b725ae77Skettenis   frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1515b725ae77Skettenis   cache->bsp = extract_unsigned_integer (buf, 8);
1516b725ae77Skettenis 
1517b725ae77Skettenis   frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
1518b725ae77Skettenis   psr = extract_unsigned_integer (buf, 8);
1519b725ae77Skettenis 
1520b725ae77Skettenis   frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
1521b725ae77Skettenis   cfm = extract_unsigned_integer (buf, 8);
1522b725ae77Skettenis 
1523b725ae77Skettenis   cache->sof = (cfm & 0x7f);
1524b725ae77Skettenis   cache->sol = (cfm >> 7) & 0x7f;
1525b725ae77Skettenis   cache->sor = ((cfm >> 14) & 0xf) * 8;
1526b725ae77Skettenis 
1527b725ae77Skettenis   cache->cfm = cfm;
1528b725ae77Skettenis 
1529b725ae77Skettenis   cache->pc = frame_func_unwind (next_frame);
1530b725ae77Skettenis 
1531b725ae77Skettenis   if (cache->pc != 0)
1532b725ae77Skettenis     examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
1533b725ae77Skettenis 
1534b725ae77Skettenis   cache->base = cache->saved_sp + cache->mem_stack_frame_size;
1535b725ae77Skettenis 
1536b725ae77Skettenis   return cache;
1537b725ae77Skettenis }
1538b725ae77Skettenis 
1539b725ae77Skettenis static void
ia64_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)1540b725ae77Skettenis ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
1541b725ae77Skettenis 		    struct frame_id *this_id)
1542b725ae77Skettenis {
1543b725ae77Skettenis   struct ia64_frame_cache *cache =
1544b725ae77Skettenis     ia64_frame_cache (next_frame, this_cache);
1545b725ae77Skettenis 
1546b725ae77Skettenis   /* This marks the outermost frame.  */
1547b725ae77Skettenis   if (cache->base == 0)
1548b725ae77Skettenis     return;
1549b725ae77Skettenis 
1550b725ae77Skettenis   (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
1551b725ae77Skettenis   if (gdbarch_debug >= 1)
1552b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
1553b725ae77Skettenis 			"regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
1554b725ae77Skettenis 			paddr_nz (this_id->code_addr),
1555b725ae77Skettenis 			paddr_nz (this_id->stack_addr),
1556b725ae77Skettenis 			paddr_nz (cache->bsp), next_frame);
1557b725ae77Skettenis }
1558b725ae77Skettenis 
1559b725ae77Skettenis static void
ia64_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)1560b725ae77Skettenis ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
1561b725ae77Skettenis 			  int regnum, int *optimizedp,
1562b725ae77Skettenis 			  enum lval_type *lvalp, CORE_ADDR *addrp,
1563b725ae77Skettenis 			  int *realnump, void *valuep)
1564b725ae77Skettenis {
1565b725ae77Skettenis   struct ia64_frame_cache *cache =
1566b725ae77Skettenis     ia64_frame_cache (next_frame, this_cache);
1567b725ae77Skettenis   char dummy_valp[MAX_REGISTER_SIZE];
1568b725ae77Skettenis   char buf[8];
1569b725ae77Skettenis 
1570b725ae77Skettenis   gdb_assert (regnum >= 0);
1571b725ae77Skettenis 
1572b725ae77Skettenis   if (!target_has_registers)
1573b725ae77Skettenis     error ("No registers.");
1574b725ae77Skettenis 
1575b725ae77Skettenis   *optimizedp = 0;
1576b725ae77Skettenis   *addrp = 0;
1577b725ae77Skettenis   *lvalp = not_lval;
1578b725ae77Skettenis   *realnump = -1;
1579b725ae77Skettenis 
1580b725ae77Skettenis   /* Rather than check each time if valuep is non-null, supply a dummy buffer
1581b725ae77Skettenis      when valuep is not supplied.  */
1582b725ae77Skettenis   if (!valuep)
1583b725ae77Skettenis     valuep = dummy_valp;
1584b725ae77Skettenis 
1585b725ae77Skettenis   memset (valuep, 0, register_size (current_gdbarch, regnum));
1586b725ae77Skettenis 
1587b725ae77Skettenis   if (regnum == SP_REGNUM)
1588b725ae77Skettenis     {
1589b725ae77Skettenis       /* Handle SP values for all frames but the topmost. */
1590b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1591b725ae77Skettenis 			      cache->base);
1592b725ae77Skettenis     }
1593b725ae77Skettenis   else if (regnum == IA64_BSP_REGNUM)
1594b725ae77Skettenis     {
1595b725ae77Skettenis       char cfm_valuep[MAX_REGISTER_SIZE];
1596b725ae77Skettenis       int  cfm_optim;
1597b725ae77Skettenis       int  cfm_realnum;
1598b725ae77Skettenis       enum lval_type cfm_lval;
1599b725ae77Skettenis       CORE_ADDR cfm_addr;
1600b725ae77Skettenis       CORE_ADDR bsp, prev_cfm, prev_bsp;
1601b725ae77Skettenis 
1602b725ae77Skettenis       /* We want to calculate the previous bsp as the end of the previous register stack frame.
1603b725ae77Skettenis 	 This corresponds to what the hardware bsp register will be if we pop the frame
1604b725ae77Skettenis 	 back which is why we might have been called.  We know the beginning of the current
1605b725ae77Skettenis 	 frame is cache->bsp - cache->sof.  This value in the previous frame points to
1606b725ae77Skettenis 	 the start of the output registers.  We can calculate the end of that frame by adding
1607b725ae77Skettenis 	 the size of output (sof (size of frame) - sol (size of locals)).  */
1608b725ae77Skettenis       ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
1609b725ae77Skettenis 				&cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
1610b725ae77Skettenis       prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
1611b725ae77Skettenis 
1612b725ae77Skettenis       bsp = rse_address_add (cache->bsp, -(cache->sof));
1613b725ae77Skettenis       prev_bsp = rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
1614b725ae77Skettenis 
1615b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1616b725ae77Skettenis 			      prev_bsp);
1617b725ae77Skettenis     }
1618b725ae77Skettenis   else if (regnum == IA64_CFM_REGNUM)
1619b725ae77Skettenis     {
1620b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
1621b725ae77Skettenis 
1622b725ae77Skettenis       if (addr != 0)
1623b725ae77Skettenis 	{
1624b725ae77Skettenis 	  *lvalp = lval_memory;
1625b725ae77Skettenis 	  *addrp = addr;
1626b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1627b725ae77Skettenis 	}
1628b725ae77Skettenis       else if (cache->prev_cfm)
1629b725ae77Skettenis 	store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm);
1630b725ae77Skettenis       else if (cache->frameless)
1631b725ae77Skettenis 	{
1632b725ae77Skettenis 	  CORE_ADDR cfm = 0;
1633b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
1634b725ae77Skettenis 	}
1635b725ae77Skettenis     }
1636b725ae77Skettenis   else if (regnum == IA64_VFP_REGNUM)
1637b725ae77Skettenis     {
1638b725ae77Skettenis       /* If the function in question uses an automatic register (r32-r127)
1639b725ae77Skettenis          for the frame pointer, it'll be found by ia64_find_saved_register()
1640b725ae77Skettenis 	 above.  If the function lacks one of these frame pointers, we can
1641b725ae77Skettenis 	 still provide a value since we know the size of the frame.  */
1642b725ae77Skettenis       CORE_ADDR vfp = cache->base;
1643b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, IA64_VFP_REGNUM), vfp);
1644b725ae77Skettenis     }
1645b725ae77Skettenis   else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
1646b725ae77Skettenis     {
1647b725ae77Skettenis       char pr_valuep[MAX_REGISTER_SIZE];
1648b725ae77Skettenis       int  pr_optim;
1649b725ae77Skettenis       int  pr_realnum;
1650b725ae77Skettenis       enum lval_type pr_lval;
1651b725ae77Skettenis       CORE_ADDR pr_addr;
1652b725ae77Skettenis       ULONGEST prN_val;
1653b725ae77Skettenis       ia64_frame_prev_register (next_frame, this_cache, IA64_PR_REGNUM,
1654b725ae77Skettenis 				&pr_optim, &pr_lval, &pr_addr, &pr_realnum, pr_valuep);
1655b725ae77Skettenis       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
1656b725ae77Skettenis 	{
1657b725ae77Skettenis 	  /* Fetch predicate register rename base from current frame
1658b725ae77Skettenis 	     marker for this frame.  */
1659b725ae77Skettenis 	  int rrb_pr = (cache->cfm >> 32) & 0x3f;
1660b725ae77Skettenis 
1661b725ae77Skettenis 	  /* Adjust the register number to account for register rotation.  */
1662b725ae77Skettenis 	  regnum = VP16_REGNUM
1663b725ae77Skettenis 	         + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
1664b725ae77Skettenis 	}
1665b725ae77Skettenis       prN_val = extract_bit_field ((unsigned char *) pr_valuep,
1666b725ae77Skettenis                                    regnum - VP0_REGNUM, 1);
1667b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val);
1668b725ae77Skettenis     }
1669b725ae77Skettenis   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
1670b725ae77Skettenis     {
1671b725ae77Skettenis       char unat_valuep[MAX_REGISTER_SIZE];
1672b725ae77Skettenis       int  unat_optim;
1673b725ae77Skettenis       int  unat_realnum;
1674b725ae77Skettenis       enum lval_type unat_lval;
1675b725ae77Skettenis       CORE_ADDR unat_addr;
1676b725ae77Skettenis       ULONGEST unatN_val;
1677b725ae77Skettenis       ia64_frame_prev_register (next_frame, this_cache, IA64_UNAT_REGNUM,
1678b725ae77Skettenis 				&unat_optim, &unat_lval, &unat_addr, &unat_realnum, unat_valuep);
1679b725ae77Skettenis       unatN_val = extract_bit_field ((unsigned char *) unat_valuep,
1680b725ae77Skettenis                                    regnum - IA64_NAT0_REGNUM, 1);
1681b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1682b725ae77Skettenis                               unatN_val);
1683b725ae77Skettenis     }
1684b725ae77Skettenis   else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
1685b725ae77Skettenis     {
1686b725ae77Skettenis       int natval = 0;
1687b725ae77Skettenis       /* Find address of general register corresponding to nat bit we're
1688b725ae77Skettenis          interested in.  */
1689b725ae77Skettenis       CORE_ADDR gr_addr;
1690b725ae77Skettenis 
1691b725ae77Skettenis       gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM
1692b725ae77Skettenis 				  + IA64_GR0_REGNUM];
1693b725ae77Skettenis       if (gr_addr != 0)
1694b725ae77Skettenis 	{
1695b725ae77Skettenis 	  /* Compute address of nat collection bits.  */
1696b725ae77Skettenis 	  CORE_ADDR nat_addr = gr_addr | 0x1f8;
1697b725ae77Skettenis 	  CORE_ADDR bsp;
1698b725ae77Skettenis 	  CORE_ADDR nat_collection;
1699b725ae77Skettenis 	  int nat_bit;
1700b725ae77Skettenis 	  /* If our nat collection address is bigger than bsp, we have to get
1701b725ae77Skettenis 	     the nat collection from rnat.  Otherwise, we fetch the nat
1702b725ae77Skettenis 	     collection from the computed address.  */
1703b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1704b725ae77Skettenis 	  bsp = extract_unsigned_integer (buf, 8);
1705b725ae77Skettenis 	  if (nat_addr >= bsp)
1706b725ae77Skettenis 	    {
1707b725ae77Skettenis 	      frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf);
1708b725ae77Skettenis 	      nat_collection = extract_unsigned_integer (buf, 8);
1709b725ae77Skettenis 	    }
1710b725ae77Skettenis 	  else
1711b725ae77Skettenis 	    nat_collection = read_memory_integer (nat_addr, 8);
1712b725ae77Skettenis 	  nat_bit = (gr_addr >> 3) & 0x3f;
1713b725ae77Skettenis 	  natval = (nat_collection >> nat_bit) & 1;
1714b725ae77Skettenis 	}
1715b725ae77Skettenis 
1716b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), natval);
1717b725ae77Skettenis     }
1718b725ae77Skettenis   else if (regnum == IA64_IP_REGNUM)
1719b725ae77Skettenis     {
1720b725ae77Skettenis       CORE_ADDR pc = 0;
1721b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1722b725ae77Skettenis 
1723b725ae77Skettenis       if (addr != 0)
1724b725ae77Skettenis 	{
1725b725ae77Skettenis 	  *lvalp = lval_memory;
1726b725ae77Skettenis 	  *addrp = addr;
1727b725ae77Skettenis 	  read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1728b725ae77Skettenis 	  pc = extract_unsigned_integer (buf, 8);
1729b725ae77Skettenis 	}
1730b725ae77Skettenis       else if (cache->frameless)
1731b725ae77Skettenis 	{
1732b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
1733b725ae77Skettenis 	  pc = extract_unsigned_integer (buf, 8);
1734b725ae77Skettenis 	}
1735b725ae77Skettenis       pc &= ~0xf;
1736b725ae77Skettenis       store_unsigned_integer (valuep, 8, pc);
1737b725ae77Skettenis     }
1738b725ae77Skettenis   else if (regnum == IA64_PSR_REGNUM)
1739b725ae77Skettenis     {
1740b725ae77Skettenis       /* We don't know how to get the complete previous PSR, but we need it for
1741b725ae77Skettenis 	 the slot information when we unwind the pc (pc is formed of IP register
1742b725ae77Skettenis 	 plus slot information from PSR).  To get the previous slot information,
1743b725ae77Skettenis 	 we mask it off the return address.  */
1744b725ae77Skettenis       ULONGEST slot_num = 0;
1745b725ae77Skettenis       CORE_ADDR pc= 0;
1746b725ae77Skettenis       CORE_ADDR psr = 0;
1747b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1748b725ae77Skettenis 
1749b725ae77Skettenis       frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
1750b725ae77Skettenis       psr = extract_unsigned_integer (buf, 8);
1751b725ae77Skettenis 
1752b725ae77Skettenis       if (addr != 0)
1753b725ae77Skettenis 	{
1754b725ae77Skettenis 	  *lvalp = lval_memory;
1755b725ae77Skettenis 	  *addrp = addr;
1756b725ae77Skettenis 	  read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1757b725ae77Skettenis 	  pc = extract_unsigned_integer (buf, 8);
1758b725ae77Skettenis 	}
1759b725ae77Skettenis       else if (cache->frameless)
1760b725ae77Skettenis 	{
1761b725ae77Skettenis 	  CORE_ADDR pc;
1762b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
1763b725ae77Skettenis 	  pc = extract_unsigned_integer (buf, 8);
1764b725ae77Skettenis 	}
1765b725ae77Skettenis       psr &= ~(3LL << 41);
1766b725ae77Skettenis       slot_num = pc & 0x3LL;
1767b725ae77Skettenis       psr |= (CORE_ADDR)slot_num << 41;
1768b725ae77Skettenis       store_unsigned_integer (valuep, 8, psr);
1769b725ae77Skettenis     }
1770b725ae77Skettenis   else if (regnum == IA64_BR0_REGNUM)
1771b725ae77Skettenis     {
1772b725ae77Skettenis       CORE_ADDR br0 = 0;
1773b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
1774b725ae77Skettenis       if (addr != 0)
1775b725ae77Skettenis 	{
1776b725ae77Skettenis 	  *lvalp = lval_memory;
1777b725ae77Skettenis 	  *addrp = addr;
1778b725ae77Skettenis 	  read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM));
1779b725ae77Skettenis 	  br0 = extract_unsigned_integer (buf, 8);
1780b725ae77Skettenis 	}
1781b725ae77Skettenis       store_unsigned_integer (valuep, 8, br0);
1782b725ae77Skettenis     }
1783b725ae77Skettenis  else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
1784b725ae77Skettenis 	   (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
1785b725ae77Skettenis     {
1786b725ae77Skettenis       CORE_ADDR addr = 0;
1787b725ae77Skettenis       if (regnum >= V32_REGNUM)
1788b725ae77Skettenis 	regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
1789b725ae77Skettenis       addr = cache->saved_regs[regnum];
1790b725ae77Skettenis       if (addr != 0)
1791b725ae77Skettenis 	{
1792b725ae77Skettenis 	  *lvalp = lval_memory;
1793b725ae77Skettenis 	  *addrp = addr;
1794b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1795b725ae77Skettenis 	}
1796b725ae77Skettenis       else if (cache->frameless)
1797b725ae77Skettenis         {
1798b725ae77Skettenis 	  char r_valuep[MAX_REGISTER_SIZE];
1799b725ae77Skettenis 	  int  r_optim;
1800b725ae77Skettenis 	  int  r_realnum;
1801b725ae77Skettenis 	  enum lval_type r_lval;
1802b725ae77Skettenis 	  CORE_ADDR r_addr;
1803b725ae77Skettenis 	  CORE_ADDR prev_cfm, prev_bsp, prev_bof;
1804b725ae77Skettenis 	  CORE_ADDR addr = 0;
1805b725ae77Skettenis 	  if (regnum >= V32_REGNUM)
1806b725ae77Skettenis 	    regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
1807b725ae77Skettenis 	  ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
1808b725ae77Skettenis 				    &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
1809b725ae77Skettenis 	  prev_cfm = extract_unsigned_integer (r_valuep, 8);
1810b725ae77Skettenis 	  ia64_frame_prev_register (next_frame, this_cache, IA64_BSP_REGNUM,
1811b725ae77Skettenis 				    &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
1812b725ae77Skettenis 	  prev_bsp = extract_unsigned_integer (r_valuep, 8);
1813b725ae77Skettenis 	  prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
1814b725ae77Skettenis 
1815b725ae77Skettenis 	  addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
1816b725ae77Skettenis 	  *lvalp = lval_memory;
1817b725ae77Skettenis 	  *addrp = addr;
1818b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1819b725ae77Skettenis         }
1820b725ae77Skettenis     }
1821b725ae77Skettenis   else
1822b725ae77Skettenis     {
1823b725ae77Skettenis       CORE_ADDR addr = 0;
1824b725ae77Skettenis       if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
1825b725ae77Skettenis 	{
1826b725ae77Skettenis 	  /* Fetch floating point register rename base from current
1827b725ae77Skettenis 	     frame marker for this frame.  */
1828b725ae77Skettenis 	  int rrb_fr = (cache->cfm >> 25) & 0x7f;
1829b725ae77Skettenis 
1830b725ae77Skettenis 	  /* Adjust the floating point register number to account for
1831b725ae77Skettenis 	     register rotation.  */
1832b725ae77Skettenis 	  regnum = IA64_FR32_REGNUM
1833b725ae77Skettenis 	         + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96;
1834b725ae77Skettenis 	}
1835b725ae77Skettenis 
1836b725ae77Skettenis       /* If we have stored a memory address, access the register.  */
1837b725ae77Skettenis       addr = cache->saved_regs[regnum];
1838b725ae77Skettenis       if (addr != 0)
1839b725ae77Skettenis 	{
1840b725ae77Skettenis 	  *lvalp = lval_memory;
1841b725ae77Skettenis 	  *addrp = addr;
1842b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1843b725ae77Skettenis 	}
1844b725ae77Skettenis       /* Otherwise, punt and get the current value of the register.  */
1845b725ae77Skettenis       else
1846b725ae77Skettenis 	frame_unwind_register (next_frame, regnum, valuep);
1847b725ae77Skettenis     }
1848b725ae77Skettenis 
1849b725ae77Skettenis   if (gdbarch_debug >= 1)
1850b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
1851b725ae77Skettenis 			"regular prev register <%d> <%s> is 0x%s\n", regnum,
1852b725ae77Skettenis 			(((unsigned) regnum <= IA64_NAT127_REGNUM)
1853b725ae77Skettenis 			 ? ia64_register_names[regnum] : "r??"),
1854b725ae77Skettenis 			paddr_nz (extract_unsigned_integer (valuep, 8)));
1855b725ae77Skettenis }
1856b725ae77Skettenis 
1857b725ae77Skettenis static const struct frame_unwind ia64_frame_unwind =
1858b725ae77Skettenis {
1859b725ae77Skettenis   NORMAL_FRAME,
1860b725ae77Skettenis   &ia64_frame_this_id,
1861b725ae77Skettenis   &ia64_frame_prev_register
1862b725ae77Skettenis };
1863b725ae77Skettenis 
1864b725ae77Skettenis static const struct frame_unwind *
ia64_frame_sniffer(struct frame_info * next_frame)1865b725ae77Skettenis ia64_frame_sniffer (struct frame_info *next_frame)
1866b725ae77Skettenis {
1867b725ae77Skettenis   return &ia64_frame_unwind;
1868b725ae77Skettenis }
1869b725ae77Skettenis 
1870b725ae77Skettenis /* Signal trampolines.  */
1871b725ae77Skettenis 
1872b725ae77Skettenis static void
ia64_sigtramp_frame_init_saved_regs(struct ia64_frame_cache * cache)1873b725ae77Skettenis ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
1874b725ae77Skettenis {
1875b725ae77Skettenis   if (SIGCONTEXT_REGISTER_ADDRESS)
1876b725ae77Skettenis     {
1877b725ae77Skettenis       int regno;
1878b725ae77Skettenis 
1879b725ae77Skettenis       cache->saved_regs[IA64_VRAP_REGNUM] =
1880b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_IP_REGNUM);
1881b725ae77Skettenis       cache->saved_regs[IA64_CFM_REGNUM] =
1882b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM);
1883b725ae77Skettenis       cache->saved_regs[IA64_PSR_REGNUM] =
1884b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
1885b725ae77Skettenis       cache->saved_regs[IA64_BSP_REGNUM] =
1886b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
1887b725ae77Skettenis       cache->saved_regs[IA64_RNAT_REGNUM] =
1888b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
1889b725ae77Skettenis       cache->saved_regs[IA64_CCV_REGNUM] =
1890b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CCV_REGNUM);
1891b725ae77Skettenis       cache->saved_regs[IA64_UNAT_REGNUM] =
1892b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_UNAT_REGNUM);
1893b725ae77Skettenis       cache->saved_regs[IA64_FPSR_REGNUM] =
1894b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_FPSR_REGNUM);
1895b725ae77Skettenis       cache->saved_regs[IA64_PFS_REGNUM] =
1896b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PFS_REGNUM);
1897b725ae77Skettenis       cache->saved_regs[IA64_LC_REGNUM] =
1898b725ae77Skettenis 	SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM);
1899b725ae77Skettenis       for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
1900b725ae77Skettenis 	cache->saved_regs[regno] =
1901b725ae77Skettenis 	  SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1902b725ae77Skettenis       for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
1903b725ae77Skettenis 	cache->saved_regs[regno] =
1904b725ae77Skettenis 	  SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1905b725ae77Skettenis       for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
1906b725ae77Skettenis 	cache->saved_regs[regno] =
1907b725ae77Skettenis 	  SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1908b725ae77Skettenis     }
1909b725ae77Skettenis }
1910b725ae77Skettenis 
1911b725ae77Skettenis static struct ia64_frame_cache *
ia64_sigtramp_frame_cache(struct frame_info * next_frame,void ** this_cache)1912b725ae77Skettenis ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
1913b725ae77Skettenis {
1914b725ae77Skettenis   struct ia64_frame_cache *cache;
1915b725ae77Skettenis   CORE_ADDR addr;
1916b725ae77Skettenis   char buf[8];
1917b725ae77Skettenis   int i;
1918b725ae77Skettenis 
1919b725ae77Skettenis   if (*this_cache)
1920b725ae77Skettenis     return *this_cache;
1921b725ae77Skettenis 
1922b725ae77Skettenis   cache = ia64_alloc_frame_cache ();
1923b725ae77Skettenis 
1924b725ae77Skettenis   frame_unwind_register (next_frame, sp_regnum, buf);
1925b725ae77Skettenis   /* Note that frame size is hard-coded below.  We cannot calculate it
1926b725ae77Skettenis      via prologue examination.  */
1927b725ae77Skettenis   cache->base = extract_unsigned_integer (buf, 8) + 16;
1928b725ae77Skettenis 
1929b725ae77Skettenis   frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1930b725ae77Skettenis   cache->bsp = extract_unsigned_integer (buf, 8);
1931b725ae77Skettenis 
1932b725ae77Skettenis   frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
1933b725ae77Skettenis   cache->cfm = extract_unsigned_integer (buf, 8);
1934b725ae77Skettenis   cache->sof = cache->cfm & 0x7f;
1935b725ae77Skettenis 
1936b725ae77Skettenis   ia64_sigtramp_frame_init_saved_regs (cache);
1937b725ae77Skettenis 
1938b725ae77Skettenis   *this_cache = cache;
1939b725ae77Skettenis   return cache;
1940b725ae77Skettenis }
1941b725ae77Skettenis 
1942b725ae77Skettenis static void
ia64_sigtramp_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)1943b725ae77Skettenis ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
1944b725ae77Skettenis 			       void **this_cache, struct frame_id *this_id)
1945b725ae77Skettenis {
1946b725ae77Skettenis   struct ia64_frame_cache *cache =
1947b725ae77Skettenis     ia64_sigtramp_frame_cache (next_frame, this_cache);
1948b725ae77Skettenis 
1949b725ae77Skettenis   (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
1950b725ae77Skettenis   if (gdbarch_debug >= 1)
1951b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
1952b725ae77Skettenis 			"sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
1953b725ae77Skettenis 			paddr_nz (this_id->code_addr),
1954b725ae77Skettenis 			paddr_nz (this_id->stack_addr),
1955b725ae77Skettenis 			paddr_nz (cache->bsp), next_frame);
1956b725ae77Skettenis }
1957b725ae77Skettenis 
1958b725ae77Skettenis static void
ia64_sigtramp_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)1959b725ae77Skettenis ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
1960b725ae77Skettenis 				   void **this_cache,
1961b725ae77Skettenis 				   int regnum, int *optimizedp,
1962b725ae77Skettenis 				   enum lval_type *lvalp, CORE_ADDR *addrp,
1963b725ae77Skettenis 				   int *realnump, void *valuep)
1964b725ae77Skettenis {
1965b725ae77Skettenis   char dummy_valp[MAX_REGISTER_SIZE];
1966b725ae77Skettenis   char buf[MAX_REGISTER_SIZE];
1967b725ae77Skettenis 
1968b725ae77Skettenis   struct ia64_frame_cache *cache =
1969b725ae77Skettenis     ia64_sigtramp_frame_cache (next_frame, this_cache);
1970b725ae77Skettenis 
1971b725ae77Skettenis   gdb_assert (regnum >= 0);
1972b725ae77Skettenis 
1973b725ae77Skettenis   if (!target_has_registers)
1974b725ae77Skettenis     error ("No registers.");
1975b725ae77Skettenis 
1976b725ae77Skettenis   *optimizedp = 0;
1977b725ae77Skettenis   *addrp = 0;
1978b725ae77Skettenis   *lvalp = not_lval;
1979b725ae77Skettenis   *realnump = -1;
1980b725ae77Skettenis 
1981b725ae77Skettenis   /* Rather than check each time if valuep is non-null, supply a dummy buffer
1982b725ae77Skettenis      when valuep is not supplied.  */
1983b725ae77Skettenis   if (!valuep)
1984b725ae77Skettenis     valuep = dummy_valp;
1985b725ae77Skettenis 
1986b725ae77Skettenis   memset (valuep, 0, register_size (current_gdbarch, regnum));
1987b725ae77Skettenis 
1988b725ae77Skettenis   if (regnum == IA64_IP_REGNUM)
1989b725ae77Skettenis     {
1990b725ae77Skettenis       CORE_ADDR pc = 0;
1991b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1992b725ae77Skettenis 
1993b725ae77Skettenis       if (addr != 0)
1994b725ae77Skettenis 	{
1995b725ae77Skettenis 	  *lvalp = lval_memory;
1996b725ae77Skettenis 	  *addrp = addr;
1997b725ae77Skettenis 	  read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1998b725ae77Skettenis 	  pc = extract_unsigned_integer (buf, 8);
1999b725ae77Skettenis 	}
2000b725ae77Skettenis       pc &= ~0xf;
2001b725ae77Skettenis       store_unsigned_integer (valuep, 8, pc);
2002b725ae77Skettenis     }
2003b725ae77Skettenis  else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
2004b725ae77Skettenis 	   (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
2005b725ae77Skettenis     {
2006b725ae77Skettenis       CORE_ADDR addr = 0;
2007b725ae77Skettenis       if (regnum >= V32_REGNUM)
2008b725ae77Skettenis 	regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
2009b725ae77Skettenis       addr = cache->saved_regs[regnum];
2010b725ae77Skettenis       if (addr != 0)
2011b725ae77Skettenis 	{
2012b725ae77Skettenis 	  *lvalp = lval_memory;
2013b725ae77Skettenis 	  *addrp = addr;
2014b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
2015b725ae77Skettenis 	}
2016b725ae77Skettenis     }
2017b725ae77Skettenis   else
2018b725ae77Skettenis     {
2019b725ae77Skettenis       /* All other registers not listed above.  */
2020b725ae77Skettenis       CORE_ADDR addr = cache->saved_regs[regnum];
2021b725ae77Skettenis       if (addr != 0)
2022b725ae77Skettenis 	{
2023b725ae77Skettenis 	  *lvalp = lval_memory;
2024b725ae77Skettenis 	  *addrp = addr;
2025b725ae77Skettenis 	  read_memory (addr, valuep, register_size (current_gdbarch, regnum));
2026b725ae77Skettenis 	}
2027b725ae77Skettenis     }
2028b725ae77Skettenis 
2029b725ae77Skettenis   if (gdbarch_debug >= 1)
2030b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
2031b725ae77Skettenis 			"sigtramp prev register <%s> is 0x%s\n",
2032b725ae77Skettenis 			(((unsigned) regnum <= IA64_NAT127_REGNUM)
2033b725ae77Skettenis 			 ? ia64_register_names[regnum] : "r??"),
2034b725ae77Skettenis 			paddr_nz (extract_unsigned_integer (valuep, 8)));
2035b725ae77Skettenis }
2036b725ae77Skettenis 
2037b725ae77Skettenis static const struct frame_unwind ia64_sigtramp_frame_unwind =
2038b725ae77Skettenis {
2039b725ae77Skettenis   SIGTRAMP_FRAME,
2040b725ae77Skettenis   ia64_sigtramp_frame_this_id,
2041b725ae77Skettenis   ia64_sigtramp_frame_prev_register
2042b725ae77Skettenis };
2043b725ae77Skettenis 
2044b725ae77Skettenis static const struct frame_unwind *
ia64_sigtramp_frame_sniffer(struct frame_info * next_frame)2045b725ae77Skettenis ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
2046b725ae77Skettenis {
2047b725ae77Skettenis   char *name;
2048b725ae77Skettenis   CORE_ADDR pc = frame_pc_unwind (next_frame);
2049b725ae77Skettenis 
2050b725ae77Skettenis   find_pc_partial_function (pc, &name, NULL, NULL);
2051*11efff7fSkettenis   if (legacy_pc_in_sigtramp (pc, name))
2052b725ae77Skettenis     return &ia64_sigtramp_frame_unwind;
2053b725ae77Skettenis 
2054b725ae77Skettenis   return NULL;
2055b725ae77Skettenis }
2056b725ae77Skettenis 
2057b725ae77Skettenis 
2058b725ae77Skettenis static CORE_ADDR
ia64_frame_base_address(struct frame_info * next_frame,void ** this_cache)2059b725ae77Skettenis ia64_frame_base_address (struct frame_info *next_frame, void **this_cache)
2060b725ae77Skettenis {
2061b725ae77Skettenis   struct ia64_frame_cache *cache =
2062b725ae77Skettenis     ia64_frame_cache (next_frame, this_cache);
2063b725ae77Skettenis 
2064b725ae77Skettenis   return cache->base;
2065b725ae77Skettenis }
2066b725ae77Skettenis 
2067b725ae77Skettenis static const struct frame_base ia64_frame_base =
2068b725ae77Skettenis {
2069b725ae77Skettenis   &ia64_frame_unwind,
2070b725ae77Skettenis   ia64_frame_base_address,
2071b725ae77Skettenis   ia64_frame_base_address,
2072b725ae77Skettenis   ia64_frame_base_address
2073b725ae77Skettenis };
2074b725ae77Skettenis 
2075b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
2076b725ae77Skettenis 
2077b725ae77Skettenis struct ia64_unwind_table_entry
2078b725ae77Skettenis   {
2079b725ae77Skettenis     unw_word_t start_offset;
2080b725ae77Skettenis     unw_word_t end_offset;
2081b725ae77Skettenis     unw_word_t info_offset;
2082b725ae77Skettenis   };
2083b725ae77Skettenis 
2084b725ae77Skettenis static __inline__ uint64_t
ia64_rse_slot_num(uint64_t addr)2085b725ae77Skettenis ia64_rse_slot_num (uint64_t addr)
2086b725ae77Skettenis {
2087b725ae77Skettenis   return (addr >> 3) & 0x3f;
2088b725ae77Skettenis }
2089b725ae77Skettenis 
2090b725ae77Skettenis /* Skip over a designated number of registers in the backing
2091b725ae77Skettenis    store, remembering every 64th position is for NAT.  */
2092b725ae77Skettenis static __inline__ uint64_t
ia64_rse_skip_regs(uint64_t addr,long num_regs)2093b725ae77Skettenis ia64_rse_skip_regs (uint64_t addr, long num_regs)
2094b725ae77Skettenis {
2095b725ae77Skettenis   long delta = ia64_rse_slot_num(addr) + num_regs;
2096b725ae77Skettenis 
2097b725ae77Skettenis   if (num_regs < 0)
2098b725ae77Skettenis     delta -= 0x3e;
2099b725ae77Skettenis   return addr + ((num_regs + delta/0x3f) << 3);
2100b725ae77Skettenis }
2101b725ae77Skettenis 
2102b725ae77Skettenis /* Gdb libunwind-frame callback function to convert from an ia64 gdb register
2103b725ae77Skettenis    number to a libunwind register number.  */
2104b725ae77Skettenis static int
ia64_gdb2uw_regnum(int regnum)2105b725ae77Skettenis ia64_gdb2uw_regnum (int regnum)
2106b725ae77Skettenis {
2107b725ae77Skettenis   if (regnum == sp_regnum)
2108b725ae77Skettenis     return UNW_IA64_SP;
2109b725ae77Skettenis   else if (regnum == IA64_BSP_REGNUM)
2110b725ae77Skettenis     return UNW_IA64_BSP;
2111b725ae77Skettenis   else if ((unsigned) (regnum - IA64_GR0_REGNUM) < 128)
2112b725ae77Skettenis     return UNW_IA64_GR + (regnum - IA64_GR0_REGNUM);
2113b725ae77Skettenis   else if ((unsigned) (regnum - V32_REGNUM) < 95)
2114b725ae77Skettenis     return UNW_IA64_GR + 32 + (regnum - V32_REGNUM);
2115b725ae77Skettenis   else if ((unsigned) (regnum - IA64_FR0_REGNUM) < 128)
2116b725ae77Skettenis     return UNW_IA64_FR + (regnum - IA64_FR0_REGNUM);
2117b725ae77Skettenis   else if ((unsigned) (regnum - IA64_PR0_REGNUM) < 64)
2118b725ae77Skettenis     return -1;
2119b725ae77Skettenis   else if ((unsigned) (regnum - IA64_BR0_REGNUM) < 8)
2120b725ae77Skettenis     return UNW_IA64_BR + (regnum - IA64_BR0_REGNUM);
2121b725ae77Skettenis   else if (regnum == IA64_PR_REGNUM)
2122b725ae77Skettenis     return UNW_IA64_PR;
2123b725ae77Skettenis   else if (regnum == IA64_IP_REGNUM)
2124b725ae77Skettenis     return UNW_REG_IP;
2125b725ae77Skettenis   else if (regnum == IA64_CFM_REGNUM)
2126b725ae77Skettenis     return UNW_IA64_CFM;
2127b725ae77Skettenis   else if ((unsigned) (regnum - IA64_AR0_REGNUM) < 128)
2128b725ae77Skettenis     return UNW_IA64_AR + (regnum - IA64_AR0_REGNUM);
2129b725ae77Skettenis   else if ((unsigned) (regnum - IA64_NAT0_REGNUM) < 128)
2130b725ae77Skettenis     return UNW_IA64_NAT + (regnum - IA64_NAT0_REGNUM);
2131b725ae77Skettenis   else
2132b725ae77Skettenis     return -1;
2133b725ae77Skettenis }
2134b725ae77Skettenis 
2135b725ae77Skettenis /* Gdb libunwind-frame callback function to convert from a libunwind register
2136b725ae77Skettenis    number to a ia64 gdb register number.  */
2137b725ae77Skettenis static int
ia64_uw2gdb_regnum(int uw_regnum)2138b725ae77Skettenis ia64_uw2gdb_regnum (int uw_regnum)
2139b725ae77Skettenis {
2140b725ae77Skettenis   if (uw_regnum == UNW_IA64_SP)
2141b725ae77Skettenis     return sp_regnum;
2142b725ae77Skettenis   else if (uw_regnum == UNW_IA64_BSP)
2143b725ae77Skettenis     return IA64_BSP_REGNUM;
2144b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 32)
2145b725ae77Skettenis     return IA64_GR0_REGNUM + (uw_regnum - UNW_IA64_GR);
2146b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 128)
2147b725ae77Skettenis     return V32_REGNUM + (uw_regnum - (IA64_GR0_REGNUM + 32));
2148b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_FR) < 128)
2149b725ae77Skettenis     return IA64_FR0_REGNUM + (uw_regnum - UNW_IA64_FR);
2150b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_BR) < 8)
2151b725ae77Skettenis     return IA64_BR0_REGNUM + (uw_regnum - UNW_IA64_BR);
2152b725ae77Skettenis   else if (uw_regnum == UNW_IA64_PR)
2153b725ae77Skettenis     return IA64_PR_REGNUM;
2154b725ae77Skettenis   else if (uw_regnum == UNW_REG_IP)
2155b725ae77Skettenis     return IA64_IP_REGNUM;
2156b725ae77Skettenis   else if (uw_regnum == UNW_IA64_CFM)
2157b725ae77Skettenis     return IA64_CFM_REGNUM;
2158b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_AR) < 128)
2159b725ae77Skettenis     return IA64_AR0_REGNUM + (uw_regnum - UNW_IA64_AR);
2160b725ae77Skettenis   else if ((unsigned) (uw_regnum - UNW_IA64_NAT) < 128)
2161b725ae77Skettenis     return IA64_NAT0_REGNUM + (uw_regnum - UNW_IA64_NAT);
2162b725ae77Skettenis   else
2163b725ae77Skettenis     return -1;
2164b725ae77Skettenis }
2165b725ae77Skettenis 
2166b725ae77Skettenis /* Gdb libunwind-frame callback function to reveal if register is a float
2167b725ae77Skettenis    register or not.  */
2168b725ae77Skettenis static int
ia64_is_fpreg(int uw_regnum)2169b725ae77Skettenis ia64_is_fpreg (int uw_regnum)
2170b725ae77Skettenis {
2171b725ae77Skettenis   return unw_is_fpreg (uw_regnum);
2172b725ae77Skettenis }
2173b725ae77Skettenis 
2174b725ae77Skettenis /* Libunwind callback accessor function for general registers.  */
2175b725ae77Skettenis static int
ia64_access_reg(unw_addr_space_t as,unw_regnum_t uw_regnum,unw_word_t * val,int write,void * arg)2176b725ae77Skettenis ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
2177b725ae77Skettenis 		 int write, void *arg)
2178b725ae77Skettenis {
2179b725ae77Skettenis   int regnum = ia64_uw2gdb_regnum (uw_regnum);
2180b725ae77Skettenis   unw_word_t bsp, sof, sol, cfm, psr, ip;
2181b725ae77Skettenis   struct frame_info *next_frame = arg;
2182b725ae77Skettenis   long new_sof, old_sof;
2183b725ae77Skettenis   char buf[MAX_REGISTER_SIZE];
2184b725ae77Skettenis 
2185b725ae77Skettenis   if (write)
2186b725ae77Skettenis     {
2187b725ae77Skettenis       if (regnum < 0)
2188b725ae77Skettenis 	/* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI.  */
2189b725ae77Skettenis 	return 0;
2190b725ae77Skettenis 
2191b725ae77Skettenis       switch (uw_regnum)
2192b725ae77Skettenis 	{
2193b725ae77Skettenis 	case UNW_REG_IP:
2194b725ae77Skettenis 	  ia64_write_pc (*val, inferior_ptid);
2195b725ae77Skettenis 	  break;
2196b725ae77Skettenis 
2197b725ae77Skettenis 	case UNW_IA64_AR_BSPSTORE:
2198b725ae77Skettenis 	  write_register (IA64_BSP_REGNUM, *val);
2199b725ae77Skettenis 	  break;
2200b725ae77Skettenis 
2201b725ae77Skettenis 	case UNW_IA64_AR_BSP:
2202b725ae77Skettenis 	case UNW_IA64_BSP:
2203b725ae77Skettenis 	  /* Account for the fact that ptrace() expects bsp to point
2204b725ae77Skettenis 	     after the current register frame.  */
2205b725ae77Skettenis 	  cfm = read_register (IA64_CFM_REGNUM);
2206b725ae77Skettenis 	  sof = (cfm & 0x7f);
2207b725ae77Skettenis 	  bsp = ia64_rse_skip_regs (*val, sof);
2208b725ae77Skettenis 	  write_register (IA64_BSP_REGNUM, bsp);
2209b725ae77Skettenis 	  break;
2210b725ae77Skettenis 
2211b725ae77Skettenis 	case UNW_IA64_CFM:
2212b725ae77Skettenis 	  /* If we change CFM, we need to adjust ptrace's notion of
2213b725ae77Skettenis 	     bsp accordingly, so that the real bsp remains
2214b725ae77Skettenis 	     unchanged.  */
2215b725ae77Skettenis 	  bsp = read_register (IA64_BSP_REGNUM);
2216b725ae77Skettenis 	  cfm = read_register (IA64_CFM_REGNUM);
2217b725ae77Skettenis 	  old_sof = (cfm & 0x7f);
2218b725ae77Skettenis 	  new_sof = (*val & 0x7f);
2219b725ae77Skettenis 	  if (old_sof != new_sof)
2220b725ae77Skettenis 	    {
2221b725ae77Skettenis 	      bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
2222b725ae77Skettenis 	      write_register (IA64_BSP_REGNUM, bsp);
2223b725ae77Skettenis 	    }
2224b725ae77Skettenis 	  write_register (IA64_CFM_REGNUM, *val);
2225b725ae77Skettenis 	  break;
2226b725ae77Skettenis 
2227b725ae77Skettenis 	default:
2228b725ae77Skettenis 	  write_register (regnum, *val);
2229b725ae77Skettenis 	  break;
2230b725ae77Skettenis 	}
2231b725ae77Skettenis       if (gdbarch_debug >= 1)
2232b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog,
2233b725ae77Skettenis 			    "  access_reg: to cache: %4s=0x%s\n",
2234b725ae77Skettenis 			    (((unsigned) regnum <= IA64_NAT127_REGNUM)
2235b725ae77Skettenis 			     ? ia64_register_names[regnum] : "r??"),
2236b725ae77Skettenis 			    paddr_nz (*val));
2237b725ae77Skettenis     }
2238b725ae77Skettenis   else
2239b725ae77Skettenis     {
2240b725ae77Skettenis       switch (uw_regnum)
2241b725ae77Skettenis 	{
2242b725ae77Skettenis 	case UNW_REG_IP:
2243b725ae77Skettenis 	  /* Libunwind expects to see the pc value which means the slot number
2244b725ae77Skettenis 	     from the psr must be merged with the ip word address.  */
2245b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
2246b725ae77Skettenis 	  ip = extract_unsigned_integer (buf, 8);
2247b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
2248b725ae77Skettenis 	  psr = extract_unsigned_integer (buf, 8);
2249b725ae77Skettenis 	  *val = ip | ((psr >> 41) & 0x3);
2250b725ae77Skettenis 	  break;
2251b725ae77Skettenis 
2252b725ae77Skettenis 	case UNW_IA64_AR_BSP:
2253b725ae77Skettenis 	  /* Libunwind expects to see the beginning of the current register
2254b725ae77Skettenis 	     frame so we must account for the fact that ptrace() will return a value
2255b725ae77Skettenis 	     for bsp that points *after* the current register frame.  */
2256b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2257b725ae77Skettenis 	  bsp = extract_unsigned_integer (buf, 8);
2258b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
2259b725ae77Skettenis 	  cfm = extract_unsigned_integer (buf, 8);
2260b725ae77Skettenis 	  sof = (cfm & 0x7f);
2261b725ae77Skettenis 	  *val = ia64_rse_skip_regs (bsp, -sof);
2262b725ae77Skettenis 	  break;
2263b725ae77Skettenis 
2264b725ae77Skettenis 	case UNW_IA64_AR_BSPSTORE:
2265b725ae77Skettenis 	  /* Libunwind wants bspstore to be after the current register frame.
2266b725ae77Skettenis 	     This is what ptrace() and gdb treats as the regular bsp value.  */
2267b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2268b725ae77Skettenis 	  *val = extract_unsigned_integer (buf, 8);
2269b725ae77Skettenis 	  break;
2270b725ae77Skettenis 
2271b725ae77Skettenis 	default:
2272b725ae77Skettenis 	  /* For all other registers, just unwind the value directly.  */
2273b725ae77Skettenis 	  frame_unwind_register (next_frame, regnum, buf);
2274b725ae77Skettenis 	  *val = extract_unsigned_integer (buf, 8);
2275b725ae77Skettenis 	  break;
2276b725ae77Skettenis 	}
2277b725ae77Skettenis 
2278b725ae77Skettenis       if (gdbarch_debug >= 1)
2279b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog,
2280b725ae77Skettenis 			    "  access_reg: from cache: %4s=0x%s\n",
2281b725ae77Skettenis 			    (((unsigned) regnum <= IA64_NAT127_REGNUM)
2282b725ae77Skettenis 			     ? ia64_register_names[regnum] : "r??"),
2283b725ae77Skettenis 			    paddr_nz (*val));
2284b725ae77Skettenis     }
2285b725ae77Skettenis   return 0;
2286b725ae77Skettenis }
2287b725ae77Skettenis 
2288b725ae77Skettenis /* Libunwind callback accessor function for floating-point registers.  */
2289b725ae77Skettenis static int
ia64_access_fpreg(unw_addr_space_t as,unw_regnum_t uw_regnum,unw_fpreg_t * val,int write,void * arg)2290b725ae77Skettenis ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val,
2291b725ae77Skettenis 		   int write, void *arg)
2292b725ae77Skettenis {
2293b725ae77Skettenis   int regnum = ia64_uw2gdb_regnum (uw_regnum);
2294b725ae77Skettenis 
2295b725ae77Skettenis   if (write)
2296b725ae77Skettenis     regcache_cooked_write (current_regcache, regnum, (char *) val);
2297b725ae77Skettenis   else
2298b725ae77Skettenis     regcache_cooked_read (current_regcache, regnum, (char *) val);
2299b725ae77Skettenis   return 0;
2300b725ae77Skettenis }
2301b725ae77Skettenis 
2302b725ae77Skettenis /* Libunwind callback accessor function for accessing memory.  */
2303b725ae77Skettenis static int
ia64_access_mem(unw_addr_space_t as,unw_word_t addr,unw_word_t * val,int write,void * arg)2304b725ae77Skettenis ia64_access_mem (unw_addr_space_t as,
2305b725ae77Skettenis 		 unw_word_t addr, unw_word_t *val,
2306b725ae77Skettenis 		 int write, void *arg)
2307b725ae77Skettenis {
2308b725ae77Skettenis   /* XXX do we need to normalize byte-order here?  */
2309b725ae77Skettenis   if (write)
2310b725ae77Skettenis     return target_write_memory (addr, (char *) val, sizeof (unw_word_t));
2311b725ae77Skettenis   else
2312b725ae77Skettenis     return target_read_memory (addr, (char *) val, sizeof (unw_word_t));
2313b725ae77Skettenis }
2314b725ae77Skettenis 
2315b725ae77Skettenis /* Call low-level function to access the kernel unwind table.  */
2316b725ae77Skettenis static int
getunwind_table(void * buf,size_t len)2317b725ae77Skettenis getunwind_table (void *buf, size_t len)
2318b725ae77Skettenis {
2319b725ae77Skettenis   LONGEST x;
2320b725ae77Skettenis   x = target_read_partial (&current_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
2321b725ae77Skettenis 			   buf, 0, len);
2322b725ae77Skettenis 
2323b725ae77Skettenis   return (int)x;
2324b725ae77Skettenis }
2325b725ae77Skettenis 
2326b725ae77Skettenis /* Get the kernel unwind table.  */
2327b725ae77Skettenis static int
get_kernel_table(unw_word_t ip,unw_dyn_info_t * di)2328b725ae77Skettenis get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
2329b725ae77Skettenis {
2330b725ae77Skettenis   size_t size;
2331b725ae77Skettenis   struct ia64_table_entry
2332b725ae77Skettenis   {
2333b725ae77Skettenis     uint64_t start_offset;
2334b725ae77Skettenis     uint64_t end_offset;
2335b725ae77Skettenis     uint64_t info_offset;
2336b725ae77Skettenis   };
2337b725ae77Skettenis   static struct ia64_table_entry *ktab = NULL, *etab;
2338b725ae77Skettenis 
2339b725ae77Skettenis   if (!ktab)
2340b725ae77Skettenis     {
2341b725ae77Skettenis       size = getunwind_table (NULL, 0);
2342b725ae77Skettenis       if ((int)size < 0)
2343b725ae77Skettenis 	return -UNW_ENOINFO;
2344b725ae77Skettenis       ktab = xmalloc (size);
2345b725ae77Skettenis       getunwind_table (ktab, size);
2346b725ae77Skettenis 
2347b725ae77Skettenis       /* Determine length of kernel's unwind table and relocate
2348b725ae77Skettenis 	 it's entries.  */
2349b725ae77Skettenis       for (etab = ktab; etab->start_offset; ++etab)
2350b725ae77Skettenis 	etab->info_offset += (uint64_t) ktab;
2351b725ae77Skettenis     }
2352b725ae77Skettenis 
2353b725ae77Skettenis   if (ip < ktab[0].start_offset || ip >= etab[-1].end_offset)
2354b725ae77Skettenis     return -UNW_ENOINFO;
2355b725ae77Skettenis 
2356b725ae77Skettenis   di->format = UNW_INFO_FORMAT_TABLE;
2357b725ae77Skettenis   di->gp = 0;
2358b725ae77Skettenis   di->start_ip = ktab[0].start_offset;
2359b725ae77Skettenis   di->end_ip = etab[-1].end_offset;
2360b725ae77Skettenis   di->u.ti.name_ptr = (unw_word_t) "<kernel>";
2361b725ae77Skettenis   di->u.ti.segbase = 0;
2362b725ae77Skettenis   di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t);
2363b725ae77Skettenis   di->u.ti.table_data = (unw_word_t *) ktab;
2364b725ae77Skettenis 
2365b725ae77Skettenis   if (gdbarch_debug >= 1)
2366b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': "
2367b725ae77Skettenis 			"segbase=0x%s, length=%s, gp=0x%s\n",
2368b725ae77Skettenis 			(char *) di->u.ti.name_ptr,
2369b725ae77Skettenis 			paddr_nz (di->u.ti.segbase),
2370b725ae77Skettenis 			paddr_u (di->u.ti.table_len),
2371b725ae77Skettenis 			paddr_nz (di->gp));
2372b725ae77Skettenis   return 0;
2373b725ae77Skettenis }
2374b725ae77Skettenis 
2375b725ae77Skettenis /* Find the unwind table entry for a specified address.  */
2376b725ae77Skettenis static int
ia64_find_unwind_table(struct objfile * objfile,unw_word_t ip,unw_dyn_info_t * dip,void ** buf)2377b725ae77Skettenis ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
2378b725ae77Skettenis 			unw_dyn_info_t *dip, void **buf)
2379b725ae77Skettenis {
2380b725ae77Skettenis   Elf_Internal_Phdr *phdr, *p_text = NULL, *p_unwind = NULL;
2381b725ae77Skettenis   Elf_Internal_Ehdr *ehdr;
2382b725ae77Skettenis   unw_word_t segbase = 0;
2383b725ae77Skettenis   CORE_ADDR load_base;
2384b725ae77Skettenis   bfd *bfd;
2385b725ae77Skettenis   int i;
2386b725ae77Skettenis 
2387b725ae77Skettenis   bfd = objfile->obfd;
2388b725ae77Skettenis 
2389b725ae77Skettenis   ehdr = elf_tdata (bfd)->elf_header;
2390b725ae77Skettenis   phdr = elf_tdata (bfd)->phdr;
2391b725ae77Skettenis 
2392b725ae77Skettenis   load_base = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
2393b725ae77Skettenis 
2394b725ae77Skettenis   for (i = 0; i < ehdr->e_phnum; ++i)
2395b725ae77Skettenis     {
2396b725ae77Skettenis       switch (phdr[i].p_type)
2397b725ae77Skettenis 	{
2398b725ae77Skettenis 	case PT_LOAD:
2399b725ae77Skettenis 	  if ((unw_word_t) (ip - load_base - phdr[i].p_vaddr)
2400b725ae77Skettenis 	      < phdr[i].p_memsz)
2401b725ae77Skettenis 	    p_text = phdr + i;
2402b725ae77Skettenis 	  break;
2403b725ae77Skettenis 
2404b725ae77Skettenis 	case PT_IA_64_UNWIND:
2405b725ae77Skettenis 	  p_unwind = phdr + i;
2406b725ae77Skettenis 	  break;
2407b725ae77Skettenis 
2408b725ae77Skettenis 	default:
2409b725ae77Skettenis 	  break;
2410b725ae77Skettenis 	}
2411b725ae77Skettenis     }
2412b725ae77Skettenis 
2413b725ae77Skettenis   if (!p_text || !p_unwind
2414b725ae77Skettenis       /* Verify that the segment that contains the IP also contains
2415b725ae77Skettenis 	 the static unwind table.  If not, we are dealing with
2416b725ae77Skettenis 	 runtime-generated code, for which we have no info here.  */
2417b725ae77Skettenis       || (p_unwind->p_vaddr - p_text->p_vaddr) >= p_text->p_memsz)
2418b725ae77Skettenis     return -UNW_ENOINFO;
2419b725ae77Skettenis 
2420b725ae77Skettenis   segbase = p_text->p_vaddr + load_base;
2421b725ae77Skettenis 
2422b725ae77Skettenis   dip->start_ip = segbase;
2423b725ae77Skettenis   dip->end_ip = dip->start_ip + p_text->p_memsz;
2424b725ae77Skettenis   dip->gp = FIND_GLOBAL_POINTER (ip);
2425b725ae77Skettenis   dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
2426b725ae77Skettenis   dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
2427b725ae77Skettenis   dip->u.rti.segbase = segbase;
2428b725ae77Skettenis   dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t);
2429b725ae77Skettenis   dip->u.rti.table_data = p_unwind->p_vaddr + load_base;
2430b725ae77Skettenis 
2431b725ae77Skettenis   return 0;
2432b725ae77Skettenis }
2433b725ae77Skettenis 
2434b725ae77Skettenis /* Libunwind callback accessor function to acquire procedure unwind-info.  */
2435b725ae77Skettenis static int
ia64_find_proc_info_x(unw_addr_space_t as,unw_word_t ip,unw_proc_info_t * pi,int need_unwind_info,void * arg)2436b725ae77Skettenis ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
2437b725ae77Skettenis 		       int need_unwind_info, void *arg)
2438b725ae77Skettenis {
2439b725ae77Skettenis   struct obj_section *sec = find_pc_section (ip);
2440b725ae77Skettenis   unw_dyn_info_t di;
2441b725ae77Skettenis   int ret;
2442b725ae77Skettenis   void *buf = NULL;
2443b725ae77Skettenis 
2444b725ae77Skettenis   if (!sec)
2445b725ae77Skettenis     {
2446b725ae77Skettenis       /* XXX This only works if the host and the target architecture are
2447b725ae77Skettenis 	 both ia64 and if the have (more or less) the same kernel
2448b725ae77Skettenis 	 version.  */
2449b725ae77Skettenis       if (get_kernel_table (ip, &di) < 0)
2450b725ae77Skettenis 	return -UNW_ENOINFO;
2451b725ae77Skettenis 
2452b725ae77Skettenis       if (gdbarch_debug >= 1)
2453b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
2454b725ae77Skettenis 			    "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
2455b725ae77Skettenis 			    "length=%s,data=0x%s)\n",
2456b725ae77Skettenis 			    paddr_nz (ip), (char *)di.u.ti.name_ptr,
2457b725ae77Skettenis 			    paddr_nz (di.u.ti.segbase),
2458b725ae77Skettenis 			    paddr_nz (di.start_ip), paddr_nz (di.end_ip),
2459b725ae77Skettenis 			    paddr_nz (di.gp),
2460b725ae77Skettenis 			    paddr_u (di.u.ti.table_len),
2461b725ae77Skettenis 			    paddr_nz ((CORE_ADDR)di.u.ti.table_data));
2462b725ae77Skettenis     }
2463b725ae77Skettenis   else
2464b725ae77Skettenis     {
2465b725ae77Skettenis       ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf);
2466b725ae77Skettenis       if (ret < 0)
2467b725ae77Skettenis 	return ret;
2468b725ae77Skettenis 
2469b725ae77Skettenis       if (gdbarch_debug >= 1)
2470b725ae77Skettenis 	fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
2471b725ae77Skettenis 			    "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
2472b725ae77Skettenis 			    "length=%s,data=0x%s)\n",
2473b725ae77Skettenis 			    paddr_nz (ip), (char *)di.u.rti.name_ptr,
2474b725ae77Skettenis 			    paddr_nz (di.u.rti.segbase),
2475b725ae77Skettenis 			    paddr_nz (di.start_ip), paddr_nz (di.end_ip),
2476b725ae77Skettenis 			    paddr_nz (di.gp),
2477b725ae77Skettenis 			    paddr_u (di.u.rti.table_len),
2478b725ae77Skettenis 			    paddr_nz (di.u.rti.table_data));
2479b725ae77Skettenis     }
2480b725ae77Skettenis 
2481b725ae77Skettenis   ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
2482b725ae77Skettenis 				       arg);
2483b725ae77Skettenis 
2484b725ae77Skettenis   /* We no longer need the dyn info storage so free it.  */
2485b725ae77Skettenis   xfree (buf);
2486b725ae77Skettenis 
2487b725ae77Skettenis   return ret;
2488b725ae77Skettenis }
2489b725ae77Skettenis 
2490b725ae77Skettenis /* Libunwind callback accessor function for cleanup.  */
2491b725ae77Skettenis static void
ia64_put_unwind_info(unw_addr_space_t as,unw_proc_info_t * pip,void * arg)2492b725ae77Skettenis ia64_put_unwind_info (unw_addr_space_t as,
2493b725ae77Skettenis 		      unw_proc_info_t *pip, void *arg)
2494b725ae77Skettenis {
2495b725ae77Skettenis   /* Nothing required for now.  */
2496b725ae77Skettenis }
2497b725ae77Skettenis 
2498b725ae77Skettenis /* Libunwind callback accessor function to get head of the dynamic
2499b725ae77Skettenis    unwind-info registration list.  */
2500b725ae77Skettenis static int
ia64_get_dyn_info_list(unw_addr_space_t as,unw_word_t * dilap,void * arg)2501b725ae77Skettenis ia64_get_dyn_info_list (unw_addr_space_t as,
2502b725ae77Skettenis 			unw_word_t *dilap, void *arg)
2503b725ae77Skettenis {
2504b725ae77Skettenis   struct obj_section *text_sec;
2505b725ae77Skettenis   struct objfile *objfile;
2506b725ae77Skettenis   unw_word_t ip, addr;
2507b725ae77Skettenis   unw_dyn_info_t di;
2508b725ae77Skettenis   int ret;
2509b725ae77Skettenis 
2510b725ae77Skettenis   if (!libunwind_is_initialized ())
2511b725ae77Skettenis     return -UNW_ENOINFO;
2512b725ae77Skettenis 
2513b725ae77Skettenis   for (objfile = object_files; objfile; objfile = objfile->next)
2514b725ae77Skettenis     {
2515b725ae77Skettenis       void *buf = NULL;
2516b725ae77Skettenis 
2517b725ae77Skettenis       text_sec = objfile->sections + SECT_OFF_TEXT (objfile);
2518b725ae77Skettenis       ip = text_sec->addr;
2519b725ae77Skettenis       ret = ia64_find_unwind_table (objfile, ip, &di, &buf);
2520b725ae77Skettenis       if (ret >= 0)
2521b725ae77Skettenis 	{
2522b725ae77Skettenis 	  addr = libunwind_find_dyn_list (as, &di, arg);
2523b725ae77Skettenis 	  /* We no longer need the dyn info storage so free it.  */
2524b725ae77Skettenis 	  xfree (buf);
2525b725ae77Skettenis 
2526b725ae77Skettenis 	  if (addr)
2527b725ae77Skettenis 	    {
2528b725ae77Skettenis 	      if (gdbarch_debug >= 1)
2529b725ae77Skettenis 		fprintf_unfiltered (gdb_stdlog,
2530b725ae77Skettenis 				    "dynamic unwind table in objfile %s "
2531b725ae77Skettenis 				    "at 0x%s (gp=0x%s)\n",
2532b725ae77Skettenis 				    bfd_get_filename (objfile->obfd),
2533b725ae77Skettenis 				    paddr_nz (addr), paddr_nz (di.gp));
2534b725ae77Skettenis 	      *dilap = addr;
2535b725ae77Skettenis 	      return 0;
2536b725ae77Skettenis 	    }
2537b725ae77Skettenis 	}
2538b725ae77Skettenis     }
2539b725ae77Skettenis   return -UNW_ENOINFO;
2540b725ae77Skettenis }
2541b725ae77Skettenis 
2542b725ae77Skettenis 
2543b725ae77Skettenis /* Frame interface functions for libunwind.  */
2544b725ae77Skettenis 
2545b725ae77Skettenis static void
ia64_libunwind_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)2546b725ae77Skettenis ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
2547b725ae77Skettenis 		      struct frame_id *this_id)
2548b725ae77Skettenis {
2549b725ae77Skettenis   char buf[8];
2550b725ae77Skettenis   CORE_ADDR bsp;
2551b725ae77Skettenis   struct frame_id id;
2552b725ae77Skettenis 
2553b725ae77Skettenis   libunwind_frame_this_id (next_frame, this_cache, &id);
2554b725ae77Skettenis 
2555b725ae77Skettenis   /* We must add the bsp as the special address for frame comparison purposes.  */
2556b725ae77Skettenis   frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2557b725ae77Skettenis   bsp = extract_unsigned_integer (buf, 8);
2558b725ae77Skettenis 
2559b725ae77Skettenis   (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
2560b725ae77Skettenis 
2561b725ae77Skettenis   if (gdbarch_debug >= 1)
2562b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
2563b725ae77Skettenis 			"libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
2564b725ae77Skettenis 			paddr_nz (id.code_addr), paddr_nz (id.stack_addr),
2565b725ae77Skettenis 			paddr_nz (bsp), next_frame);
2566b725ae77Skettenis }
2567b725ae77Skettenis 
2568b725ae77Skettenis static void
ia64_libunwind_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)2569b725ae77Skettenis ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
2570b725ae77Skettenis 				    void **this_cache,
2571b725ae77Skettenis 				    int regnum, int *optimizedp,
2572b725ae77Skettenis 				    enum lval_type *lvalp, CORE_ADDR *addrp,
2573b725ae77Skettenis 				    int *realnump, void *valuep)
2574b725ae77Skettenis {
2575b725ae77Skettenis   int reg = regnum;
2576b725ae77Skettenis 
2577b725ae77Skettenis   if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
2578b725ae77Skettenis     reg = IA64_PR_REGNUM;
2579b725ae77Skettenis   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
2580b725ae77Skettenis     reg = IA64_UNAT_REGNUM;
2581b725ae77Skettenis 
2582b725ae77Skettenis   /* Let libunwind do most of the work.  */
2583b725ae77Skettenis   libunwind_frame_prev_register (next_frame, this_cache, reg,
2584b725ae77Skettenis 				 optimizedp, lvalp, addrp, realnump, valuep);
2585b725ae77Skettenis 
2586*11efff7fSkettenis   /* No more to do if the value is not supposed to be supplied.  */
2587*11efff7fSkettenis   if (!valuep)
2588*11efff7fSkettenis     return;
2589*11efff7fSkettenis 
2590b725ae77Skettenis   if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
2591b725ae77Skettenis     {
2592b725ae77Skettenis       ULONGEST prN_val;
2593b725ae77Skettenis 
2594b725ae77Skettenis       if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
2595b725ae77Skettenis 	{
2596b725ae77Skettenis 	  int rrb_pr = 0;
2597b725ae77Skettenis 	  ULONGEST cfm;
2598b725ae77Skettenis 	  unsigned char buf[MAX_REGISTER_SIZE];
2599b725ae77Skettenis 
2600b725ae77Skettenis 	  /* Fetch predicate register rename base from current frame
2601b725ae77Skettenis 	     marker for this frame.  */
2602b725ae77Skettenis 	  frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
2603b725ae77Skettenis 	  cfm = extract_unsigned_integer (buf, 8);
2604b725ae77Skettenis 	  rrb_pr = (cfm >> 32) & 0x3f;
2605b725ae77Skettenis 
2606b725ae77Skettenis 	  /* Adjust the register number to account for register rotation.  */
2607b725ae77Skettenis 	  regnum = VP16_REGNUM
2608b725ae77Skettenis 	    + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
2609b725ae77Skettenis 	}
2610b725ae77Skettenis       prN_val = extract_bit_field ((unsigned char *) valuep,
2611b725ae77Skettenis 				   regnum - VP0_REGNUM, 1);
2612b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val);
2613b725ae77Skettenis     }
2614b725ae77Skettenis   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
2615b725ae77Skettenis     {
2616b725ae77Skettenis       ULONGEST unatN_val;
2617b725ae77Skettenis 
2618b725ae77Skettenis       unatN_val = extract_bit_field ((unsigned char *) valuep,
2619b725ae77Skettenis                                    regnum - IA64_NAT0_REGNUM, 1);
2620b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
2621b725ae77Skettenis                               unatN_val);
2622b725ae77Skettenis     }
2623b725ae77Skettenis   else if (regnum == IA64_BSP_REGNUM)
2624b725ae77Skettenis     {
2625b725ae77Skettenis       char cfm_valuep[MAX_REGISTER_SIZE];
2626b725ae77Skettenis       int  cfm_optim;
2627b725ae77Skettenis       int  cfm_realnum;
2628b725ae77Skettenis       enum lval_type cfm_lval;
2629b725ae77Skettenis       CORE_ADDR cfm_addr;
2630b725ae77Skettenis       CORE_ADDR bsp, prev_cfm, prev_bsp;
2631b725ae77Skettenis 
2632b725ae77Skettenis       /* We want to calculate the previous bsp as the end of the previous register stack frame.
2633b725ae77Skettenis 	 This corresponds to what the hardware bsp register will be if we pop the frame
2634b725ae77Skettenis 	 back which is why we might have been called.  We know that libunwind will pass us back
2635b725ae77Skettenis 	 the beginning of the current frame so we should just add sof to it. */
2636b725ae77Skettenis       prev_bsp = extract_unsigned_integer (valuep, 8);
2637b725ae77Skettenis       libunwind_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
2638b725ae77Skettenis 				     &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
2639b725ae77Skettenis       prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
2640b725ae77Skettenis       prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
2641b725ae77Skettenis 
2642b725ae77Skettenis       store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
2643b725ae77Skettenis 			      prev_bsp);
2644b725ae77Skettenis     }
2645b725ae77Skettenis 
2646b725ae77Skettenis   if (gdbarch_debug >= 1)
2647b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
2648b725ae77Skettenis 			"libunwind prev register <%s> is 0x%s\n",
2649b725ae77Skettenis 			(((unsigned) regnum <= IA64_NAT127_REGNUM)
2650b725ae77Skettenis 			 ? ia64_register_names[regnum] : "r??"),
2651b725ae77Skettenis 			paddr_nz (extract_unsigned_integer (valuep, 8)));
2652b725ae77Skettenis }
2653b725ae77Skettenis 
2654b725ae77Skettenis static const struct frame_unwind ia64_libunwind_frame_unwind =
2655b725ae77Skettenis {
2656b725ae77Skettenis   NORMAL_FRAME,
2657b725ae77Skettenis   ia64_libunwind_frame_this_id,
2658b725ae77Skettenis   ia64_libunwind_frame_prev_register
2659b725ae77Skettenis };
2660b725ae77Skettenis 
2661b725ae77Skettenis static const struct frame_unwind *
ia64_libunwind_frame_sniffer(struct frame_info * next_frame)2662b725ae77Skettenis ia64_libunwind_frame_sniffer (struct frame_info *next_frame)
2663b725ae77Skettenis {
2664b725ae77Skettenis   if (libunwind_is_initialized () && libunwind_frame_sniffer (next_frame))
2665b725ae77Skettenis     return &ia64_libunwind_frame_unwind;
2666b725ae77Skettenis 
2667b725ae77Skettenis   return NULL;
2668b725ae77Skettenis }
2669b725ae77Skettenis 
2670b725ae77Skettenis /* Set of libunwind callback acccessor functions.  */
2671b725ae77Skettenis static unw_accessors_t ia64_unw_accessors =
2672b725ae77Skettenis {
2673b725ae77Skettenis   ia64_find_proc_info_x,
2674b725ae77Skettenis   ia64_put_unwind_info,
2675b725ae77Skettenis   ia64_get_dyn_info_list,
2676b725ae77Skettenis   ia64_access_mem,
2677b725ae77Skettenis   ia64_access_reg,
2678b725ae77Skettenis   ia64_access_fpreg,
2679b725ae77Skettenis   /* resume */
2680b725ae77Skettenis   /* get_proc_name */
2681b725ae77Skettenis };
2682b725ae77Skettenis 
2683b725ae77Skettenis /* Set of ia64 gdb libunwind-frame callbacks and data for generic libunwind-frame code to use.  */
2684b725ae77Skettenis static struct libunwind_descr ia64_libunwind_descr =
2685b725ae77Skettenis {
2686b725ae77Skettenis   ia64_gdb2uw_regnum,
2687b725ae77Skettenis   ia64_uw2gdb_regnum,
2688b725ae77Skettenis   ia64_is_fpreg,
2689b725ae77Skettenis   &ia64_unw_accessors,
2690b725ae77Skettenis };
2691b725ae77Skettenis 
2692b725ae77Skettenis #endif /* HAVE_LIBUNWIND_IA64_H  */
2693b725ae77Skettenis 
2694b725ae77Skettenis /* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
2695b725ae77Skettenis    EXTRACT_RETURN_VALUE?  GCC_P is true if compiled with gcc and TYPE
2696b725ae77Skettenis    is the type (which is known to be struct, union or array).  */
2697b725ae77Skettenis int
ia64_use_struct_convention(int gcc_p,struct type * type)2698b725ae77Skettenis ia64_use_struct_convention (int gcc_p, struct type *type)
2699b725ae77Skettenis {
2700b725ae77Skettenis   struct type *float_elt_type;
2701b725ae77Skettenis 
2702b725ae77Skettenis   /* HFAs are structures (or arrays) consisting entirely of floating
2703b725ae77Skettenis      point values of the same length.  Up to 8 of these are returned
2704b725ae77Skettenis      in registers.  Don't use the struct convention when this is the
2705b725ae77Skettenis      case.  */
2706b725ae77Skettenis   float_elt_type = is_float_or_hfa_type (type);
2707b725ae77Skettenis   if (float_elt_type != NULL
2708b725ae77Skettenis       && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8)
2709b725ae77Skettenis     return 0;
2710b725ae77Skettenis 
2711b725ae77Skettenis   /* Other structs of length 32 or less are returned in r8-r11.
2712b725ae77Skettenis      Don't use the struct convention for those either.  */
2713b725ae77Skettenis   return TYPE_LENGTH (type) > 32;
2714b725ae77Skettenis }
2715b725ae77Skettenis 
2716b725ae77Skettenis void
ia64_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)2717b725ae77Skettenis ia64_extract_return_value (struct type *type, struct regcache *regcache, void *valbuf)
2718b725ae77Skettenis {
2719b725ae77Skettenis   struct type *float_elt_type;
2720b725ae77Skettenis 
2721b725ae77Skettenis   float_elt_type = is_float_or_hfa_type (type);
2722b725ae77Skettenis   if (float_elt_type != NULL)
2723b725ae77Skettenis     {
2724b725ae77Skettenis       char from[MAX_REGISTER_SIZE];
2725b725ae77Skettenis       int offset = 0;
2726b725ae77Skettenis       int regnum = IA64_FR8_REGNUM;
2727b725ae77Skettenis       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
2728b725ae77Skettenis 
2729b725ae77Skettenis       while (n-- > 0)
2730b725ae77Skettenis 	{
2731b725ae77Skettenis 	  regcache_cooked_read (regcache, regnum, from);
2732b725ae77Skettenis 	  convert_typed_floating (from, builtin_type_ia64_ext,
2733b725ae77Skettenis 				  (char *)valbuf + offset, float_elt_type);
2734b725ae77Skettenis 	  offset += TYPE_LENGTH (float_elt_type);
2735b725ae77Skettenis 	  regnum++;
2736b725ae77Skettenis 	}
2737b725ae77Skettenis     }
2738b725ae77Skettenis   else
2739b725ae77Skettenis     {
2740b725ae77Skettenis       ULONGEST val;
2741b725ae77Skettenis       int offset = 0;
2742b725ae77Skettenis       int regnum = IA64_GR8_REGNUM;
2743b725ae77Skettenis       int reglen = TYPE_LENGTH (ia64_register_type (NULL, IA64_GR8_REGNUM));
2744b725ae77Skettenis       int n = TYPE_LENGTH (type) / reglen;
2745b725ae77Skettenis       int m = TYPE_LENGTH (type) % reglen;
2746b725ae77Skettenis 
2747b725ae77Skettenis       while (n-- > 0)
2748b725ae77Skettenis 	{
2749b725ae77Skettenis 	  ULONGEST val;
2750b725ae77Skettenis 	  regcache_cooked_read_unsigned (regcache, regnum, &val);
2751b725ae77Skettenis 	  memcpy ((char *)valbuf + offset, &val, reglen);
2752b725ae77Skettenis 	  offset += reglen;
2753b725ae77Skettenis 	  regnum++;
2754b725ae77Skettenis 	}
2755b725ae77Skettenis 
2756b725ae77Skettenis       if (m)
2757b725ae77Skettenis 	{
2758b725ae77Skettenis           regcache_cooked_read_unsigned (regcache, regnum, &val);
2759b725ae77Skettenis 	  memcpy ((char *)valbuf + offset, &val, m);
2760b725ae77Skettenis 	}
2761b725ae77Skettenis     }
2762b725ae77Skettenis }
2763b725ae77Skettenis 
2764b725ae77Skettenis CORE_ADDR
ia64_extract_struct_value_address(struct regcache * regcache)2765b725ae77Skettenis ia64_extract_struct_value_address (struct regcache *regcache)
2766b725ae77Skettenis {
2767b725ae77Skettenis   error ("ia64_extract_struct_value_address called and cannot get struct value address");
2768b725ae77Skettenis   return 0;
2769b725ae77Skettenis }
2770b725ae77Skettenis 
2771b725ae77Skettenis 
2772b725ae77Skettenis static int
is_float_or_hfa_type_recurse(struct type * t,struct type ** etp)2773b725ae77Skettenis is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
2774b725ae77Skettenis {
2775b725ae77Skettenis   switch (TYPE_CODE (t))
2776b725ae77Skettenis     {
2777b725ae77Skettenis     case TYPE_CODE_FLT:
2778b725ae77Skettenis       if (*etp)
2779b725ae77Skettenis 	return TYPE_LENGTH (*etp) == TYPE_LENGTH (t);
2780b725ae77Skettenis       else
2781b725ae77Skettenis 	{
2782b725ae77Skettenis 	  *etp = t;
2783b725ae77Skettenis 	  return 1;
2784b725ae77Skettenis 	}
2785b725ae77Skettenis       break;
2786b725ae77Skettenis     case TYPE_CODE_ARRAY:
2787b725ae77Skettenis       return
2788b725ae77Skettenis 	is_float_or_hfa_type_recurse (check_typedef (TYPE_TARGET_TYPE (t)),
2789b725ae77Skettenis 				      etp);
2790b725ae77Skettenis       break;
2791b725ae77Skettenis     case TYPE_CODE_STRUCT:
2792b725ae77Skettenis       {
2793b725ae77Skettenis 	int i;
2794b725ae77Skettenis 
2795b725ae77Skettenis 	for (i = 0; i < TYPE_NFIELDS (t); i++)
2796b725ae77Skettenis 	  if (!is_float_or_hfa_type_recurse
2797b725ae77Skettenis 	      (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
2798b725ae77Skettenis 	    return 0;
2799b725ae77Skettenis 	return 1;
2800b725ae77Skettenis       }
2801b725ae77Skettenis       break;
2802b725ae77Skettenis     default:
2803b725ae77Skettenis       return 0;
2804b725ae77Skettenis       break;
2805b725ae77Skettenis     }
2806b725ae77Skettenis }
2807b725ae77Skettenis 
2808b725ae77Skettenis /* Determine if the given type is one of the floating point types or
2809b725ae77Skettenis    and HFA (which is a struct, array, or combination thereof whose
2810b725ae77Skettenis    bottom-most elements are all of the same floating point type).  */
2811b725ae77Skettenis 
2812b725ae77Skettenis static struct type *
is_float_or_hfa_type(struct type * t)2813b725ae77Skettenis is_float_or_hfa_type (struct type *t)
2814b725ae77Skettenis {
2815b725ae77Skettenis   struct type *et = 0;
2816b725ae77Skettenis 
2817b725ae77Skettenis   return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
2818b725ae77Skettenis }
2819b725ae77Skettenis 
2820b725ae77Skettenis 
2821b725ae77Skettenis /* Return 1 if the alignment of T is such that the next even slot
2822b725ae77Skettenis    should be used.  Return 0, if the next available slot should
2823b725ae77Skettenis    be used.  (See section 8.5.1 of the IA-64 Software Conventions
2824b725ae77Skettenis    and Runtime manual).  */
2825b725ae77Skettenis 
2826b725ae77Skettenis static int
slot_alignment_is_next_even(struct type * t)2827b725ae77Skettenis slot_alignment_is_next_even (struct type *t)
2828b725ae77Skettenis {
2829b725ae77Skettenis   switch (TYPE_CODE (t))
2830b725ae77Skettenis     {
2831b725ae77Skettenis     case TYPE_CODE_INT:
2832b725ae77Skettenis     case TYPE_CODE_FLT:
2833b725ae77Skettenis       if (TYPE_LENGTH (t) > 8)
2834b725ae77Skettenis 	return 1;
2835b725ae77Skettenis       else
2836b725ae77Skettenis 	return 0;
2837b725ae77Skettenis     case TYPE_CODE_ARRAY:
2838b725ae77Skettenis       return
2839b725ae77Skettenis 	slot_alignment_is_next_even (check_typedef (TYPE_TARGET_TYPE (t)));
2840b725ae77Skettenis     case TYPE_CODE_STRUCT:
2841b725ae77Skettenis       {
2842b725ae77Skettenis 	int i;
2843b725ae77Skettenis 
2844b725ae77Skettenis 	for (i = 0; i < TYPE_NFIELDS (t); i++)
2845b725ae77Skettenis 	  if (slot_alignment_is_next_even
2846b725ae77Skettenis 	      (check_typedef (TYPE_FIELD_TYPE (t, i))))
2847b725ae77Skettenis 	    return 1;
2848b725ae77Skettenis 	return 0;
2849b725ae77Skettenis       }
2850b725ae77Skettenis     default:
2851b725ae77Skettenis       return 0;
2852b725ae77Skettenis     }
2853b725ae77Skettenis }
2854b725ae77Skettenis 
2855b725ae77Skettenis /* Attempt to find (and return) the global pointer for the given
2856b725ae77Skettenis    function.
2857b725ae77Skettenis 
2858b725ae77Skettenis    This is a rather nasty bit of code searchs for the .dynamic section
2859b725ae77Skettenis    in the objfile corresponding to the pc of the function we're trying
2860b725ae77Skettenis    to call.  Once it finds the addresses at which the .dynamic section
2861b725ae77Skettenis    lives in the child process, it scans the Elf64_Dyn entries for a
2862b725ae77Skettenis    DT_PLTGOT tag.  If it finds one of these, the corresponding
2863b725ae77Skettenis    d_un.d_ptr value is the global pointer.  */
2864b725ae77Skettenis 
2865b725ae77Skettenis static CORE_ADDR
generic_elf_find_global_pointer(CORE_ADDR faddr)2866b725ae77Skettenis generic_elf_find_global_pointer (CORE_ADDR faddr)
2867b725ae77Skettenis {
2868b725ae77Skettenis   struct obj_section *faddr_sect;
2869b725ae77Skettenis 
2870b725ae77Skettenis   faddr_sect = find_pc_section (faddr);
2871b725ae77Skettenis   if (faddr_sect != NULL)
2872b725ae77Skettenis     {
2873b725ae77Skettenis       struct obj_section *osect;
2874b725ae77Skettenis 
2875b725ae77Skettenis       ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
2876b725ae77Skettenis 	{
2877b725ae77Skettenis 	  if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
2878b725ae77Skettenis 	    break;
2879b725ae77Skettenis 	}
2880b725ae77Skettenis 
2881b725ae77Skettenis       if (osect < faddr_sect->objfile->sections_end)
2882b725ae77Skettenis 	{
2883b725ae77Skettenis 	  CORE_ADDR addr;
2884b725ae77Skettenis 
2885b725ae77Skettenis 	  addr = osect->addr;
2886b725ae77Skettenis 	  while (addr < osect->endaddr)
2887b725ae77Skettenis 	    {
2888b725ae77Skettenis 	      int status;
2889b725ae77Skettenis 	      LONGEST tag;
2890b725ae77Skettenis 	      char buf[8];
2891b725ae77Skettenis 
2892b725ae77Skettenis 	      status = target_read_memory (addr, buf, sizeof (buf));
2893b725ae77Skettenis 	      if (status != 0)
2894b725ae77Skettenis 		break;
2895b725ae77Skettenis 	      tag = extract_signed_integer (buf, sizeof (buf));
2896b725ae77Skettenis 
2897b725ae77Skettenis 	      if (tag == DT_PLTGOT)
2898b725ae77Skettenis 		{
2899b725ae77Skettenis 		  CORE_ADDR global_pointer;
2900b725ae77Skettenis 
2901b725ae77Skettenis 		  status = target_read_memory (addr + 8, buf, sizeof (buf));
2902b725ae77Skettenis 		  if (status != 0)
2903b725ae77Skettenis 		    break;
2904b725ae77Skettenis 		  global_pointer = extract_unsigned_integer (buf, sizeof (buf));
2905b725ae77Skettenis 
2906b725ae77Skettenis 		  /* The payoff... */
2907b725ae77Skettenis 		  return global_pointer;
2908b725ae77Skettenis 		}
2909b725ae77Skettenis 
2910b725ae77Skettenis 	      if (tag == DT_NULL)
2911b725ae77Skettenis 		break;
2912b725ae77Skettenis 
2913b725ae77Skettenis 	      addr += 16;
2914b725ae77Skettenis 	    }
2915b725ae77Skettenis 	}
2916b725ae77Skettenis     }
2917b725ae77Skettenis   return 0;
2918b725ae77Skettenis }
2919b725ae77Skettenis 
2920b725ae77Skettenis /* Given a function's address, attempt to find (and return) the
2921b725ae77Skettenis    corresponding (canonical) function descriptor.  Return 0 if
2922b725ae77Skettenis    not found.  */
2923b725ae77Skettenis static CORE_ADDR
find_extant_func_descr(CORE_ADDR faddr)2924b725ae77Skettenis find_extant_func_descr (CORE_ADDR faddr)
2925b725ae77Skettenis {
2926b725ae77Skettenis   struct obj_section *faddr_sect;
2927b725ae77Skettenis 
2928b725ae77Skettenis   /* Return early if faddr is already a function descriptor.  */
2929b725ae77Skettenis   faddr_sect = find_pc_section (faddr);
2930b725ae77Skettenis   if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0)
2931b725ae77Skettenis     return faddr;
2932b725ae77Skettenis 
2933b725ae77Skettenis   if (faddr_sect != NULL)
2934b725ae77Skettenis     {
2935b725ae77Skettenis       struct obj_section *osect;
2936b725ae77Skettenis       ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
2937b725ae77Skettenis 	{
2938b725ae77Skettenis 	  if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
2939b725ae77Skettenis 	    break;
2940b725ae77Skettenis 	}
2941b725ae77Skettenis 
2942b725ae77Skettenis       if (osect < faddr_sect->objfile->sections_end)
2943b725ae77Skettenis 	{
2944b725ae77Skettenis 	  CORE_ADDR addr;
2945b725ae77Skettenis 
2946b725ae77Skettenis 	  addr = osect->addr;
2947b725ae77Skettenis 	  while (addr < osect->endaddr)
2948b725ae77Skettenis 	    {
2949b725ae77Skettenis 	      int status;
2950b725ae77Skettenis 	      LONGEST faddr2;
2951b725ae77Skettenis 	      char buf[8];
2952b725ae77Skettenis 
2953b725ae77Skettenis 	      status = target_read_memory (addr, buf, sizeof (buf));
2954b725ae77Skettenis 	      if (status != 0)
2955b725ae77Skettenis 		break;
2956b725ae77Skettenis 	      faddr2 = extract_signed_integer (buf, sizeof (buf));
2957b725ae77Skettenis 
2958b725ae77Skettenis 	      if (faddr == faddr2)
2959b725ae77Skettenis 		return addr;
2960b725ae77Skettenis 
2961b725ae77Skettenis 	      addr += 16;
2962b725ae77Skettenis 	    }
2963b725ae77Skettenis 	}
2964b725ae77Skettenis     }
2965b725ae77Skettenis   return 0;
2966b725ae77Skettenis }
2967b725ae77Skettenis 
2968b725ae77Skettenis /* Attempt to find a function descriptor corresponding to the
2969b725ae77Skettenis    given address.  If none is found, construct one on the
2970b725ae77Skettenis    stack using the address at fdaptr.  */
2971b725ae77Skettenis 
2972b725ae77Skettenis static CORE_ADDR
find_func_descr(CORE_ADDR faddr,CORE_ADDR * fdaptr)2973b725ae77Skettenis find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
2974b725ae77Skettenis {
2975b725ae77Skettenis   CORE_ADDR fdesc;
2976b725ae77Skettenis 
2977b725ae77Skettenis   fdesc = find_extant_func_descr (faddr);
2978b725ae77Skettenis 
2979b725ae77Skettenis   if (fdesc == 0)
2980b725ae77Skettenis     {
2981b725ae77Skettenis       CORE_ADDR global_pointer;
2982b725ae77Skettenis       char buf[16];
2983b725ae77Skettenis 
2984b725ae77Skettenis       fdesc = *fdaptr;
2985b725ae77Skettenis       *fdaptr += 16;
2986b725ae77Skettenis 
2987b725ae77Skettenis       global_pointer = FIND_GLOBAL_POINTER (faddr);
2988b725ae77Skettenis 
2989b725ae77Skettenis       if (global_pointer == 0)
2990b725ae77Skettenis 	global_pointer = read_register (IA64_GR1_REGNUM);
2991b725ae77Skettenis 
2992b725ae77Skettenis       store_unsigned_integer (buf, 8, faddr);
2993b725ae77Skettenis       store_unsigned_integer (buf + 8, 8, global_pointer);
2994b725ae77Skettenis 
2995b725ae77Skettenis       write_memory (fdesc, buf, 16);
2996b725ae77Skettenis     }
2997b725ae77Skettenis 
2998b725ae77Skettenis   return fdesc;
2999b725ae77Skettenis }
3000b725ae77Skettenis 
3001b725ae77Skettenis /* Use the following routine when printing out function pointers
3002b725ae77Skettenis    so the user can see the function address rather than just the
3003b725ae77Skettenis    function descriptor.  */
3004b725ae77Skettenis static CORE_ADDR
ia64_convert_from_func_ptr_addr(struct gdbarch * gdbarch,CORE_ADDR addr,struct target_ops * targ)3005b725ae77Skettenis ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
3006b725ae77Skettenis 				 struct target_ops *targ)
3007b725ae77Skettenis {
3008b725ae77Skettenis   struct obj_section *s;
3009b725ae77Skettenis 
3010b725ae77Skettenis   s = find_pc_section (addr);
3011b725ae77Skettenis 
3012b725ae77Skettenis   /* check if ADDR points to a function descriptor.  */
3013b725ae77Skettenis   if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
3014b725ae77Skettenis     return read_memory_unsigned_integer (addr, 8);
3015b725ae77Skettenis 
3016b725ae77Skettenis   return addr;
3017b725ae77Skettenis }
3018b725ae77Skettenis 
3019b725ae77Skettenis static CORE_ADDR
ia64_frame_align(struct gdbarch * gdbarch,CORE_ADDR sp)3020b725ae77Skettenis ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
3021b725ae77Skettenis {
3022b725ae77Skettenis   return sp & ~0xfLL;
3023b725ae77Skettenis }
3024b725ae77Skettenis 
3025b725ae77Skettenis static CORE_ADDR
ia64_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)3026*11efff7fSkettenis ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
3027b725ae77Skettenis 		      struct regcache *regcache, CORE_ADDR bp_addr,
3028b725ae77Skettenis 		      int nargs, struct value **args, CORE_ADDR sp,
3029b725ae77Skettenis 		      int struct_return, CORE_ADDR struct_addr)
3030b725ae77Skettenis {
3031b725ae77Skettenis   int argno;
3032b725ae77Skettenis   struct value *arg;
3033b725ae77Skettenis   struct type *type;
3034b725ae77Skettenis   int len, argoffset;
3035b725ae77Skettenis   int nslots, rseslots, memslots, slotnum, nfuncargs;
3036b725ae77Skettenis   int floatreg;
3037b725ae77Skettenis   CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr, pc, global_pointer;
3038*11efff7fSkettenis   CORE_ADDR func_addr = find_function_addr (function, NULL);
3039b725ae77Skettenis 
3040b725ae77Skettenis   nslots = 0;
3041b725ae77Skettenis   nfuncargs = 0;
3042b725ae77Skettenis   /* Count the number of slots needed for the arguments.  */
3043b725ae77Skettenis   for (argno = 0; argno < nargs; argno++)
3044b725ae77Skettenis     {
3045b725ae77Skettenis       arg = args[argno];
3046b725ae77Skettenis       type = check_typedef (VALUE_TYPE (arg));
3047b725ae77Skettenis       len = TYPE_LENGTH (type);
3048b725ae77Skettenis 
3049b725ae77Skettenis       if ((nslots & 1) && slot_alignment_is_next_even (type))
3050b725ae77Skettenis 	nslots++;
3051b725ae77Skettenis 
3052b725ae77Skettenis       if (TYPE_CODE (type) == TYPE_CODE_FUNC)
3053b725ae77Skettenis 	nfuncargs++;
3054b725ae77Skettenis 
3055b725ae77Skettenis       nslots += (len + 7) / 8;
3056b725ae77Skettenis     }
3057b725ae77Skettenis 
3058b725ae77Skettenis   /* Divvy up the slots between the RSE and the memory stack.  */
3059b725ae77Skettenis   rseslots = (nslots > 8) ? 8 : nslots;
3060b725ae77Skettenis   memslots = nslots - rseslots;
3061b725ae77Skettenis 
3062b725ae77Skettenis   /* Allocate a new RSE frame.  */
3063b725ae77Skettenis   cfm = read_register (IA64_CFM_REGNUM);
3064b725ae77Skettenis 
3065b725ae77Skettenis   bsp = read_register (IA64_BSP_REGNUM);
3066b725ae77Skettenis   new_bsp = rse_address_add (bsp, rseslots);
3067b725ae77Skettenis   write_register (IA64_BSP_REGNUM, new_bsp);
3068b725ae77Skettenis 
3069b725ae77Skettenis   pfs = read_register (IA64_PFS_REGNUM);
3070b725ae77Skettenis   pfs &= 0xc000000000000000LL;
3071b725ae77Skettenis   pfs |= (cfm & 0xffffffffffffLL);
3072b725ae77Skettenis   write_register (IA64_PFS_REGNUM, pfs);
3073b725ae77Skettenis 
3074b725ae77Skettenis   cfm &= 0xc000000000000000LL;
3075b725ae77Skettenis   cfm |= rseslots;
3076b725ae77Skettenis   write_register (IA64_CFM_REGNUM, cfm);
3077b725ae77Skettenis 
3078b725ae77Skettenis   /* We will attempt to find function descriptors in the .opd segment,
3079b725ae77Skettenis      but if we can't we'll construct them ourselves.  That being the
3080b725ae77Skettenis      case, we'll need to reserve space on the stack for them.  */
3081b725ae77Skettenis   funcdescaddr = sp - nfuncargs * 16;
3082b725ae77Skettenis   funcdescaddr &= ~0xfLL;
3083b725ae77Skettenis 
3084b725ae77Skettenis   /* Adjust the stack pointer to it's new value.  The calling conventions
3085b725ae77Skettenis      require us to have 16 bytes of scratch, plus whatever space is
3086b725ae77Skettenis      necessary for the memory slots and our function descriptors.  */
3087b725ae77Skettenis   sp = sp - 16 - (memslots + nfuncargs) * 8;
3088b725ae77Skettenis   sp &= ~0xfLL;				/* Maintain 16 byte alignment.  */
3089b725ae77Skettenis 
3090b725ae77Skettenis   /* Place the arguments where they belong.  The arguments will be
3091b725ae77Skettenis      either placed in the RSE backing store or on the memory stack.
3092b725ae77Skettenis      In addition, floating point arguments or HFAs are placed in
3093b725ae77Skettenis      floating point registers.  */
3094b725ae77Skettenis   slotnum = 0;
3095b725ae77Skettenis   floatreg = IA64_FR8_REGNUM;
3096b725ae77Skettenis   for (argno = 0; argno < nargs; argno++)
3097b725ae77Skettenis     {
3098b725ae77Skettenis       struct type *float_elt_type;
3099b725ae77Skettenis 
3100b725ae77Skettenis       arg = args[argno];
3101b725ae77Skettenis       type = check_typedef (VALUE_TYPE (arg));
3102b725ae77Skettenis       len = TYPE_LENGTH (type);
3103b725ae77Skettenis 
3104b725ae77Skettenis       /* Special handling for function parameters.  */
3105b725ae77Skettenis       if (len == 8
3106b725ae77Skettenis           && TYPE_CODE (type) == TYPE_CODE_PTR
3107b725ae77Skettenis 	  && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
3108b725ae77Skettenis 	{
3109b725ae77Skettenis 	  char val_buf[8];
3110b725ae77Skettenis 
3111b725ae77Skettenis 	  store_unsigned_integer (val_buf, 8,
3112b725ae77Skettenis 				  find_func_descr (extract_unsigned_integer (VALUE_CONTENTS (arg), 8),
3113b725ae77Skettenis 						   &funcdescaddr));
3114b725ae77Skettenis 	  if (slotnum < rseslots)
3115b725ae77Skettenis 	    write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
3116b725ae77Skettenis 	  else
3117b725ae77Skettenis 	    write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
3118b725ae77Skettenis 	  slotnum++;
3119b725ae77Skettenis 	  continue;
3120b725ae77Skettenis 	}
3121b725ae77Skettenis 
3122b725ae77Skettenis       /* Normal slots.  */
3123b725ae77Skettenis 
3124b725ae77Skettenis       /* Skip odd slot if necessary...  */
3125b725ae77Skettenis       if ((slotnum & 1) && slot_alignment_is_next_even (type))
3126b725ae77Skettenis 	slotnum++;
3127b725ae77Skettenis 
3128b725ae77Skettenis       argoffset = 0;
3129b725ae77Skettenis       while (len > 0)
3130b725ae77Skettenis 	{
3131b725ae77Skettenis 	  char val_buf[8];
3132b725ae77Skettenis 
3133b725ae77Skettenis 	  memset (val_buf, 0, 8);
3134b725ae77Skettenis 	  memcpy (val_buf, VALUE_CONTENTS (arg) + argoffset, (len > 8) ? 8 : len);
3135b725ae77Skettenis 
3136b725ae77Skettenis 	  if (slotnum < rseslots)
3137b725ae77Skettenis 	    write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
3138b725ae77Skettenis 	  else
3139b725ae77Skettenis 	    write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
3140b725ae77Skettenis 
3141b725ae77Skettenis 	  argoffset += 8;
3142b725ae77Skettenis 	  len -= 8;
3143b725ae77Skettenis 	  slotnum++;
3144b725ae77Skettenis 	}
3145b725ae77Skettenis 
3146b725ae77Skettenis       /* Handle floating point types (including HFAs).  */
3147b725ae77Skettenis       float_elt_type = is_float_or_hfa_type (type);
3148b725ae77Skettenis       if (float_elt_type != NULL)
3149b725ae77Skettenis 	{
3150b725ae77Skettenis 	  argoffset = 0;
3151b725ae77Skettenis 	  len = TYPE_LENGTH (type);
3152b725ae77Skettenis 	  while (len > 0 && floatreg < IA64_FR16_REGNUM)
3153b725ae77Skettenis 	    {
3154b725ae77Skettenis 	      char to[MAX_REGISTER_SIZE];
3155b725ae77Skettenis 	      convert_typed_floating (VALUE_CONTENTS (arg) + argoffset, float_elt_type,
3156b725ae77Skettenis 				      to, builtin_type_ia64_ext);
3157b725ae77Skettenis 	      regcache_cooked_write (regcache, floatreg, (void *)to);
3158b725ae77Skettenis 	      floatreg++;
3159b725ae77Skettenis 	      argoffset += TYPE_LENGTH (float_elt_type);
3160b725ae77Skettenis 	      len -= TYPE_LENGTH (float_elt_type);
3161b725ae77Skettenis 	    }
3162b725ae77Skettenis 	}
3163b725ae77Skettenis     }
3164b725ae77Skettenis 
3165b725ae77Skettenis   /* Store the struct return value in r8 if necessary.  */
3166b725ae77Skettenis   if (struct_return)
3167b725ae77Skettenis     {
3168b725ae77Skettenis       regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM, (ULONGEST)struct_addr);
3169b725ae77Skettenis     }
3170b725ae77Skettenis 
3171b725ae77Skettenis   global_pointer = FIND_GLOBAL_POINTER (func_addr);
3172b725ae77Skettenis 
3173b725ae77Skettenis   if (global_pointer != 0)
3174b725ae77Skettenis     write_register (IA64_GR1_REGNUM, global_pointer);
3175b725ae77Skettenis 
3176b725ae77Skettenis   write_register (IA64_BR0_REGNUM, bp_addr);
3177b725ae77Skettenis 
3178b725ae77Skettenis   write_register (sp_regnum, sp);
3179b725ae77Skettenis 
3180b725ae77Skettenis   return sp;
3181b725ae77Skettenis }
3182b725ae77Skettenis 
3183b725ae77Skettenis static struct frame_id
ia64_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)3184b725ae77Skettenis ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
3185b725ae77Skettenis {
3186b725ae77Skettenis   char buf[8];
3187b725ae77Skettenis   CORE_ADDR sp, bsp;
3188b725ae77Skettenis 
3189b725ae77Skettenis   frame_unwind_register (next_frame, sp_regnum, buf);
3190b725ae77Skettenis   sp = extract_unsigned_integer (buf, 8);
3191b725ae77Skettenis 
3192b725ae77Skettenis   frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
3193b725ae77Skettenis   bsp = extract_unsigned_integer (buf, 8);
3194b725ae77Skettenis 
3195b725ae77Skettenis   if (gdbarch_debug >= 1)
3196b725ae77Skettenis     fprintf_unfiltered (gdb_stdlog,
3197b725ae77Skettenis 			"dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n",
3198b725ae77Skettenis 			paddr_nz (frame_pc_unwind (next_frame)),
3199b725ae77Skettenis 			paddr_nz (sp), paddr_nz (bsp));
3200b725ae77Skettenis 
3201b725ae77Skettenis   return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
3202b725ae77Skettenis }
3203b725ae77Skettenis 
3204b725ae77Skettenis static CORE_ADDR
ia64_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)3205b725ae77Skettenis ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
3206b725ae77Skettenis {
3207b725ae77Skettenis   char buf[8];
3208b725ae77Skettenis   CORE_ADDR ip, psr, pc;
3209b725ae77Skettenis 
3210b725ae77Skettenis   frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
3211b725ae77Skettenis   ip = extract_unsigned_integer (buf, 8);
3212b725ae77Skettenis   frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
3213b725ae77Skettenis   psr = extract_unsigned_integer (buf, 8);
3214b725ae77Skettenis 
3215b725ae77Skettenis   pc = (ip & ~0xf) | ((psr >> 41) & 3);
3216b725ae77Skettenis   return pc;
3217b725ae77Skettenis }
3218b725ae77Skettenis 
3219b725ae77Skettenis static void
ia64_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)3220b725ae77Skettenis ia64_store_return_value (struct type *type, struct regcache *regcache, const void *valbuf)
3221b725ae77Skettenis {
3222b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_FLT)
3223b725ae77Skettenis     {
3224b725ae77Skettenis       char to[MAX_REGISTER_SIZE];
3225b725ae77Skettenis       convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext);
3226b725ae77Skettenis       regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to);
3227b725ae77Skettenis       target_store_registers (IA64_FR8_REGNUM);
3228b725ae77Skettenis     }
3229b725ae77Skettenis   else
3230b725ae77Skettenis     regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf);
3231b725ae77Skettenis }
3232b725ae77Skettenis 
3233b725ae77Skettenis static void
ia64_remote_translate_xfer_address(struct gdbarch * gdbarch,struct regcache * regcache,CORE_ADDR memaddr,int nr_bytes,CORE_ADDR * targ_addr,int * targ_len)3234b725ae77Skettenis ia64_remote_translate_xfer_address (struct gdbarch *gdbarch,
3235b725ae77Skettenis 				    struct regcache *regcache,
3236b725ae77Skettenis 				    CORE_ADDR memaddr, int nr_bytes,
3237b725ae77Skettenis 				    CORE_ADDR *targ_addr, int *targ_len)
3238b725ae77Skettenis {
3239b725ae77Skettenis   *targ_addr = memaddr;
3240b725ae77Skettenis   *targ_len  = nr_bytes;
3241b725ae77Skettenis }
3242b725ae77Skettenis 
3243b725ae77Skettenis static int
ia64_print_insn(bfd_vma memaddr,struct disassemble_info * info)3244b725ae77Skettenis ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
3245b725ae77Skettenis {
3246b725ae77Skettenis   info->bytes_per_line = SLOT_MULTIPLIER;
3247b725ae77Skettenis   return print_insn_ia64 (memaddr, info);
3248b725ae77Skettenis }
3249b725ae77Skettenis 
3250b725ae77Skettenis static struct gdbarch *
ia64_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)3251b725ae77Skettenis ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
3252b725ae77Skettenis {
3253b725ae77Skettenis   struct gdbarch *gdbarch;
3254b725ae77Skettenis   struct gdbarch_tdep *tdep;
3255b725ae77Skettenis 
3256b725ae77Skettenis   /* If there is already a candidate, use it.  */
3257b725ae77Skettenis   arches = gdbarch_list_lookup_by_info (arches, &info);
3258b725ae77Skettenis   if (arches != NULL)
3259b725ae77Skettenis     return arches->gdbarch;
3260b725ae77Skettenis 
3261b725ae77Skettenis   tdep = xmalloc (sizeof (struct gdbarch_tdep));
3262b725ae77Skettenis   gdbarch = gdbarch_alloc (&info, tdep);
3263b725ae77Skettenis 
3264b725ae77Skettenis   /* Set the method of obtaining the sigcontext addresses at which
3265b725ae77Skettenis      registers are saved.  The method of checking to see if
3266b725ae77Skettenis      native_find_global_pointer is nonzero to indicate that we're
3267b725ae77Skettenis      on AIX is kind of hokey, but I can't think of a better way
3268b725ae77Skettenis      to do it.  */
3269b725ae77Skettenis   if (info.osabi == GDB_OSABI_LINUX)
3270b725ae77Skettenis     tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
3271b725ae77Skettenis   else if (native_find_global_pointer != 0)
3272b725ae77Skettenis     tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address;
3273b725ae77Skettenis   else
3274b725ae77Skettenis     tdep->sigcontext_register_address = 0;
3275b725ae77Skettenis 
3276b725ae77Skettenis   /* We know that GNU/Linux won't have to resort to the
3277b725ae77Skettenis      native_find_global_pointer hackery.  But that's the only one we
3278b725ae77Skettenis      know about so far, so if native_find_global_pointer is set to
3279b725ae77Skettenis      something non-zero, then use it.  Otherwise fall back to using
3280b725ae77Skettenis      generic_elf_find_global_pointer.  This arrangement should (in
3281b725ae77Skettenis      theory) allow us to cross debug GNU/Linux binaries from an AIX
3282b725ae77Skettenis      machine.  */
3283b725ae77Skettenis   if (info.osabi == GDB_OSABI_LINUX)
3284b725ae77Skettenis     tdep->find_global_pointer = generic_elf_find_global_pointer;
3285b725ae77Skettenis   else if (native_find_global_pointer != 0)
3286b725ae77Skettenis     tdep->find_global_pointer = native_find_global_pointer;
3287b725ae77Skettenis   else
3288b725ae77Skettenis     tdep->find_global_pointer = generic_elf_find_global_pointer;
3289b725ae77Skettenis 
3290b725ae77Skettenis   /* Define the ia64 floating-point format to gdb.  */
3291b725ae77Skettenis   builtin_type_ia64_ext =
3292b725ae77Skettenis     init_type (TYPE_CODE_FLT, 128 / 8,
3293b725ae77Skettenis                0, "builtin_type_ia64_ext", NULL);
3294b725ae77Skettenis   TYPE_FLOATFORMAT (builtin_type_ia64_ext) = &floatformat_ia64_ext;
3295b725ae77Skettenis 
3296b725ae77Skettenis   /* According to the ia64 specs, instructions that store long double
3297b725ae77Skettenis      floats in memory use a long-double format different than that
3298b725ae77Skettenis      used in the floating registers.  The memory format matches the
3299b725ae77Skettenis      x86 extended float format which is 80 bits.  An OS may choose to
3300b725ae77Skettenis      use this format (e.g. GNU/Linux) or choose to use a different
3301b725ae77Skettenis      format for storing long doubles (e.g. HPUX).  In the latter case,
3302b725ae77Skettenis      the setting of the format may be moved/overridden in an
3303b725ae77Skettenis      OS-specific tdep file.  */
3304b725ae77Skettenis   set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);
3305b725ae77Skettenis 
3306b725ae77Skettenis   set_gdbarch_short_bit (gdbarch, 16);
3307b725ae77Skettenis   set_gdbarch_int_bit (gdbarch, 32);
3308b725ae77Skettenis   set_gdbarch_long_bit (gdbarch, 64);
3309b725ae77Skettenis   set_gdbarch_long_long_bit (gdbarch, 64);
3310b725ae77Skettenis   set_gdbarch_float_bit (gdbarch, 32);
3311b725ae77Skettenis   set_gdbarch_double_bit (gdbarch, 64);
3312b725ae77Skettenis   set_gdbarch_long_double_bit (gdbarch, 128);
3313b725ae77Skettenis   set_gdbarch_ptr_bit (gdbarch, 64);
3314b725ae77Skettenis 
3315b725ae77Skettenis   set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS);
3316b725ae77Skettenis   set_gdbarch_num_pseudo_regs (gdbarch, LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
3317b725ae77Skettenis   set_gdbarch_sp_regnum (gdbarch, sp_regnum);
3318b725ae77Skettenis   set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
3319b725ae77Skettenis 
3320b725ae77Skettenis   set_gdbarch_register_name (gdbarch, ia64_register_name);
3321b725ae77Skettenis   /* FIXME:  Following interface should not be needed, however, without it recurse.exp
3322b725ae77Skettenis      gets a number of extra failures.  */
3323b725ae77Skettenis   set_gdbarch_deprecated_register_size (gdbarch, 8);
3324b725ae77Skettenis   set_gdbarch_register_type (gdbarch, ia64_register_type);
3325b725ae77Skettenis 
3326b725ae77Skettenis   set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read);
3327b725ae77Skettenis   set_gdbarch_pseudo_register_write (gdbarch, ia64_pseudo_register_write);
3328b725ae77Skettenis   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum);
3329b725ae77Skettenis   set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p);
3330b725ae77Skettenis   set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p);
3331b725ae77Skettenis   set_gdbarch_register_to_value (gdbarch, ia64_register_to_value);
3332b725ae77Skettenis   set_gdbarch_value_to_register (gdbarch, ia64_value_to_register);
3333b725ae77Skettenis 
3334b725ae77Skettenis   set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
3335b725ae77Skettenis 
3336*11efff7fSkettenis   set_gdbarch_deprecated_use_struct_convention (gdbarch, ia64_use_struct_convention);
3337b725ae77Skettenis   set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
3338b725ae77Skettenis 
3339b725ae77Skettenis   set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
3340b725ae77Skettenis   set_gdbarch_deprecated_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address);
3341b725ae77Skettenis 
3342b725ae77Skettenis   set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
3343b725ae77Skettenis   set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
3344b725ae77Skettenis   set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
3345b725ae77Skettenis   set_gdbarch_read_pc (gdbarch, ia64_read_pc);
3346b725ae77Skettenis   if (info.osabi == GDB_OSABI_LINUX)
3347b725ae77Skettenis     set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
3348b725ae77Skettenis   else
3349b725ae77Skettenis     set_gdbarch_write_pc (gdbarch, ia64_write_pc);
3350b725ae77Skettenis 
3351b725ae77Skettenis   /* Settings for calling functions in the inferior.  */
3352b725ae77Skettenis   set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
3353b725ae77Skettenis   set_gdbarch_frame_align (gdbarch, ia64_frame_align);
3354b725ae77Skettenis   set_gdbarch_unwind_dummy_id (gdbarch, ia64_unwind_dummy_id);
3355b725ae77Skettenis 
3356b725ae77Skettenis   set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
3357b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, ia64_sigtramp_frame_sniffer);
3358b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
3359b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, ia64_libunwind_frame_sniffer);
3360b725ae77Skettenis   libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
3361b725ae77Skettenis #endif
3362b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, ia64_frame_sniffer);
3363b725ae77Skettenis   frame_base_set_default (gdbarch, &ia64_frame_base);
3364b725ae77Skettenis 
3365b725ae77Skettenis   /* Settings that should be unnecessary.  */
3366b725ae77Skettenis   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
3367b725ae77Skettenis 
3368b725ae77Skettenis   set_gdbarch_remote_translate_xfer_address (
3369b725ae77Skettenis     gdbarch, ia64_remote_translate_xfer_address);
3370b725ae77Skettenis 
3371b725ae77Skettenis   set_gdbarch_print_insn (gdbarch, ia64_print_insn);
3372b725ae77Skettenis   set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
3373b725ae77Skettenis 
3374b725ae77Skettenis   return gdbarch;
3375b725ae77Skettenis }
3376b725ae77Skettenis 
3377b725ae77Skettenis extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */
3378b725ae77Skettenis 
3379b725ae77Skettenis void
_initialize_ia64_tdep(void)3380b725ae77Skettenis _initialize_ia64_tdep (void)
3381b725ae77Skettenis {
3382b725ae77Skettenis   register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init);
3383b725ae77Skettenis }
3384