1130803Smarcel/* Target-dependent code for UltraSPARC.
2130803Smarcel
3130803Smarcel   Copyright 2003, 2004 Free Software Foundation, Inc.
4130803Smarcel
5130803Smarcel   This file is part of GDB.
6130803Smarcel
7130803Smarcel   This program is free software; you can redistribute it and/or modify
8130803Smarcel   it under the terms of the GNU General Public License as published by
9130803Smarcel   the Free Software Foundation; either version 2 of the License, or
10130803Smarcel   (at your option) any later version.
11130803Smarcel
12130803Smarcel   This program is distributed in the hope that it will be useful,
13130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
14130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15130803Smarcel   GNU General Public License for more details.
16130803Smarcel
17130803Smarcel   You should have received a copy of the GNU General Public License
18130803Smarcel   along with this program; if not, write to the Free Software
19130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
20130803Smarcel   Boston, MA 02111-1307, USA.  */
21130803Smarcel
22130803Smarcel#include "defs.h"
23130803Smarcel#include "arch-utils.h"
24130803Smarcel#include "floatformat.h"
25130803Smarcel#include "frame.h"
26130803Smarcel#include "frame-base.h"
27130803Smarcel#include "frame-unwind.h"
28130803Smarcel#include "gdbcore.h"
29130803Smarcel#include "gdbtypes.h"
30130803Smarcel#include "inferior.h"
31130803Smarcel#include "symtab.h"
32130803Smarcel#include "objfiles.h"
33130803Smarcel#include "osabi.h"
34130803Smarcel#include "regcache.h"
35130803Smarcel#include "target.h"
36130803Smarcel#include "value.h"
37130803Smarcel
38130803Smarcel#include "gdb_assert.h"
39130803Smarcel#include "gdb_string.h"
40130803Smarcel
41130803Smarcel#include "sparc64-tdep.h"
42130803Smarcel
43130803Smarcel/* This file implements the The SPARC 64-bit ABI as defined by the
44130803Smarcel   section "Low-Level System Information" of the SPARC Compliance
45130803Smarcel   Definition (SCD) 2.4.1, which is the 64-bit System V psABI for
46130803Smarcel   SPARC.  */
47130803Smarcel
48130803Smarcel/* Please use the sparc32_-prefix for 32-bit specific code, the
49130803Smarcel   sparc64_-prefix for 64-bit specific code and the sparc_-prefix for
50130803Smarcel   code can handle both.  */
51130803Smarcel
52130803Smarcel/* The functions on this page are intended to be used to classify
53130803Smarcel   function arguments.  */
54130803Smarcel
55130803Smarcel/* Return the contents if register REGNUM as an address.  */
56130803Smarcel
57130803Smarcelstatic CORE_ADDR
58130803Smarcelsparc_address_from_register (int regnum)
59130803Smarcel{
60130803Smarcel  ULONGEST addr;
61130803Smarcel
62130803Smarcel  regcache_cooked_read_unsigned (current_regcache, regnum, &addr);
63130803Smarcel  return addr;
64130803Smarcel}
65130803Smarcel
66130803Smarcel/* Check whether TYPE is "Integral or Pointer".  */
67130803Smarcel
68130803Smarcelstatic int
69130803Smarcelsparc64_integral_or_pointer_p (const struct type *type)
70130803Smarcel{
71130803Smarcel  switch (TYPE_CODE (type))
72130803Smarcel    {
73130803Smarcel    case TYPE_CODE_INT:
74130803Smarcel    case TYPE_CODE_BOOL:
75130803Smarcel    case TYPE_CODE_CHAR:
76130803Smarcel    case TYPE_CODE_ENUM:
77130803Smarcel    case TYPE_CODE_RANGE:
78130803Smarcel      {
79130803Smarcel	int len = TYPE_LENGTH (type);
80130803Smarcel	gdb_assert (len == 1 || len == 2 || len == 4 || len == 8);
81130803Smarcel      }
82130803Smarcel      return 1;
83130803Smarcel    case TYPE_CODE_PTR:
84130803Smarcel    case TYPE_CODE_REF:
85130803Smarcel      {
86130803Smarcel	int len = TYPE_LENGTH (type);
87130803Smarcel	gdb_assert (len == 8);
88130803Smarcel      }
89130803Smarcel      return 1;
90130803Smarcel    default:
91130803Smarcel      break;
92130803Smarcel    }
93130803Smarcel
94130803Smarcel  return 0;
95130803Smarcel}
96130803Smarcel
97130803Smarcel/* Check whether TYPE is "Floating".  */
98130803Smarcel
99130803Smarcelstatic int
100130803Smarcelsparc64_floating_p (const struct type *type)
101130803Smarcel{
102130803Smarcel  switch (TYPE_CODE (type))
103130803Smarcel    {
104130803Smarcel    case TYPE_CODE_FLT:
105130803Smarcel      {
106130803Smarcel	int len = TYPE_LENGTH (type);
107130803Smarcel	gdb_assert (len == 4 || len == 8 || len == 16);
108130803Smarcel      }
109130803Smarcel      return 1;
110130803Smarcel    default:
111130803Smarcel      break;
112130803Smarcel    }
113130803Smarcel
114130803Smarcel  return 0;
115130803Smarcel}
116130803Smarcel
117130803Smarcel/* Check whether TYPE is "Structure or Union".  */
118130803Smarcel
119130803Smarcelstatic int
120130803Smarcelsparc64_structure_or_union_p (const struct type *type)
121130803Smarcel{
122130803Smarcel  switch (TYPE_CODE (type))
123130803Smarcel    {
124130803Smarcel    case TYPE_CODE_STRUCT:
125130803Smarcel    case TYPE_CODE_UNION:
126130803Smarcel      return 1;
127130803Smarcel    default:
128130803Smarcel      break;
129130803Smarcel    }
130130803Smarcel
131130803Smarcel  return 0;
132130803Smarcel}
133130803Smarcel
134130803Smarcel/* Register information.  */
135130803Smarcel
136130803Smarcelstruct sparc64_register_info
137130803Smarcel{
138130803Smarcel  char *name;
139130803Smarcel  struct type **type;
140130803Smarcel};
141130803Smarcel
142130803Smarcelstatic struct sparc64_register_info sparc64_register_info[] =
143130803Smarcel{
144130803Smarcel  { "g0", &builtin_type_int64 },
145130803Smarcel  { "g1", &builtin_type_int64 },
146130803Smarcel  { "g2", &builtin_type_int64 },
147130803Smarcel  { "g3", &builtin_type_int64 },
148130803Smarcel  { "g4", &builtin_type_int64 },
149130803Smarcel  { "g5", &builtin_type_int64 },
150130803Smarcel  { "g6", &builtin_type_int64 },
151130803Smarcel  { "g7", &builtin_type_int64 },
152130803Smarcel
153130803Smarcel  { "o0", &builtin_type_int64 },
154130803Smarcel  { "o1", &builtin_type_int64 },
155130803Smarcel  { "o2", &builtin_type_int64 },
156130803Smarcel  { "o3", &builtin_type_int64 },
157130803Smarcel  { "o4", &builtin_type_int64 },
158130803Smarcel  { "o5", &builtin_type_int64 },
159130803Smarcel  { "sp", &builtin_type_void_data_ptr },
160130803Smarcel  { "o7", &builtin_type_int64 },
161130803Smarcel
162130803Smarcel  { "l0", &builtin_type_int64 },
163130803Smarcel  { "l1", &builtin_type_int64 },
164130803Smarcel  { "l2", &builtin_type_int64 },
165130803Smarcel  { "l3", &builtin_type_int64 },
166130803Smarcel  { "l4", &builtin_type_int64 },
167130803Smarcel  { "l5", &builtin_type_int64 },
168130803Smarcel  { "l6", &builtin_type_int64 },
169130803Smarcel  { "l7", &builtin_type_int64 },
170130803Smarcel
171130803Smarcel  { "i0", &builtin_type_int64 },
172130803Smarcel  { "i1", &builtin_type_int64 },
173130803Smarcel  { "i2", &builtin_type_int64 },
174130803Smarcel  { "i3", &builtin_type_int64 },
175130803Smarcel  { "i4", &builtin_type_int64 },
176130803Smarcel  { "i5", &builtin_type_int64 },
177130803Smarcel  { "fp", &builtin_type_void_data_ptr },
178130803Smarcel  { "i7", &builtin_type_int64 },
179130803Smarcel
180130803Smarcel  { "f0", &builtin_type_float },
181130803Smarcel  { "f1", &builtin_type_float },
182130803Smarcel  { "f2", &builtin_type_float },
183130803Smarcel  { "f3", &builtin_type_float },
184130803Smarcel  { "f4", &builtin_type_float },
185130803Smarcel  { "f5", &builtin_type_float },
186130803Smarcel  { "f6", &builtin_type_float },
187130803Smarcel  { "f7", &builtin_type_float },
188130803Smarcel  { "f8", &builtin_type_float },
189130803Smarcel  { "f9", &builtin_type_float },
190130803Smarcel  { "f10", &builtin_type_float },
191130803Smarcel  { "f11", &builtin_type_float },
192130803Smarcel  { "f12", &builtin_type_float },
193130803Smarcel  { "f13", &builtin_type_float },
194130803Smarcel  { "f14", &builtin_type_float },
195130803Smarcel  { "f15", &builtin_type_float },
196130803Smarcel  { "f16", &builtin_type_float },
197130803Smarcel  { "f17", &builtin_type_float },
198130803Smarcel  { "f18", &builtin_type_float },
199130803Smarcel  { "f19", &builtin_type_float },
200130803Smarcel  { "f20", &builtin_type_float },
201130803Smarcel  { "f21", &builtin_type_float },
202130803Smarcel  { "f22", &builtin_type_float },
203130803Smarcel  { "f23", &builtin_type_float },
204130803Smarcel  { "f24", &builtin_type_float },
205130803Smarcel  { "f25", &builtin_type_float },
206130803Smarcel  { "f26", &builtin_type_float },
207130803Smarcel  { "f27", &builtin_type_float },
208130803Smarcel  { "f28", &builtin_type_float },
209130803Smarcel  { "f29", &builtin_type_float },
210130803Smarcel  { "f30", &builtin_type_float },
211130803Smarcel  { "f31", &builtin_type_float },
212130803Smarcel  { "f32", &builtin_type_double },
213130803Smarcel  { "f34", &builtin_type_double },
214130803Smarcel  { "f36", &builtin_type_double },
215130803Smarcel  { "f38", &builtin_type_double },
216130803Smarcel  { "f40", &builtin_type_double },
217130803Smarcel  { "f42", &builtin_type_double },
218130803Smarcel  { "f44", &builtin_type_double },
219130803Smarcel  { "f46", &builtin_type_double },
220130803Smarcel  { "f48", &builtin_type_double },
221130803Smarcel  { "f50", &builtin_type_double },
222130803Smarcel  { "f52", &builtin_type_double },
223130803Smarcel  { "f54", &builtin_type_double },
224130803Smarcel  { "f56", &builtin_type_double },
225130803Smarcel  { "f58", &builtin_type_double },
226130803Smarcel  { "f60", &builtin_type_double },
227130803Smarcel  { "f62", &builtin_type_double },
228130803Smarcel
229130803Smarcel  { "pc", &builtin_type_void_func_ptr },
230130803Smarcel  { "npc", &builtin_type_void_func_ptr },
231130803Smarcel
232130803Smarcel  /* This raw register contains the contents of %cwp, %pstate, %asi
233130803Smarcel     and %ccr as laid out in a %tstate register.  */
234130803Smarcel  /* FIXME: Give it a name until we start using register groups.  */
235130803Smarcel  { "state", &builtin_type_int64 },
236130803Smarcel
237130803Smarcel  { "fsr", &builtin_type_int64 },
238130803Smarcel  { "fprs", &builtin_type_int64 },
239130803Smarcel
240130803Smarcel  /* "Although Y is a 64-bit register, its high-order 32 bits are
241130803Smarcel     reserved and always read as 0."  */
242130803Smarcel  { "y", &builtin_type_int64 }
243130803Smarcel};
244130803Smarcel
245130803Smarcel/* Total number of registers.  */
246130803Smarcel#define SPARC64_NUM_REGS ARRAY_SIZE (sparc64_register_info)
247130803Smarcel
248130803Smarcel/* We provide the aliases %d0..%d62 and %q0..%q60 for the floating
249130803Smarcel   registers as "psuedo" registers.  */
250130803Smarcel
251130803Smarcelstatic struct sparc64_register_info sparc64_pseudo_register_info[] =
252130803Smarcel{
253130803Smarcel  { "cwp", &builtin_type_int64 },
254130803Smarcel  { "pstate", &builtin_type_int64 },
255130803Smarcel  { "asi", &builtin_type_int64 },
256130803Smarcel  { "ccr", &builtin_type_int64 },
257130803Smarcel
258130803Smarcel  { "d0", &builtin_type_double },
259130803Smarcel  { "d2", &builtin_type_double },
260130803Smarcel  { "d4", &builtin_type_double },
261130803Smarcel  { "d6", &builtin_type_double },
262130803Smarcel  { "d8", &builtin_type_double },
263130803Smarcel  { "d10", &builtin_type_double },
264130803Smarcel  { "d12", &builtin_type_double },
265130803Smarcel  { "d14", &builtin_type_double },
266130803Smarcel  { "d16", &builtin_type_double },
267130803Smarcel  { "d18", &builtin_type_double },
268130803Smarcel  { "d20", &builtin_type_double },
269130803Smarcel  { "d22", &builtin_type_double },
270130803Smarcel  { "d24", &builtin_type_double },
271130803Smarcel  { "d26", &builtin_type_double },
272130803Smarcel  { "d28", &builtin_type_double },
273130803Smarcel  { "d30", &builtin_type_double },
274130803Smarcel  { "d32", &builtin_type_double },
275130803Smarcel  { "d34", &builtin_type_double },
276130803Smarcel  { "d36", &builtin_type_double },
277130803Smarcel  { "d38", &builtin_type_double },
278130803Smarcel  { "d40", &builtin_type_double },
279130803Smarcel  { "d42", &builtin_type_double },
280130803Smarcel  { "d44", &builtin_type_double },
281130803Smarcel  { "d46", &builtin_type_double },
282130803Smarcel  { "d48", &builtin_type_double },
283130803Smarcel  { "d50", &builtin_type_double },
284130803Smarcel  { "d52", &builtin_type_double },
285130803Smarcel  { "d54", &builtin_type_double },
286130803Smarcel  { "d56", &builtin_type_double },
287130803Smarcel  { "d58", &builtin_type_double },
288130803Smarcel  { "d60", &builtin_type_double },
289130803Smarcel  { "d62", &builtin_type_double },
290130803Smarcel
291130803Smarcel  { "q0", &builtin_type_long_double },
292130803Smarcel  { "q4", &builtin_type_long_double },
293130803Smarcel  { "q8", &builtin_type_long_double },
294130803Smarcel  { "q12", &builtin_type_long_double },
295130803Smarcel  { "q16", &builtin_type_long_double },
296130803Smarcel  { "q20", &builtin_type_long_double },
297130803Smarcel  { "q24", &builtin_type_long_double },
298130803Smarcel  { "q28", &builtin_type_long_double },
299130803Smarcel  { "q32", &builtin_type_long_double },
300130803Smarcel  { "q36", &builtin_type_long_double },
301130803Smarcel  { "q40", &builtin_type_long_double },
302130803Smarcel  { "q44", &builtin_type_long_double },
303130803Smarcel  { "q48", &builtin_type_long_double },
304130803Smarcel  { "q52", &builtin_type_long_double },
305130803Smarcel  { "q56", &builtin_type_long_double },
306130803Smarcel  { "q60", &builtin_type_long_double }
307130803Smarcel};
308130803Smarcel
309130803Smarcel/* Total number of pseudo registers.  */
310130803Smarcel#define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_info)
311130803Smarcel
312130803Smarcel/* Return the name of register REGNUM.  */
313130803Smarcel
314130803Smarcelstatic const char *
315130803Smarcelsparc64_register_name (int regnum)
316130803Smarcel{
317130803Smarcel  if (regnum >= 0 && regnum < SPARC64_NUM_REGS)
318130803Smarcel    return sparc64_register_info[regnum].name;
319130803Smarcel
320130803Smarcel  if (regnum >= SPARC64_NUM_REGS
321130803Smarcel      && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS)
322130803Smarcel    return sparc64_pseudo_register_info[regnum - SPARC64_NUM_REGS].name;
323130803Smarcel
324130803Smarcel  return NULL;
325130803Smarcel}
326130803Smarcel
327130803Smarcel/* Return the GDB type object for the "standard" data type of data in
328130803Smarcel   register REGNUM. */
329130803Smarcel
330130803Smarcelstatic struct type *
331130803Smarcelsparc64_register_type (struct gdbarch *gdbarch, int regnum)
332130803Smarcel{
333130803Smarcel  if (regnum >= SPARC64_NUM_REGS
334130803Smarcel      && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS)
335130803Smarcel    return *sparc64_pseudo_register_info[regnum - SPARC64_NUM_REGS].type;
336130803Smarcel
337130803Smarcel  gdb_assert (regnum >= 0 && regnum < SPARC64_NUM_REGS);
338130803Smarcel  return *sparc64_register_info[regnum].type;
339130803Smarcel}
340130803Smarcel
341130803Smarcelstatic void
342130803Smarcelsparc64_pseudo_register_read (struct gdbarch *gdbarch,
343130803Smarcel			      struct regcache *regcache,
344130803Smarcel			      int regnum, void *buf)
345130803Smarcel{
346130803Smarcel  gdb_assert (regnum >= SPARC64_NUM_REGS);
347130803Smarcel
348130803Smarcel  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
349130803Smarcel    {
350130803Smarcel      regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
351130803Smarcel      regcache_raw_read (regcache, regnum, buf);
352130803Smarcel      regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4);
353130803Smarcel    }
354130803Smarcel  else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM)
355130803Smarcel    {
356130803Smarcel      regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM);
357130803Smarcel      regcache_raw_read (regcache, regnum, buf);
358130803Smarcel    }
359130803Smarcel  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
360130803Smarcel    {
361130803Smarcel      regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);
362130803Smarcel      regcache_raw_read (regcache, regnum, buf);
363130803Smarcel      regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4);
364130803Smarcel      regcache_raw_read (regcache, regnum + 2, ((char *)buf) + 8);
365130803Smarcel      regcache_raw_read (regcache, regnum + 3, ((char *)buf) + 12);
366130803Smarcel    }
367130803Smarcel  else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM)
368130803Smarcel    {
369130803Smarcel      regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM);
370130803Smarcel      regcache_raw_read (regcache, regnum, buf);
371130803Smarcel      regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 8);
372130803Smarcel    }
373130803Smarcel  else if (regnum == SPARC64_CWP_REGNUM
374130803Smarcel	   || regnum == SPARC64_PSTATE_REGNUM
375130803Smarcel	   || regnum == SPARC64_ASI_REGNUM
376130803Smarcel	   || regnum == SPARC64_CCR_REGNUM)
377130803Smarcel    {
378130803Smarcel      ULONGEST state;
379130803Smarcel
380130803Smarcel      regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
381130803Smarcel      switch (regnum)
382130803Smarcel	{
383130803Smarcel	case SPARC64_CWP_REGNUM:
384130803Smarcel	  state = (state >> 0) & ((1 << 5) - 1);
385130803Smarcel	  break;
386130803Smarcel	case SPARC64_PSTATE_REGNUM:
387130803Smarcel	  state = (state >> 8) & ((1 << 12) - 1);
388130803Smarcel	  break;
389130803Smarcel	case SPARC64_ASI_REGNUM:
390130803Smarcel	  state = (state >> 24) & ((1 << 8) - 1);
391130803Smarcel	  break;
392130803Smarcel	case SPARC64_CCR_REGNUM:
393130803Smarcel	  state = (state >> 32) & ((1 << 8) - 1);
394130803Smarcel	  break;
395130803Smarcel	}
396130803Smarcel      store_unsigned_integer (buf, 8, state);
397130803Smarcel    }
398130803Smarcel}
399130803Smarcel
400130803Smarcelstatic void
401130803Smarcelsparc64_pseudo_register_write (struct gdbarch *gdbarch,
402130803Smarcel			       struct regcache *regcache,
403130803Smarcel			       int regnum, const void *buf)
404130803Smarcel{
405130803Smarcel  gdb_assert (regnum >= SPARC64_NUM_REGS);
406130803Smarcel
407130803Smarcel  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
408130803Smarcel    {
409130803Smarcel      regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
410130803Smarcel      regcache_raw_write (regcache, regnum, buf);
411130803Smarcel      regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4);
412130803Smarcel    }
413130803Smarcel  else if (regnum >= SPARC64_D32_REGNUM && regnum <= SPARC64_D62_REGNUM)
414130803Smarcel    {
415130803Smarcel      regnum = SPARC64_F32_REGNUM + (regnum - SPARC64_D32_REGNUM);
416130803Smarcel      regcache_raw_write (regcache, regnum, buf);
417130803Smarcel    }
418130803Smarcel  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q28_REGNUM)
419130803Smarcel    {
420130803Smarcel      regnum = SPARC_F0_REGNUM + 4 * (regnum - SPARC64_Q0_REGNUM);
421130803Smarcel      regcache_raw_write (regcache, regnum, buf);
422130803Smarcel      regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4);
423130803Smarcel      regcache_raw_write (regcache, regnum + 2, ((const char *)buf) + 8);
424130803Smarcel      regcache_raw_write (regcache, regnum + 3, ((const char *)buf) + 12);
425130803Smarcel    }
426130803Smarcel  else if (regnum >= SPARC64_Q32_REGNUM && regnum <= SPARC64_Q60_REGNUM)
427130803Smarcel    {
428130803Smarcel      regnum = SPARC64_F32_REGNUM + 2 * (regnum - SPARC64_Q32_REGNUM);
429130803Smarcel      regcache_raw_write (regcache, regnum, buf);
430130803Smarcel      regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 8);
431130803Smarcel    }
432130803Smarcel  else if (regnum == SPARC64_CWP_REGNUM
433130803Smarcel	   || regnum == SPARC64_PSTATE_REGNUM
434130803Smarcel	   || regnum == SPARC64_ASI_REGNUM
435130803Smarcel	   || regnum == SPARC64_CCR_REGNUM)
436130803Smarcel    {
437130803Smarcel      ULONGEST state, bits;
438130803Smarcel
439130803Smarcel      regcache_raw_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
440130803Smarcel      bits = extract_unsigned_integer (buf, 8);
441130803Smarcel      switch (regnum)
442130803Smarcel	{
443130803Smarcel	case SPARC64_CWP_REGNUM:
444130803Smarcel	  state |= ((bits & ((1 << 5) - 1)) << 0);
445130803Smarcel	  break;
446130803Smarcel	case SPARC64_PSTATE_REGNUM:
447130803Smarcel	  state |= ((bits & ((1 << 12) - 1)) << 8);
448130803Smarcel	  break;
449130803Smarcel	case SPARC64_ASI_REGNUM:
450130803Smarcel	  state |= ((bits & ((1 << 8) - 1)) << 24);
451130803Smarcel	  break;
452130803Smarcel	case SPARC64_CCR_REGNUM:
453130803Smarcel	  state |= ((bits & ((1 << 8) - 1)) << 32);
454130803Smarcel	  break;
455130803Smarcel	}
456130803Smarcel      regcache_raw_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
457130803Smarcel    }
458130803Smarcel}
459130803Smarcel
460130803Smarcel
461130803Smarcel/* Return PC of first real instruction of the function starting at
462130803Smarcel   START_PC.  */
463130803Smarcel
464130803Smarcelstatic CORE_ADDR
465130803Smarcelsparc64_skip_prologue (CORE_ADDR start_pc)
466130803Smarcel{
467130803Smarcel  struct symtab_and_line sal;
468130803Smarcel  CORE_ADDR func_start, func_end;
469130803Smarcel  struct sparc_frame_cache cache;
470130803Smarcel
471130803Smarcel  /* This is the preferred method, find the end of the prologue by
472130803Smarcel     using the debugging information.  */
473130803Smarcel  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
474130803Smarcel    {
475130803Smarcel      sal = find_pc_line (func_start, 0);
476130803Smarcel
477130803Smarcel      if (sal.end < func_end
478130803Smarcel	  && start_pc <= sal.end)
479130803Smarcel	return sal.end;
480130803Smarcel    }
481130803Smarcel
482130803Smarcel  return sparc_analyze_prologue (start_pc, 0xffffffffffffffffULL, &cache);
483130803Smarcel}
484130803Smarcel
485130803Smarcel/* Normal frames.  */
486130803Smarcel
487130803Smarcelstatic struct sparc_frame_cache *
488130803Smarcelsparc64_frame_cache (struct frame_info *next_frame, void **this_cache)
489130803Smarcel{
490130803Smarcel  return sparc_frame_cache (next_frame, this_cache);
491130803Smarcel}
492130803Smarcel
493130803Smarcelstatic void
494130803Smarcelsparc64_frame_this_id (struct frame_info *next_frame, void **this_cache,
495130803Smarcel		       struct frame_id *this_id)
496130803Smarcel{
497130803Smarcel  struct sparc_frame_cache *cache =
498130803Smarcel    sparc64_frame_cache (next_frame, this_cache);
499130803Smarcel
500130803Smarcel  /* This marks the outermost frame.  */
501130803Smarcel  if (cache->base == 0)
502130803Smarcel    return;
503130803Smarcel
504130803Smarcel  (*this_id) = frame_id_build (cache->base, cache->pc);
505130803Smarcel}
506130803Smarcel
507130803Smarcelstatic void
508130803Smarcelsparc64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
509130803Smarcel			     int regnum, int *optimizedp,
510130803Smarcel			     enum lval_type *lvalp, CORE_ADDR *addrp,
511130803Smarcel			     int *realnump, void *valuep)
512130803Smarcel{
513130803Smarcel  struct sparc_frame_cache *cache =
514130803Smarcel    sparc64_frame_cache (next_frame, this_cache);
515130803Smarcel
516130803Smarcel  if (regnum == SPARC64_PC_REGNUM || regnum == SPARC64_NPC_REGNUM)
517130803Smarcel    {
518130803Smarcel      *optimizedp = 0;
519130803Smarcel      *lvalp = not_lval;
520130803Smarcel      *addrp = 0;
521130803Smarcel      *realnump = -1;
522130803Smarcel      if (valuep)
523130803Smarcel	{
524130803Smarcel	  CORE_ADDR pc = (regnum == SPARC64_NPC_REGNUM) ? 4 : 0;
525130803Smarcel
526130803Smarcel	  regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
527130803Smarcel	  pc += frame_unwind_register_unsigned (next_frame, regnum) + 8;
528130803Smarcel	  store_unsigned_integer (valuep, 8, pc);
529130803Smarcel	}
530130803Smarcel      return;
531130803Smarcel    }
532130803Smarcel
533130803Smarcel  /* The previous frame's `local' and `in' registers have been saved
534130803Smarcel     in the register save area.  */
535130803Smarcel  if (!cache->frameless_p
536130803Smarcel      && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)
537130803Smarcel    {
538130803Smarcel      *optimizedp = 0;
539130803Smarcel      *lvalp = lval_memory;
540130803Smarcel      *addrp = cache->base + BIAS + (regnum - SPARC_L0_REGNUM) * 8;
541130803Smarcel      *realnump = -1;
542130803Smarcel      if (valuep)
543130803Smarcel	{
544130803Smarcel	  struct gdbarch *gdbarch = get_frame_arch (next_frame);
545130803Smarcel
546130803Smarcel	  /* Read the value in from memory.  */
547130803Smarcel	  read_memory (*addrp, valuep, register_size (gdbarch, regnum));
548130803Smarcel	}
549130803Smarcel      return;
550130803Smarcel    }
551130803Smarcel
552130803Smarcel  /* The previous frame's `out' registers are accessable as the
553130803Smarcel     current frame's `in' registers.  */
554130803Smarcel  if (!cache->frameless_p
555130803Smarcel      && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
556130803Smarcel    regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
557130803Smarcel
558130803Smarcel  frame_register_unwind (next_frame, regnum,
559130803Smarcel			 optimizedp, lvalp, addrp, realnump, valuep);
560130803Smarcel}
561130803Smarcel
562130803Smarcelstatic const struct frame_unwind sparc64_frame_unwind =
563130803Smarcel{
564130803Smarcel  NORMAL_FRAME,
565130803Smarcel  sparc64_frame_this_id,
566130803Smarcel  sparc64_frame_prev_register
567130803Smarcel};
568130803Smarcel
569130803Smarcelstatic const struct frame_unwind *
570130803Smarcelsparc64_frame_sniffer (struct frame_info *next_frame)
571130803Smarcel{
572130803Smarcel  return &sparc64_frame_unwind;
573130803Smarcel}
574130803Smarcel
575130803Smarcel
576130803Smarcelstatic CORE_ADDR
577130803Smarcelsparc64_frame_base_address (struct frame_info *next_frame, void **this_cache)
578130803Smarcel{
579130803Smarcel  struct sparc_frame_cache *cache =
580130803Smarcel    sparc64_frame_cache (next_frame, this_cache);
581130803Smarcel
582130803Smarcel  /* ??? Should we take BIAS into account here?  */
583130803Smarcel  return cache->base;
584130803Smarcel}
585130803Smarcel
586130803Smarcelstatic const struct frame_base sparc64_frame_base =
587130803Smarcel{
588130803Smarcel  &sparc64_frame_unwind,
589130803Smarcel  sparc64_frame_base_address,
590130803Smarcel  sparc64_frame_base_address,
591130803Smarcel  sparc64_frame_base_address
592130803Smarcel};
593130803Smarcel
594130803Smarcel/* Check whether TYPE must be 16-byte aligned.  */
595130803Smarcel
596130803Smarcelstatic int
597130803Smarcelsparc64_16_byte_align_p (struct type *type)
598130803Smarcel{
599130803Smarcel  if (sparc64_floating_p (type) && TYPE_LENGTH (type) == 16)
600130803Smarcel    return 1;
601130803Smarcel
602130803Smarcel  if (sparc64_structure_or_union_p (type))
603130803Smarcel    {
604130803Smarcel      int i;
605130803Smarcel
606130803Smarcel      for (i = 0; i < TYPE_NFIELDS (type); i++)
607130803Smarcel	{
608130803Smarcel	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
609130803Smarcel
610130803Smarcel	  if (sparc64_16_byte_align_p (subtype))
611130803Smarcel	    return 1;
612130803Smarcel	}
613130803Smarcel    }
614130803Smarcel
615130803Smarcel  return 0;
616130803Smarcel}
617130803Smarcel
618130803Smarcel/* Store floating fields of element ELEMENT of an "parameter array"
619130803Smarcel   that has type TYPE and is stored at BITPOS in VALBUF in the
620130803Smarcel   apropriate registers of REGCACHE.  This function can be called
621130803Smarcel   recursively and therefore handles floating types in addition to
622130803Smarcel   structures.  */
623130803Smarcel
624130803Smarcelstatic void
625130803Smarcelsparc64_store_floating_fields (struct regcache *regcache, struct type *type,
626130803Smarcel			       char *valbuf, int element, int bitpos)
627130803Smarcel{
628130803Smarcel  gdb_assert (element < 16);
629130803Smarcel
630130803Smarcel  if (sparc64_floating_p (type))
631130803Smarcel    {
632130803Smarcel      int len = TYPE_LENGTH (type);
633130803Smarcel      int regnum;
634130803Smarcel
635130803Smarcel      if (len == 16)
636130803Smarcel	{
637130803Smarcel	  gdb_assert (bitpos == 0);
638130803Smarcel	  gdb_assert ((element % 2) == 0);
639130803Smarcel
640130803Smarcel	  regnum = SPARC64_Q0_REGNUM + element / 2;
641130803Smarcel	  regcache_cooked_write (regcache, regnum, valbuf);
642130803Smarcel	}
643130803Smarcel      else if (len == 8)
644130803Smarcel	{
645130803Smarcel	  gdb_assert (bitpos == 0 || bitpos == 64);
646130803Smarcel
647130803Smarcel	  regnum = SPARC64_D0_REGNUM + element + bitpos / 64;
648130803Smarcel	  regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8));
649130803Smarcel	}
650130803Smarcel      else
651130803Smarcel	{
652130803Smarcel	  gdb_assert (len == 4);
653130803Smarcel	  gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 128);
654130803Smarcel
655130803Smarcel	  regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32;
656130803Smarcel	  regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8));
657130803Smarcel	}
658130803Smarcel    }
659130803Smarcel  else if (sparc64_structure_or_union_p (type))
660130803Smarcel    {
661130803Smarcel      int i;
662130803Smarcel
663130803Smarcel      for (i = 0; i < TYPE_NFIELDS (type); i++)
664130803Smarcel	{
665130803Smarcel	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
666130803Smarcel	  int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
667130803Smarcel
668130803Smarcel	  sparc64_store_floating_fields (regcache, subtype, valbuf,
669130803Smarcel					 element, subpos);
670130803Smarcel	}
671130803Smarcel
672130803Smarcel      /* GCC has an interesting bug.  If TYPE is a structure that has
673130803Smarcel         a single `float' member, GCC doesn't treat it as a structure
674130803Smarcel         at all, but rather as an ordinary `float' argument.  This
675130803Smarcel         argument will be stored in %f1, as required by the psABI.
676130803Smarcel         However, as a member of a structure the psABI requires it to
677130803Smarcel         be stored in %f0.  This bug is present in GCC 3.3.2, but
678130803Smarcel         probably in older releases to.  To appease GCC, if a
679130803Smarcel         structure has only a single `float' member, we store its
680130803Smarcel         value in %f1 too (we already have stored in %f0).  */
681130803Smarcel      if (TYPE_NFIELDS (type) == 1)
682130803Smarcel	{
683130803Smarcel	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, 0));
684130803Smarcel
685130803Smarcel	  if (sparc64_floating_p (subtype) && TYPE_LENGTH (subtype) == 4)
686130803Smarcel	    regcache_cooked_write (regcache, SPARC_F1_REGNUM, valbuf);
687130803Smarcel	}
688130803Smarcel    }
689130803Smarcel}
690130803Smarcel
691130803Smarcel/* Fetch floating fields from a variable of type TYPE from the
692130803Smarcel   appropriate registers for BITPOS in REGCACHE and store it at BITPOS
693130803Smarcel   in VALBUF.  This function can be called recursively and therefore
694130803Smarcel   handles floating types in addition to structures.  */
695130803Smarcel
696130803Smarcelstatic void
697130803Smarcelsparc64_extract_floating_fields (struct regcache *regcache, struct type *type,
698130803Smarcel				 char *valbuf, int bitpos)
699130803Smarcel{
700130803Smarcel  if (sparc64_floating_p (type))
701130803Smarcel    {
702130803Smarcel      int len = TYPE_LENGTH (type);
703130803Smarcel      int regnum;
704130803Smarcel
705130803Smarcel      if (len == 16)
706130803Smarcel	{
707130803Smarcel	  gdb_assert (bitpos == 0 || bitpos == 128);
708130803Smarcel
709130803Smarcel	  regnum = SPARC64_Q0_REGNUM + bitpos / 128;
710130803Smarcel	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
711130803Smarcel	}
712130803Smarcel      else if (len == 8)
713130803Smarcel	{
714130803Smarcel	  gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256);
715130803Smarcel
716130803Smarcel	  regnum = SPARC64_D0_REGNUM + bitpos / 64;
717130803Smarcel	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
718130803Smarcel	}
719130803Smarcel      else
720130803Smarcel	{
721130803Smarcel	  gdb_assert (len == 4);
722130803Smarcel	  gdb_assert (bitpos % 32 == 0 && bitpos >= 0 && bitpos < 256);
723130803Smarcel
724130803Smarcel	  regnum = SPARC_F0_REGNUM + bitpos / 32;
725130803Smarcel	  regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
726130803Smarcel	}
727130803Smarcel    }
728130803Smarcel  else if (sparc64_structure_or_union_p (type))
729130803Smarcel    {
730130803Smarcel      int i;
731130803Smarcel
732130803Smarcel      for (i = 0; i < TYPE_NFIELDS (type); i++)
733130803Smarcel	{
734130803Smarcel	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
735130803Smarcel	  int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
736130803Smarcel
737130803Smarcel	  sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos);
738130803Smarcel	}
739130803Smarcel    }
740130803Smarcel}
741130803Smarcel
742130803Smarcel/* Store the NARGS arguments ARGS and STRUCT_ADDR (if STRUCT_RETURN is
743130803Smarcel   non-zero) in REGCACHE and on the stack (starting from address SP).  */
744130803Smarcel
745130803Smarcelstatic CORE_ADDR
746130803Smarcelsparc64_store_arguments (struct regcache *regcache, int nargs,
747130803Smarcel			 struct value **args, CORE_ADDR sp,
748130803Smarcel			 int struct_return, CORE_ADDR struct_addr)
749130803Smarcel{
750130803Smarcel  /* Number of extended words in the "parameter array".  */
751130803Smarcel  int num_elements = 0;
752130803Smarcel  int element = 0;
753130803Smarcel  int i;
754130803Smarcel
755130803Smarcel  /* Take BIAS into account.  */
756130803Smarcel  sp += BIAS;
757130803Smarcel
758130803Smarcel  /* First we calculate the number of extended words in the "parameter
759130803Smarcel     array".  While doing so we also convert some of the arguments.  */
760130803Smarcel
761130803Smarcel  if (struct_return)
762130803Smarcel    num_elements++;
763130803Smarcel
764130803Smarcel  for (i = 0; i < nargs; i++)
765130803Smarcel    {
766130803Smarcel      struct type *type = VALUE_TYPE (args[i]);
767130803Smarcel      int len = TYPE_LENGTH (type);
768130803Smarcel
769130803Smarcel      if (sparc64_structure_or_union_p (type))
770130803Smarcel	{
771130803Smarcel	  /* Structure or Union arguments.  */
772130803Smarcel	  if (len <= 16)
773130803Smarcel	    {
774130803Smarcel	      if (num_elements % 2 && sparc64_16_byte_align_p (type))
775130803Smarcel		num_elements++;
776130803Smarcel	      num_elements += ((len + 7) / 8);
777130803Smarcel	    }
778130803Smarcel	  else
779130803Smarcel	    {
780130803Smarcel	      /* The psABI says that "Structures or unions larger than
781130803Smarcel		 sixteen bytes are copied by the caller and passed
782130803Smarcel		 indirectly; the caller will pass the address of a
783130803Smarcel		 correctly aligned structure value.  This sixty-four
784130803Smarcel		 bit address will occupy one word in the parameter
785130803Smarcel		 array, and may be promoted to an %o register like any
786130803Smarcel		 other pointer value."  Allocate memory for these
787130803Smarcel		 values on the stack.  */
788130803Smarcel	      sp -= len;
789130803Smarcel
790130803Smarcel	      /* Use 16-byte alignment for these values.  That's
791130803Smarcel                 always correct, and wasting a few bytes shouldn't be
792130803Smarcel                 a problem.  */
793130803Smarcel	      sp &= ~0xf;
794130803Smarcel
795130803Smarcel	      write_memory (sp, VALUE_CONTENTS (args[i]), len);
796130803Smarcel	      args[i] = value_from_pointer (lookup_pointer_type (type), sp);
797130803Smarcel	      num_elements++;
798130803Smarcel	    }
799130803Smarcel	}
800130803Smarcel      else if (sparc64_floating_p (type))
801130803Smarcel	{
802130803Smarcel	  /* Floating arguments.  */
803130803Smarcel
804130803Smarcel	  if (len == 16)
805130803Smarcel	    {
806130803Smarcel	      /* The psABI says that "Each quad-precision parameter
807130803Smarcel                 value will be assigned to two extended words in the
808130803Smarcel                 parameter array.  */
809130803Smarcel	      num_elements += 2;
810130803Smarcel
811130803Smarcel	      /* The psABI says that "Long doubles must be
812130803Smarcel                 quad-aligned, and thus a hole might be introduced
813130803Smarcel                 into the parameter array to force alignment."  Skip
814130803Smarcel                 an element if necessary.  */
815130803Smarcel	      if (num_elements % 2)
816130803Smarcel		num_elements++;
817130803Smarcel	    }
818130803Smarcel	  else
819130803Smarcel	    num_elements++;
820130803Smarcel	}
821130803Smarcel      else
822130803Smarcel	{
823130803Smarcel	  /* Integral and pointer arguments.  */
824130803Smarcel	  gdb_assert (sparc64_integral_or_pointer_p (type));
825130803Smarcel
826130803Smarcel	  /* The psABI says that "Each argument value of integral type
827130803Smarcel	     smaller than an extended word will be widened by the
828130803Smarcel	     caller to an extended word according to the signed-ness
829130803Smarcel	     of the argument type."  */
830130803Smarcel	  if (len < 8)
831130803Smarcel	    args[i] = value_cast (builtin_type_int64, args[i]);
832130803Smarcel	  num_elements++;
833130803Smarcel	}
834130803Smarcel    }
835130803Smarcel
836130803Smarcel  /* Allocate the "parameter array".  */
837130803Smarcel  sp -= num_elements * 8;
838130803Smarcel
839130803Smarcel  /* The psABI says that "Every stack frame must be 16-byte aligned."  */
840130803Smarcel  sp &= ~0xf;
841130803Smarcel
842130803Smarcel  /* Now we store the arguments in to the "paramater array".  Some
843130803Smarcel     Integer or Pointer arguments and Structure or Union arguments
844130803Smarcel     will be passed in %o registers.  Some Floating arguments and
845130803Smarcel     floating members of structures are passed in floating-point
846130803Smarcel     registers.  However, for functions with variable arguments,
847130803Smarcel     floating arguments are stored in an %0 register, and for
848130803Smarcel     functions without a prototype floating arguments are stored in
849130803Smarcel     both a floating-point and an %o registers, or a floating-point
850130803Smarcel     register and memory.  To simplify the logic here we always pass
851130803Smarcel     arguments in memory, an %o register, and a floating-point
852130803Smarcel     register if appropriate.  This should be no problem since the
853130803Smarcel     contents of any unused memory or registers in the "parameter
854130803Smarcel     array" are undefined.  */
855130803Smarcel
856130803Smarcel  if (struct_return)
857130803Smarcel    {
858130803Smarcel      regcache_cooked_write_unsigned (regcache, SPARC_O0_REGNUM, struct_addr);
859130803Smarcel      element++;
860130803Smarcel    }
861130803Smarcel
862130803Smarcel  for (i = 0; i < nargs; i++)
863130803Smarcel    {
864130803Smarcel      char *valbuf = VALUE_CONTENTS (args[i]);
865130803Smarcel      struct type *type = VALUE_TYPE (args[i]);
866130803Smarcel      int len = TYPE_LENGTH (type);
867130803Smarcel      int regnum = -1;
868130803Smarcel      char buf[16];
869130803Smarcel
870130803Smarcel      if (sparc64_structure_or_union_p (type))
871130803Smarcel	{
872130803Smarcel	  /* Structure or Union arguments.  */
873130803Smarcel	  gdb_assert (len <= 16);
874130803Smarcel	  memset (buf, 0, sizeof (buf));
875130803Smarcel	  valbuf = memcpy (buf, valbuf, len);
876130803Smarcel
877130803Smarcel	  if (element % 2 && sparc64_16_byte_align_p (type))
878130803Smarcel	    element++;
879130803Smarcel
880130803Smarcel	  if (element < 6)
881130803Smarcel	    {
882130803Smarcel	      regnum = SPARC_O0_REGNUM + element;
883130803Smarcel	      if (len > 8 && element < 5)
884130803Smarcel		regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
885130803Smarcel	    }
886130803Smarcel
887130803Smarcel	  if (element < 16)
888130803Smarcel	    sparc64_store_floating_fields (regcache, type, valbuf, element, 0);
889130803Smarcel	}
890130803Smarcel      else if (sparc64_floating_p (type))
891130803Smarcel	{
892130803Smarcel	  /* Floating arguments.  */
893130803Smarcel	  if (len == 16)
894130803Smarcel	    {
895130803Smarcel	      if (element % 2)
896130803Smarcel		element++;
897130803Smarcel	      if (element < 16)
898130803Smarcel		regnum = SPARC64_Q0_REGNUM + element / 2;
899130803Smarcel	    }
900130803Smarcel	  else if (len == 8)
901130803Smarcel	    {
902130803Smarcel	      if (element < 16)
903130803Smarcel		regnum = SPARC64_D0_REGNUM + element;
904130803Smarcel	    }
905130803Smarcel	  else
906130803Smarcel	    {
907130803Smarcel	      /* The psABI says "Each single-precision parameter value
908130803Smarcel                 will be assigned to one extended word in the
909130803Smarcel                 parameter array, and right-justified within that
910130803Smarcel                 word; the left half (even floatregister) is
911130803Smarcel                 undefined."  Even though the psABI says that "the
912130803Smarcel                 left half is undefined", set it to zero here.  */
913130803Smarcel	      memset (buf, 0, 4);
914130803Smarcel	      memcpy (buf + 4, valbuf, 4);
915130803Smarcel	      valbuf = buf;
916130803Smarcel	      len = 8;
917130803Smarcel	      if (element < 16)
918130803Smarcel		regnum = SPARC64_D0_REGNUM + element;
919130803Smarcel	    }
920130803Smarcel	}
921130803Smarcel      else
922130803Smarcel	{
923130803Smarcel	  /* Integral and pointer arguments.  */
924130803Smarcel	  gdb_assert (len == 8);
925130803Smarcel	  if (element < 6)
926130803Smarcel	    regnum = SPARC_O0_REGNUM + element;
927130803Smarcel	}
928130803Smarcel
929130803Smarcel      if (regnum != -1)
930130803Smarcel	{
931130803Smarcel	  regcache_cooked_write (regcache, regnum, valbuf);
932130803Smarcel
933130803Smarcel	  /* If we're storing the value in a floating-point register,
934130803Smarcel             also store it in the corresponding %0 register(s).  */
935130803Smarcel	  if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM)
936130803Smarcel	    {
937130803Smarcel	      gdb_assert (element < 6);
938130803Smarcel	      regnum = SPARC_O0_REGNUM + element;
939130803Smarcel	      regcache_cooked_write (regcache, regnum, valbuf);
940130803Smarcel	    }
941130803Smarcel	  else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
942130803Smarcel	    {
943130803Smarcel	      gdb_assert (element < 6);
944130803Smarcel	      regnum = SPARC_O0_REGNUM + element;
945130803Smarcel	      regcache_cooked_write (regcache, regnum, valbuf);
946130803Smarcel	      regcache_cooked_write (regcache, regnum + 1, valbuf);
947130803Smarcel	    }
948130803Smarcel	}
949130803Smarcel
950130803Smarcel      /* Always store the argument in memeory.  */
951130803Smarcel      write_memory (sp + element * 8, valbuf, len);
952130803Smarcel      element += ((len + 7) / 8);
953130803Smarcel    }
954130803Smarcel
955130803Smarcel  gdb_assert (element == num_elements);
956130803Smarcel
957130803Smarcel  /* Take BIAS into account.  */
958130803Smarcel  sp -= BIAS;
959130803Smarcel  return sp;
960130803Smarcel}
961130803Smarcel
962130803Smarcelstatic CORE_ADDR
963130803Smarcelsparc64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
964130803Smarcel			 struct regcache *regcache, CORE_ADDR bp_addr,
965130803Smarcel			 int nargs, struct value **args, CORE_ADDR sp,
966130803Smarcel			 int struct_return, CORE_ADDR struct_addr)
967130803Smarcel{
968130803Smarcel  /* Set return address.  */
969130803Smarcel  regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, bp_addr - 8);
970130803Smarcel
971130803Smarcel  /* Set up function arguments.  */
972130803Smarcel  sp = sparc64_store_arguments (regcache, nargs, args, sp,
973130803Smarcel				struct_return, struct_addr);
974130803Smarcel
975130803Smarcel  /* Allocate the register save area.  */
976130803Smarcel  sp -= 16 * 8;
977130803Smarcel
978130803Smarcel  /* Stack should be 16-byte aligned at this point.  */
979130803Smarcel  gdb_assert ((sp + BIAS) % 16 == 0);
980130803Smarcel
981130803Smarcel  /* Finally, update the stack pointer.  */
982130803Smarcel  regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp);
983130803Smarcel
984130803Smarcel  return sp;
985130803Smarcel}
986130803Smarcel
987130803Smarcel
988130803Smarcel/* Extract from an array REGBUF containing the (raw) register state, a
989130803Smarcel   function return value of TYPE, and copy that into VALBUF.  */
990130803Smarcel
991130803Smarcelstatic void
992130803Smarcelsparc64_extract_return_value (struct type *type, struct regcache *regcache,
993130803Smarcel			      void *valbuf)
994130803Smarcel{
995130803Smarcel  int len = TYPE_LENGTH (type);
996130803Smarcel  char buf[32];
997130803Smarcel  int i;
998130803Smarcel
999130803Smarcel  if (sparc64_structure_or_union_p (type))
1000130803Smarcel    {
1001130803Smarcel      /* Structure or Union return values.  */
1002130803Smarcel      gdb_assert (len <= 32);
1003130803Smarcel
1004130803Smarcel      for (i = 0; i < ((len + 7) / 8); i++)
1005130803Smarcel	regcache_cooked_read (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
1006130803Smarcel      if (TYPE_CODE (type) != TYPE_CODE_UNION)
1007130803Smarcel	sparc64_extract_floating_fields (regcache, type, buf, 0);
1008130803Smarcel      memcpy (valbuf, buf, len);
1009130803Smarcel    }
1010130803Smarcel  else if (sparc64_floating_p (type))
1011130803Smarcel    {
1012130803Smarcel      /* Floating return values.  */
1013130803Smarcel      for (i = 0; i < len / 4; i++)
1014130803Smarcel	regcache_cooked_read (regcache, SPARC_F0_REGNUM + i, buf + i * 4);
1015130803Smarcel      memcpy (valbuf, buf, len);
1016130803Smarcel    }
1017130803Smarcel  else
1018130803Smarcel    {
1019130803Smarcel      /* Integral and pointer return values.  */
1020130803Smarcel      gdb_assert (sparc64_integral_or_pointer_p (type));
1021130803Smarcel
1022130803Smarcel      /* Just stripping off any unused bytes should preserve the
1023130803Smarcel         signed-ness just fine.  */
1024130803Smarcel      regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
1025130803Smarcel      memcpy (valbuf, buf + 8 - len, len);
1026130803Smarcel    }
1027130803Smarcel}
1028130803Smarcel
1029130803Smarcel/* Write into the appropriate registers a function return value stored
1030130803Smarcel   in VALBUF of type TYPE.  */
1031130803Smarcel
1032130803Smarcelstatic void
1033130803Smarcelsparc64_store_return_value (struct type *type, struct regcache *regcache,
1034130803Smarcel			    const void *valbuf)
1035130803Smarcel{
1036130803Smarcel  int len = TYPE_LENGTH (type);
1037130803Smarcel  char buf[16];
1038130803Smarcel  int i;
1039130803Smarcel
1040130803Smarcel  if (sparc64_structure_or_union_p (type))
1041130803Smarcel    {
1042130803Smarcel      /* Structure or Union return values.  */
1043130803Smarcel      gdb_assert (len <= 32);
1044130803Smarcel
1045130803Smarcel      /* Simplify matters by storing the complete value (including
1046130803Smarcel         floating members) into %o0 and %o1.  Floating members are
1047130803Smarcel         also store in the appropriate floating-point registers.  */
1048130803Smarcel      memset (buf, 0, sizeof (buf));
1049130803Smarcel      memcpy (buf, valbuf, len);
1050130803Smarcel      for (i = 0; i < ((len + 7) / 8); i++)
1051130803Smarcel	regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
1052130803Smarcel      if (TYPE_CODE (type) != TYPE_CODE_UNION)
1053130803Smarcel	sparc64_store_floating_fields (regcache, type, buf, 0, 0);
1054130803Smarcel    }
1055130803Smarcel  else if (sparc64_floating_p (type))
1056130803Smarcel    {
1057130803Smarcel      /* Floating return values.  */
1058130803Smarcel      memcpy (buf, valbuf, len);
1059130803Smarcel      for (i = 0; i < len / 4; i++)
1060130803Smarcel	regcache_cooked_write (regcache, SPARC_F0_REGNUM + i, buf + i * 4);
1061130803Smarcel    }
1062130803Smarcel  else
1063130803Smarcel    {
1064130803Smarcel      /* Integral and pointer return values.  */
1065130803Smarcel      gdb_assert (sparc64_integral_or_pointer_p (type));
1066130803Smarcel
1067130803Smarcel      /* ??? Do we need to do any sign-extension here?  */
1068130803Smarcel      memset (buf, 0, 8);
1069130803Smarcel      memcpy (buf + 8 - len, valbuf, len);
1070130803Smarcel      regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
1071130803Smarcel    }
1072130803Smarcel}
1073130803Smarcel
1074130803Smarcelstatic enum return_value_convention
1075130803Smarcelsparc64_return_value (struct gdbarch *gdbarch, struct type *type,
1076130803Smarcel		      struct regcache *regcache, void *readbuf,
1077130803Smarcel		      const void *writebuf)
1078130803Smarcel{
1079130803Smarcel  if (TYPE_LENGTH (type) > 32)
1080130803Smarcel    return RETURN_VALUE_STRUCT_CONVENTION;
1081130803Smarcel
1082130803Smarcel  if (readbuf)
1083130803Smarcel    sparc64_extract_return_value (type, regcache, readbuf);
1084130803Smarcel  if (writebuf)
1085130803Smarcel    sparc64_store_return_value (type, regcache, writebuf);
1086130803Smarcel
1087130803Smarcel  return RETURN_VALUE_REGISTER_CONVENTION;
1088130803Smarcel}
1089130803Smarcel
1090130803Smarcel
1091130803Smarcelvoid
1092130803Smarcelsparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
1093130803Smarcel{
1094130803Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1095130803Smarcel
1096130803Smarcel  tdep->pc_regnum = SPARC64_PC_REGNUM;
1097130803Smarcel  tdep->npc_regnum = SPARC64_NPC_REGNUM;
1098130803Smarcel
1099130803Smarcel  /* This is what all the fuss is about.  */
1100130803Smarcel  set_gdbarch_long_bit (gdbarch, 64);
1101130803Smarcel  set_gdbarch_long_long_bit (gdbarch, 64);
1102130803Smarcel  set_gdbarch_ptr_bit (gdbarch, 64);
1103130803Smarcel
1104130803Smarcel  set_gdbarch_num_regs (gdbarch, SPARC64_NUM_REGS);
1105130803Smarcel  set_gdbarch_register_name (gdbarch, sparc64_register_name);
1106130803Smarcel  set_gdbarch_register_type (gdbarch, sparc64_register_type);
1107130803Smarcel  set_gdbarch_num_pseudo_regs (gdbarch, SPARC64_NUM_PSEUDO_REGS);
1108130803Smarcel  set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read);
1109130803Smarcel  set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write);
1110130803Smarcel
1111130803Smarcel  /* Register numbers of various important registers.  */
1112130803Smarcel  set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM); /* %pc */
1113130803Smarcel
1114130803Smarcel  /* Call dummy code.  */
1115130803Smarcel  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1116130803Smarcel  set_gdbarch_push_dummy_code (gdbarch, NULL);
1117130803Smarcel  set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call);
1118130803Smarcel
1119130803Smarcel  set_gdbarch_return_value (gdbarch, sparc64_return_value);
1120130803Smarcel  set_gdbarch_stabs_argument_has_addr
1121130803Smarcel    (gdbarch, default_stabs_argument_has_addr);
1122130803Smarcel
1123130803Smarcel  set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
1124130803Smarcel
1125130803Smarcel  frame_unwind_append_sniffer (gdbarch, sparc64_frame_sniffer);
1126130803Smarcel  frame_base_set_default (gdbarch, &sparc64_frame_base);
1127130803Smarcel}
1128130803Smarcel
1129130803Smarcel
1130130803Smarcel/* Helper functions for dealing with register sets.  */
1131130803Smarcel
1132130803Smarcel#define TSTATE_CWP	0x000000000000001fULL
1133130803Smarcel#define TSTATE_ICC	0x0000000f00000000ULL
1134130803Smarcel#define TSTATE_XCC	0x000000f000000000ULL
1135130803Smarcel
1136130803Smarcel#define PSR_S		0x00000080
1137130803Smarcel#define PSR_ICC		0x00f00000
1138130803Smarcel#define PSR_VERS	0x0f000000
1139130803Smarcel#define PSR_IMPL	0xf0000000
1140130803Smarcel#define PSR_V8PLUS	0xff000000
1141130803Smarcel#define PSR_XCC		0x000f0000
1142130803Smarcel
1143130803Smarcelvoid
1144130803Smarcelsparc64_supply_gregset (const struct sparc_gregset *gregset,
1145130803Smarcel			struct regcache *regcache,
1146130803Smarcel			int regnum, const void *gregs)
1147130803Smarcel{
1148130803Smarcel  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
1149130803Smarcel  const char *regs = gregs;
1150130803Smarcel  int i;
1151130803Smarcel
1152130803Smarcel  if (sparc32)
1153130803Smarcel    {
1154130803Smarcel      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
1155130803Smarcel	{
1156130803Smarcel	  int offset = gregset->r_tstate_offset;
1157130803Smarcel	  ULONGEST tstate, psr;
1158130803Smarcel	  char buf[4];
1159130803Smarcel
1160130803Smarcel	  tstate = extract_unsigned_integer (regs + offset, 8);
1161130803Smarcel	  psr = ((tstate & TSTATE_CWP) | PSR_S | ((tstate & TSTATE_ICC) >> 12)
1162130803Smarcel		 | ((tstate & TSTATE_XCC) >> 20) | PSR_V8PLUS);
1163130803Smarcel	  store_unsigned_integer (buf, 4, psr);
1164130803Smarcel	  regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, buf);
1165130803Smarcel	}
1166130803Smarcel
1167130803Smarcel      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
1168130803Smarcel	regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
1169130803Smarcel			     regs + gregset->r_pc_offset + 4);
1170130803Smarcel
1171130803Smarcel      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
1172130803Smarcel	regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
1173130803Smarcel			     regs + gregset->r_npc_offset + 4);
1174130803Smarcel
1175130803Smarcel      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
1176130803Smarcel	{
1177130803Smarcel	  int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
1178130803Smarcel	  regcache_raw_supply (regcache, SPARC32_Y_REGNUM, regs + offset);
1179130803Smarcel	}
1180130803Smarcel    }
1181130803Smarcel  else
1182130803Smarcel    {
1183130803Smarcel      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
1184130803Smarcel	regcache_raw_supply (regcache, SPARC64_STATE_REGNUM,
1185130803Smarcel			     regs + gregset->r_tstate_offset);
1186130803Smarcel
1187130803Smarcel      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
1188130803Smarcel	regcache_raw_supply (regcache, SPARC64_PC_REGNUM,
1189130803Smarcel			     regs + gregset->r_pc_offset);
1190130803Smarcel
1191130803Smarcel      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
1192130803Smarcel	regcache_raw_supply (regcache, SPARC64_NPC_REGNUM,
1193130803Smarcel			     regs + gregset->r_npc_offset);
1194130803Smarcel
1195130803Smarcel      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
1196130803Smarcel	{
1197130803Smarcel	  char buf[8];
1198130803Smarcel
1199130803Smarcel	  memset (buf, 0, 8);
1200130803Smarcel	  memcpy (buf + 8 - gregset->r_y_size,
1201130803Smarcel		  regs + gregset->r_y_offset, gregset->r_y_size);
1202130803Smarcel	  regcache_raw_supply (regcache, SPARC64_Y_REGNUM, buf);
1203130803Smarcel	}
1204130803Smarcel
1205130803Smarcel      if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
1206130803Smarcel	  && gregset->r_fprs_offset != -1)
1207130803Smarcel	regcache_raw_supply (regcache, SPARC64_FPRS_REGNUM,
1208130803Smarcel			     regs + gregset->r_fprs_offset);
1209130803Smarcel    }
1210130803Smarcel
1211130803Smarcel  if (regnum == SPARC_G0_REGNUM || regnum == -1)
1212130803Smarcel    regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL);
1213130803Smarcel
1214130803Smarcel  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
1215130803Smarcel    {
1216130803Smarcel      int offset = gregset->r_g1_offset;
1217130803Smarcel
1218130803Smarcel      if (sparc32)
1219130803Smarcel	offset += 4;
1220130803Smarcel
1221130803Smarcel      for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
1222130803Smarcel	{
1223130803Smarcel	  if (regnum == i || regnum == -1)
1224130803Smarcel	    regcache_raw_supply (regcache, i, regs + offset);
1225130803Smarcel	  offset += 8;
1226130803Smarcel	}
1227130803Smarcel    }
1228130803Smarcel
1229130803Smarcel  if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
1230130803Smarcel    {
1231130803Smarcel      /* Not all of the register set variants include Locals and
1232130803Smarcel         Inputs.  For those that don't, we read them off the stack.  */
1233130803Smarcel      if (gregset->r_l0_offset == -1)
1234130803Smarcel	{
1235130803Smarcel	  ULONGEST sp;
1236130803Smarcel
1237130803Smarcel	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
1238130803Smarcel	  sparc_supply_rwindow (regcache, sp, regnum);
1239130803Smarcel	}
1240130803Smarcel      else
1241130803Smarcel	{
1242130803Smarcel	  int offset = gregset->r_l0_offset;
1243130803Smarcel
1244130803Smarcel	  if (sparc32)
1245130803Smarcel	    offset += 4;
1246130803Smarcel
1247130803Smarcel	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1248130803Smarcel	    {
1249130803Smarcel	      if (regnum == i || regnum == -1)
1250130803Smarcel		regcache_raw_supply (regcache, i, regs + offset);
1251130803Smarcel	      offset += 8;
1252130803Smarcel	    }
1253130803Smarcel	}
1254130803Smarcel    }
1255130803Smarcel}
1256130803Smarcel
1257130803Smarcelvoid
1258130803Smarcelsparc64_collect_gregset (const struct sparc_gregset *gregset,
1259130803Smarcel			 const struct regcache *regcache,
1260130803Smarcel			 int regnum, void *gregs)
1261130803Smarcel{
1262130803Smarcel  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
1263130803Smarcel  char *regs = gregs;
1264130803Smarcel  int i;
1265130803Smarcel
1266130803Smarcel  if (sparc32)
1267130803Smarcel    {
1268130803Smarcel      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
1269130803Smarcel	{
1270130803Smarcel	  int offset = gregset->r_tstate_offset;
1271130803Smarcel	  ULONGEST tstate, psr;
1272130803Smarcel	  char buf[8];
1273130803Smarcel
1274130803Smarcel	  tstate = extract_unsigned_integer (regs + offset, 8);
1275130803Smarcel	  regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, buf);
1276130803Smarcel	  psr = extract_unsigned_integer (buf, 4);
1277130803Smarcel	  tstate |= (psr & PSR_ICC) << 12;
1278130803Smarcel	  if ((psr & (PSR_VERS | PSR_IMPL)) == PSR_V8PLUS)
1279130803Smarcel	    tstate |= (psr & PSR_XCC) << 20;
1280130803Smarcel	  store_unsigned_integer (buf, 8, tstate);
1281130803Smarcel	  memcpy (regs + offset, buf, 8);
1282130803Smarcel	}
1283130803Smarcel
1284130803Smarcel      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
1285130803Smarcel	regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
1286130803Smarcel			      regs + gregset->r_pc_offset + 4);
1287130803Smarcel
1288130803Smarcel      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
1289130803Smarcel	regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
1290130803Smarcel			      regs + gregset->r_npc_offset + 4);
1291130803Smarcel
1292130803Smarcel      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
1293130803Smarcel	{
1294130803Smarcel	  int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
1295130803Smarcel	  regcache_raw_collect (regcache, SPARC32_Y_REGNUM, regs + offset);
1296130803Smarcel	}
1297130803Smarcel    }
1298130803Smarcel  else
1299130803Smarcel    {
1300130803Smarcel      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
1301130803Smarcel	regcache_raw_collect (regcache, SPARC64_STATE_REGNUM,
1302130803Smarcel			      regs + gregset->r_tstate_offset);
1303130803Smarcel
1304130803Smarcel      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
1305130803Smarcel	regcache_raw_collect (regcache, SPARC64_PC_REGNUM,
1306130803Smarcel			      regs + gregset->r_pc_offset);
1307130803Smarcel
1308130803Smarcel      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
1309130803Smarcel	regcache_raw_collect (regcache, SPARC64_NPC_REGNUM,
1310130803Smarcel			      regs + gregset->r_npc_offset);
1311130803Smarcel
1312130803Smarcel      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
1313130803Smarcel	{
1314130803Smarcel	  char buf[8];
1315130803Smarcel
1316130803Smarcel	  regcache_raw_collect (regcache, SPARC64_Y_REGNUM, buf);
1317130803Smarcel	  memcpy (regs + gregset->r_y_offset,
1318130803Smarcel		  buf + 8 - gregset->r_y_size, gregset->r_y_size);
1319130803Smarcel	}
1320130803Smarcel
1321130803Smarcel      if ((regnum == SPARC64_FPRS_REGNUM || regnum == -1)
1322130803Smarcel	  && gregset->r_fprs_offset != -1)
1323130803Smarcel	regcache_raw_collect (regcache, SPARC64_FPRS_REGNUM,
1324130803Smarcel			      regs + gregset->r_fprs_offset);
1325130803Smarcel
1326130803Smarcel    }
1327130803Smarcel
1328130803Smarcel  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
1329130803Smarcel    {
1330130803Smarcel      int offset = gregset->r_g1_offset;
1331130803Smarcel
1332130803Smarcel      if (sparc32)
1333130803Smarcel	offset += 4;
1334130803Smarcel
1335130803Smarcel      /* %g0 is always zero.  */
1336130803Smarcel      for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
1337130803Smarcel	{
1338130803Smarcel	  if (regnum == i || regnum == -1)
1339130803Smarcel	    regcache_raw_collect (regcache, i, regs + offset);
1340130803Smarcel	  offset += 8;
1341130803Smarcel	}
1342130803Smarcel    }
1343130803Smarcel
1344130803Smarcel  if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
1345130803Smarcel    {
1346130803Smarcel      /* Not all of the register set variants include Locals and
1347130803Smarcel         Inputs.  For those that don't, we read them off the stack.  */
1348130803Smarcel      if (gregset->r_l0_offset != -1)
1349130803Smarcel	{
1350130803Smarcel	  int offset = gregset->r_l0_offset;
1351130803Smarcel
1352130803Smarcel	  if (sparc32)
1353130803Smarcel	    offset += 4;
1354130803Smarcel
1355130803Smarcel	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1356130803Smarcel	    {
1357130803Smarcel	      if (regnum == i || regnum == -1)
1358130803Smarcel		regcache_raw_collect (regcache, i, regs + offset);
1359130803Smarcel	      offset += 8;
1360130803Smarcel	    }
1361130803Smarcel	}
1362130803Smarcel    }
1363130803Smarcel}
1364130803Smarcel
1365130803Smarcelvoid
1366130803Smarcelsparc64_supply_fpregset (struct regcache *regcache,
1367130803Smarcel			 int regnum, const void *fpregs)
1368130803Smarcel{
1369130803Smarcel  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
1370130803Smarcel  const char *regs = fpregs;
1371130803Smarcel  int i;
1372130803Smarcel
1373130803Smarcel  for (i = 0; i < 32; i++)
1374130803Smarcel    {
1375130803Smarcel      if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
1376130803Smarcel	regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
1377130803Smarcel    }
1378130803Smarcel
1379130803Smarcel  if (sparc32)
1380130803Smarcel    {
1381130803Smarcel      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
1382130803Smarcel	regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
1383130803Smarcel			     regs + (32 * 4) + (16 * 8) + 4);
1384130803Smarcel    }
1385130803Smarcel  else
1386130803Smarcel    {
1387130803Smarcel      for (i = 0; i < 16; i++)
1388130803Smarcel	{
1389130803Smarcel	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
1390130803Smarcel	    regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i,
1391130803Smarcel				 regs + (32 * 4) + (i * 8));
1392130803Smarcel	}
1393130803Smarcel
1394130803Smarcel      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
1395130803Smarcel	regcache_raw_supply (regcache, SPARC64_FSR_REGNUM,
1396130803Smarcel			     regs + (32 * 4) + (16 * 8));
1397130803Smarcel    }
1398130803Smarcel}
1399130803Smarcel
1400130803Smarcelvoid
1401130803Smarcelsparc64_collect_fpregset (const struct regcache *regcache,
1402130803Smarcel			  int regnum, void *fpregs)
1403130803Smarcel{
1404130803Smarcel  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
1405130803Smarcel  char *regs = fpregs;
1406130803Smarcel  int i;
1407130803Smarcel
1408130803Smarcel  for (i = 0; i < 32; i++)
1409130803Smarcel    {
1410130803Smarcel      if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
1411130803Smarcel	regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
1412130803Smarcel    }
1413130803Smarcel
1414130803Smarcel  if (sparc32)
1415130803Smarcel    {
1416130803Smarcel      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
1417130803Smarcel	regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
1418130803Smarcel			      regs + (32 * 4) + (16 * 8) + 4);
1419130803Smarcel    }
1420130803Smarcel  else
1421130803Smarcel    {
1422130803Smarcel      for (i = 0; i < 16; i++)
1423130803Smarcel	{
1424130803Smarcel	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
1425130803Smarcel	    regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i,
1426130803Smarcel				  regs + (32 * 4) + (i * 8));
1427130803Smarcel	}
1428130803Smarcel
1429130803Smarcel      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
1430130803Smarcel	regcache_raw_collect (regcache, SPARC64_FSR_REGNUM,
1431130803Smarcel			      regs + (32 * 4) + (16 * 8));
1432130803Smarcel    }
1433130803Smarcel}
1434