xref: /openbsd-src/gnu/usr.bin/binutils/gdb/d10v-tdep.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Target-dependent code for Renesas D10V, for GDB.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 /*  Contributed by Martin Hunt, hunt@cygnus.com */
24b725ae77Skettenis 
25b725ae77Skettenis #include "defs.h"
26b725ae77Skettenis #include "frame.h"
27b725ae77Skettenis #include "frame-unwind.h"
28b725ae77Skettenis #include "frame-base.h"
29b725ae77Skettenis #include "symtab.h"
30b725ae77Skettenis #include "gdbtypes.h"
31b725ae77Skettenis #include "gdbcmd.h"
32b725ae77Skettenis #include "gdbcore.h"
33b725ae77Skettenis #include "gdb_string.h"
34b725ae77Skettenis #include "value.h"
35b725ae77Skettenis #include "inferior.h"
36b725ae77Skettenis #include "dis-asm.h"
37b725ae77Skettenis #include "symfile.h"
38b725ae77Skettenis #include "objfiles.h"
39b725ae77Skettenis #include "language.h"
40b725ae77Skettenis #include "arch-utils.h"
41b725ae77Skettenis #include "regcache.h"
42b725ae77Skettenis #include "remote.h"
43b725ae77Skettenis #include "floatformat.h"
44b725ae77Skettenis #include "gdb/sim-d10v.h"
45b725ae77Skettenis #include "sim-regno.h"
46b725ae77Skettenis #include "disasm.h"
47b725ae77Skettenis #include "trad-frame.h"
48b725ae77Skettenis 
49b725ae77Skettenis #include "gdb_assert.h"
50b725ae77Skettenis 
51b725ae77Skettenis struct gdbarch_tdep
52b725ae77Skettenis   {
53b725ae77Skettenis     int a0_regnum;
54b725ae77Skettenis     int nr_dmap_regs;
55b725ae77Skettenis     unsigned long (*dmap_register) (void *regcache, int nr);
56b725ae77Skettenis     unsigned long (*imap_register) (void *regcache, int nr);
57b725ae77Skettenis   };
58b725ae77Skettenis 
59b725ae77Skettenis /* These are the addresses the D10V-EVA board maps data and
60b725ae77Skettenis    instruction memory to.  */
61b725ae77Skettenis 
62b725ae77Skettenis enum memspace {
63b725ae77Skettenis   DMEM_START  = 0x2000000,
64b725ae77Skettenis   IMEM_START  = 0x1000000,
65b725ae77Skettenis   STACK_START = 0x200bffe
66b725ae77Skettenis };
67b725ae77Skettenis 
68b725ae77Skettenis /* d10v register names.  */
69b725ae77Skettenis 
70b725ae77Skettenis enum
71b725ae77Skettenis   {
72b725ae77Skettenis     R0_REGNUM = 0,
73b725ae77Skettenis     R3_REGNUM = 3,
74b725ae77Skettenis     D10V_FP_REGNUM = 11,
75b725ae77Skettenis     LR_REGNUM = 13,
76b725ae77Skettenis     D10V_SP_REGNUM = 15,
77b725ae77Skettenis     PSW_REGNUM = 16,
78b725ae77Skettenis     D10V_PC_REGNUM = 18,
79b725ae77Skettenis     NR_IMAP_REGS = 2,
80b725ae77Skettenis     NR_A_REGS = 2,
81b725ae77Skettenis     TS2_NUM_REGS = 37,
82b725ae77Skettenis     TS3_NUM_REGS = 42,
83b725ae77Skettenis     /* d10v calling convention.  */
84b725ae77Skettenis     ARG1_REGNUM = R0_REGNUM,
85b725ae77Skettenis     ARGN_REGNUM = R3_REGNUM
86b725ae77Skettenis   };
87b725ae77Skettenis 
88b725ae77Skettenis static int
nr_dmap_regs(struct gdbarch * gdbarch)89b725ae77Skettenis nr_dmap_regs (struct gdbarch *gdbarch)
90b725ae77Skettenis {
91b725ae77Skettenis   return gdbarch_tdep (gdbarch)->nr_dmap_regs;
92b725ae77Skettenis }
93b725ae77Skettenis 
94b725ae77Skettenis static int
a0_regnum(struct gdbarch * gdbarch)95b725ae77Skettenis a0_regnum (struct gdbarch *gdbarch)
96b725ae77Skettenis {
97b725ae77Skettenis   return gdbarch_tdep (gdbarch)->a0_regnum;
98b725ae77Skettenis }
99b725ae77Skettenis 
100b725ae77Skettenis /* Local functions */
101b725ae77Skettenis 
102b725ae77Skettenis extern void _initialize_d10v_tdep (void);
103b725ae77Skettenis 
104b725ae77Skettenis static void d10v_eva_prepare_to_trace (void);
105b725ae77Skettenis 
106b725ae77Skettenis static void d10v_eva_get_trace_data (void);
107b725ae77Skettenis 
108b725ae77Skettenis static CORE_ADDR
d10v_frame_align(struct gdbarch * gdbarch,CORE_ADDR sp)109b725ae77Skettenis d10v_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
110b725ae77Skettenis {
111b725ae77Skettenis   /* Align to the size of an instruction (so that they can safely be
112b725ae77Skettenis      pushed onto the stack.  */
113b725ae77Skettenis   return sp & ~3;
114b725ae77Skettenis }
115b725ae77Skettenis 
116b725ae77Skettenis static const unsigned char *
d10v_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)117b725ae77Skettenis d10v_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
118b725ae77Skettenis {
119b725ae77Skettenis   static unsigned char breakpoint[] =
120b725ae77Skettenis   {0x2f, 0x90, 0x5e, 0x00};
121b725ae77Skettenis   *lenptr = sizeof (breakpoint);
122b725ae77Skettenis   return breakpoint;
123b725ae77Skettenis }
124b725ae77Skettenis 
125b725ae77Skettenis /* Map the REG_NR onto an ascii name.  Return NULL or an empty string
126b725ae77Skettenis    when the reg_nr isn't valid.  */
127b725ae77Skettenis 
128b725ae77Skettenis enum ts2_regnums
129b725ae77Skettenis   {
130b725ae77Skettenis     TS2_IMAP0_REGNUM = 32,
131b725ae77Skettenis     TS2_DMAP_REGNUM = 34,
132b725ae77Skettenis     TS2_NR_DMAP_REGS = 1,
133b725ae77Skettenis     TS2_A0_REGNUM = 35
134b725ae77Skettenis   };
135b725ae77Skettenis 
136b725ae77Skettenis static const char *
d10v_ts2_register_name(int reg_nr)137b725ae77Skettenis d10v_ts2_register_name (int reg_nr)
138b725ae77Skettenis {
139b725ae77Skettenis   static char *register_names[] =
140b725ae77Skettenis   {
141b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
142b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
143b725ae77Skettenis     "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c",
144b725ae77Skettenis     "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15",
145b725ae77Skettenis     "imap0", "imap1", "dmap", "a0", "a1"
146b725ae77Skettenis   };
147b725ae77Skettenis   if (reg_nr < 0)
148b725ae77Skettenis     return NULL;
149b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
150b725ae77Skettenis     return NULL;
151b725ae77Skettenis   return register_names[reg_nr];
152b725ae77Skettenis }
153b725ae77Skettenis 
154b725ae77Skettenis enum ts3_regnums
155b725ae77Skettenis   {
156b725ae77Skettenis     TS3_IMAP0_REGNUM = 36,
157b725ae77Skettenis     TS3_DMAP0_REGNUM = 38,
158b725ae77Skettenis     TS3_NR_DMAP_REGS = 4,
159b725ae77Skettenis     TS3_A0_REGNUM = 32
160b725ae77Skettenis   };
161b725ae77Skettenis 
162b725ae77Skettenis static const char *
d10v_ts3_register_name(int reg_nr)163b725ae77Skettenis d10v_ts3_register_name (int reg_nr)
164b725ae77Skettenis {
165b725ae77Skettenis   static char *register_names[] =
166b725ae77Skettenis   {
167b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
168b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
169b725ae77Skettenis     "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c",
170b725ae77Skettenis     "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15",
171b725ae77Skettenis     "a0", "a1",
172b725ae77Skettenis     "spi", "spu",
173b725ae77Skettenis     "imap0", "imap1",
174b725ae77Skettenis     "dmap0", "dmap1", "dmap2", "dmap3"
175b725ae77Skettenis   };
176b725ae77Skettenis   if (reg_nr < 0)
177b725ae77Skettenis     return NULL;
178b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
179b725ae77Skettenis     return NULL;
180b725ae77Skettenis   return register_names[reg_nr];
181b725ae77Skettenis }
182b725ae77Skettenis 
183b725ae77Skettenis /* Access the DMAP/IMAP registers in a target independent way.
184b725ae77Skettenis 
185b725ae77Skettenis    Divide the D10V's 64k data space into four 16k segments:
186b725ae77Skettenis    0x0000 -- 0x3fff, 0x4000 -- 0x7fff, 0x8000 -- 0xbfff, and
187b725ae77Skettenis    0xc000 -- 0xffff.
188b725ae77Skettenis 
189b725ae77Skettenis    On the TS2, the first two segments (0x0000 -- 0x3fff, 0x4000 --
190b725ae77Skettenis    0x7fff) always map to the on-chip data RAM, and the fourth always
191b725ae77Skettenis    maps to I/O space.  The third (0x8000 - 0xbfff) can be mapped into
192b725ae77Skettenis    unified memory or instruction memory, under the control of the
193b725ae77Skettenis    single DMAP register.
194b725ae77Skettenis 
195b725ae77Skettenis    On the TS3, there are four DMAP registers, each of which controls
196b725ae77Skettenis    one of the segments.  */
197b725ae77Skettenis 
198b725ae77Skettenis static unsigned long
d10v_ts2_dmap_register(void * regcache,int reg_nr)199b725ae77Skettenis d10v_ts2_dmap_register (void *regcache, int reg_nr)
200b725ae77Skettenis {
201b725ae77Skettenis   switch (reg_nr)
202b725ae77Skettenis     {
203b725ae77Skettenis     case 0:
204b725ae77Skettenis     case 1:
205b725ae77Skettenis       return 0x2000;
206b725ae77Skettenis     case 2:
207b725ae77Skettenis       {
208b725ae77Skettenis 	ULONGEST reg;
209b725ae77Skettenis 	regcache_cooked_read_unsigned (regcache, TS2_DMAP_REGNUM, &reg);
210b725ae77Skettenis 	return reg;
211b725ae77Skettenis       }
212b725ae77Skettenis     default:
213b725ae77Skettenis       return 0;
214b725ae77Skettenis     }
215b725ae77Skettenis }
216b725ae77Skettenis 
217b725ae77Skettenis static unsigned long
d10v_ts3_dmap_register(void * regcache,int reg_nr)218b725ae77Skettenis d10v_ts3_dmap_register (void *regcache, int reg_nr)
219b725ae77Skettenis {
220b725ae77Skettenis   ULONGEST reg;
221b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, TS3_DMAP0_REGNUM + reg_nr, &reg);
222b725ae77Skettenis   return reg;
223b725ae77Skettenis }
224b725ae77Skettenis 
225b725ae77Skettenis static unsigned long
d10v_ts2_imap_register(void * regcache,int reg_nr)226b725ae77Skettenis d10v_ts2_imap_register (void *regcache, int reg_nr)
227b725ae77Skettenis {
228b725ae77Skettenis   ULONGEST reg;
229b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, TS2_IMAP0_REGNUM + reg_nr, &reg);
230b725ae77Skettenis   return reg;
231b725ae77Skettenis }
232b725ae77Skettenis 
233b725ae77Skettenis static unsigned long
d10v_ts3_imap_register(void * regcache,int reg_nr)234b725ae77Skettenis d10v_ts3_imap_register (void *regcache, int reg_nr)
235b725ae77Skettenis {
236b725ae77Skettenis   ULONGEST reg;
237b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, TS3_IMAP0_REGNUM + reg_nr, &reg);
238b725ae77Skettenis   return reg;
239b725ae77Skettenis }
240b725ae77Skettenis 
241b725ae77Skettenis /* MAP GDB's internal register numbering (determined by the layout
242b725ae77Skettenis    from the DEPRECATED_REGISTER_BYTE array) onto the simulator's
243b725ae77Skettenis    register numbering.  */
244b725ae77Skettenis 
245b725ae77Skettenis static int
d10v_ts2_register_sim_regno(int nr)246b725ae77Skettenis d10v_ts2_register_sim_regno (int nr)
247b725ae77Skettenis {
248b725ae77Skettenis   /* Only makes sense to supply raw registers.  */
249b725ae77Skettenis   gdb_assert (nr >= 0 && nr < NUM_REGS);
250b725ae77Skettenis   if (nr >= TS2_IMAP0_REGNUM
251b725ae77Skettenis       && nr < TS2_IMAP0_REGNUM + NR_IMAP_REGS)
252b725ae77Skettenis     return nr - TS2_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM;
253b725ae77Skettenis   if (nr == TS2_DMAP_REGNUM)
254b725ae77Skettenis     return nr - TS2_DMAP_REGNUM + SIM_D10V_TS2_DMAP_REGNUM;
255b725ae77Skettenis   if (nr >= TS2_A0_REGNUM
256b725ae77Skettenis       && nr < TS2_A0_REGNUM + NR_A_REGS)
257b725ae77Skettenis     return nr - TS2_A0_REGNUM + SIM_D10V_A0_REGNUM;
258b725ae77Skettenis   return nr;
259b725ae77Skettenis }
260b725ae77Skettenis 
261b725ae77Skettenis static int
d10v_ts3_register_sim_regno(int nr)262b725ae77Skettenis d10v_ts3_register_sim_regno (int nr)
263b725ae77Skettenis {
264b725ae77Skettenis   /* Only makes sense to supply raw registers.  */
265b725ae77Skettenis   gdb_assert (nr >= 0 && nr < NUM_REGS);
266b725ae77Skettenis   if (nr >= TS3_IMAP0_REGNUM
267b725ae77Skettenis       && nr < TS3_IMAP0_REGNUM + NR_IMAP_REGS)
268b725ae77Skettenis     return nr - TS3_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM;
269b725ae77Skettenis   if (nr >= TS3_DMAP0_REGNUM
270b725ae77Skettenis       && nr < TS3_DMAP0_REGNUM + TS3_NR_DMAP_REGS)
271b725ae77Skettenis     return nr - TS3_DMAP0_REGNUM + SIM_D10V_DMAP0_REGNUM;
272b725ae77Skettenis   if (nr >= TS3_A0_REGNUM
273b725ae77Skettenis       && nr < TS3_A0_REGNUM + NR_A_REGS)
274b725ae77Skettenis     return nr - TS3_A0_REGNUM + SIM_D10V_A0_REGNUM;
275b725ae77Skettenis   return nr;
276b725ae77Skettenis }
277b725ae77Skettenis 
278b725ae77Skettenis /* Return the GDB type object for the "standard" data type
279b725ae77Skettenis    of data in register N.  */
280b725ae77Skettenis 
281b725ae77Skettenis static struct type *
d10v_register_type(struct gdbarch * gdbarch,int reg_nr)282b725ae77Skettenis d10v_register_type (struct gdbarch *gdbarch, int reg_nr)
283b725ae77Skettenis {
284b725ae77Skettenis   if (reg_nr == D10V_PC_REGNUM)
285*11efff7fSkettenis     return builtin_type (gdbarch)->builtin_func_ptr;
286b725ae77Skettenis   if (reg_nr == D10V_SP_REGNUM || reg_nr == D10V_FP_REGNUM)
287*11efff7fSkettenis     return builtin_type (gdbarch)->builtin_data_ptr;
288b725ae77Skettenis   else if (reg_nr >= a0_regnum (gdbarch)
289b725ae77Skettenis 	   && reg_nr < (a0_regnum (gdbarch) + NR_A_REGS))
290b725ae77Skettenis     return builtin_type_int64;
291b725ae77Skettenis   else
292b725ae77Skettenis     return builtin_type_int16;
293b725ae77Skettenis }
294b725ae77Skettenis 
295b725ae77Skettenis static int
d10v_iaddr_p(CORE_ADDR x)296b725ae77Skettenis d10v_iaddr_p (CORE_ADDR x)
297b725ae77Skettenis {
298b725ae77Skettenis   return (((x) & 0x3000000) == IMEM_START);
299b725ae77Skettenis }
300b725ae77Skettenis 
301b725ae77Skettenis static CORE_ADDR
d10v_make_daddr(CORE_ADDR x)302b725ae77Skettenis d10v_make_daddr (CORE_ADDR x)
303b725ae77Skettenis {
304b725ae77Skettenis   return ((x) | DMEM_START);
305b725ae77Skettenis }
306b725ae77Skettenis 
307b725ae77Skettenis static CORE_ADDR
d10v_make_iaddr(CORE_ADDR x)308b725ae77Skettenis d10v_make_iaddr (CORE_ADDR x)
309b725ae77Skettenis {
310b725ae77Skettenis   if (d10v_iaddr_p (x))
311b725ae77Skettenis     return x;	/* Idempotency -- x is already in the IMEM space.  */
312b725ae77Skettenis   else
313b725ae77Skettenis     return (((x) << 2) | IMEM_START);
314b725ae77Skettenis }
315b725ae77Skettenis 
316b725ae77Skettenis static CORE_ADDR
d10v_convert_iaddr_to_raw(CORE_ADDR x)317b725ae77Skettenis d10v_convert_iaddr_to_raw (CORE_ADDR x)
318b725ae77Skettenis {
319b725ae77Skettenis   return (((x) >> 2) & 0xffff);
320b725ae77Skettenis }
321b725ae77Skettenis 
322b725ae77Skettenis static CORE_ADDR
d10v_convert_daddr_to_raw(CORE_ADDR x)323b725ae77Skettenis d10v_convert_daddr_to_raw (CORE_ADDR x)
324b725ae77Skettenis {
325b725ae77Skettenis   return ((x) & 0xffff);
326b725ae77Skettenis }
327b725ae77Skettenis 
328b725ae77Skettenis static void
d10v_address_to_pointer(struct type * type,void * buf,CORE_ADDR addr)329b725ae77Skettenis d10v_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
330b725ae77Skettenis {
331b725ae77Skettenis   /* Is it a code address?  */
332b725ae77Skettenis   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
333b725ae77Skettenis       || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
334b725ae77Skettenis     {
335b725ae77Skettenis       store_unsigned_integer (buf, TYPE_LENGTH (type),
336b725ae77Skettenis                               d10v_convert_iaddr_to_raw (addr));
337b725ae77Skettenis     }
338b725ae77Skettenis   else
339b725ae77Skettenis     {
340b725ae77Skettenis       /* Strip off any upper segment bits.  */
341b725ae77Skettenis       store_unsigned_integer (buf, TYPE_LENGTH (type),
342b725ae77Skettenis                               d10v_convert_daddr_to_raw (addr));
343b725ae77Skettenis     }
344b725ae77Skettenis }
345b725ae77Skettenis 
346b725ae77Skettenis static CORE_ADDR
d10v_pointer_to_address(struct type * type,const void * buf)347b725ae77Skettenis d10v_pointer_to_address (struct type *type, const void *buf)
348b725ae77Skettenis {
349b725ae77Skettenis   CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
350b725ae77Skettenis   /* Is it a code address?  */
351b725ae77Skettenis   if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
352b725ae77Skettenis       || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
353b725ae77Skettenis       || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
354b725ae77Skettenis     return d10v_make_iaddr (addr);
355b725ae77Skettenis   else
356b725ae77Skettenis     return d10v_make_daddr (addr);
357b725ae77Skettenis }
358b725ae77Skettenis 
359b725ae77Skettenis /* Don't do anything if we have an integer, this way users can type 'x
360b725ae77Skettenis    <addr>' w/o having gdb outsmart them.  The internal gdb conversions
361b725ae77Skettenis    to the correct space are taken care of in the pointer_to_address
362b725ae77Skettenis    function.  If we don't do this, 'x $fp' wouldn't work.  */
363b725ae77Skettenis static CORE_ADDR
d10v_integer_to_address(struct type * type,void * buf)364b725ae77Skettenis d10v_integer_to_address (struct type *type, void *buf)
365b725ae77Skettenis {
366b725ae77Skettenis   LONGEST val;
367b725ae77Skettenis   val = unpack_long (type, buf);
368b725ae77Skettenis   return val;
369b725ae77Skettenis }
370b725ae77Skettenis 
371b725ae77Skettenis /* Handle the d10v's return_value convention.  */
372b725ae77Skettenis 
373b725ae77Skettenis static enum return_value_convention
d10v_return_value(struct gdbarch * gdbarch,struct type * valtype,struct regcache * regcache,void * readbuf,const void * writebuf)374b725ae77Skettenis d10v_return_value (struct gdbarch *gdbarch, struct type *valtype,
375b725ae77Skettenis 		   struct regcache *regcache, void *readbuf,
376b725ae77Skettenis 		   const void *writebuf)
377b725ae77Skettenis {
378b725ae77Skettenis   if (TYPE_LENGTH (valtype) > 8)
379b725ae77Skettenis     /* Anything larger than 8 bytes (4 registers) goes on the stack.  */
380b725ae77Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
381b725ae77Skettenis   if (TYPE_LENGTH (valtype) == 5
382b725ae77Skettenis       || TYPE_LENGTH (valtype) == 6)
383b725ae77Skettenis     /* Anything 5 or 6 bytes in size goes in memory.  Contents don't
384b725ae77Skettenis        appear to matter.  Note that 7 and 8 byte objects do end up in
385b725ae77Skettenis        registers!  */
386b725ae77Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
387b725ae77Skettenis   if (TYPE_LENGTH (valtype) == 1)
388b725ae77Skettenis     {
389b725ae77Skettenis       /* All single byte values go in a register stored right-aligned.
390b725ae77Skettenis          Note: 2 byte integer values are handled further down.  */
391b725ae77Skettenis       if (readbuf)
392b725ae77Skettenis 	{
393b725ae77Skettenis 	  /* Since TYPE is smaller than the register, there isn't a
394b725ae77Skettenis              sign extension problem.  Let the extraction truncate the
395b725ae77Skettenis              register value.  */
396b725ae77Skettenis 	  ULONGEST regval;
397b725ae77Skettenis 	  regcache_cooked_read_unsigned (regcache, R0_REGNUM,
398b725ae77Skettenis 					 &regval);
399b725ae77Skettenis 	  store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval);
400b725ae77Skettenis 
401b725ae77Skettenis 	}
402b725ae77Skettenis       if (writebuf)
403b725ae77Skettenis 	{
404b725ae77Skettenis 	  ULONGEST regval;
405b725ae77Skettenis 	  if (TYPE_CODE (valtype) == TYPE_CODE_INT)
406b725ae77Skettenis 	    /* Some sort of integer value stored in R0.  Use
407b725ae77Skettenis 	       unpack_long since that should handle any required sign
408b725ae77Skettenis 	       extension.  */
409b725ae77Skettenis 	    regval = unpack_long (valtype, writebuf);
410b725ae77Skettenis 	  else
411b725ae77Skettenis 	    /* Some other type.  Don't sign-extend the value when
412b725ae77Skettenis                storing it in the register.  */
413b725ae77Skettenis 	    regval = extract_unsigned_integer (writebuf, 1);
414b725ae77Skettenis 	  regcache_cooked_write_unsigned (regcache, R0_REGNUM, regval);
415b725ae77Skettenis 	}
416b725ae77Skettenis       return RETURN_VALUE_REGISTER_CONVENTION;
417b725ae77Skettenis     }
418b725ae77Skettenis   if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
419b725ae77Skettenis        || TYPE_CODE (valtype) == TYPE_CODE_UNION)
420b725ae77Skettenis       && TYPE_NFIELDS (valtype) > 1
421b725ae77Skettenis       && TYPE_FIELD_BITPOS (valtype, 1) == 8)
422b725ae77Skettenis     /* If a composite is 8 bit aligned (determined by looking at the
423b725ae77Skettenis        start address of the second field), put it in memory.  */
424b725ae77Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
425b725ae77Skettenis   /* Assume it is in registers.  */
426b725ae77Skettenis   if (writebuf || readbuf)
427b725ae77Skettenis     {
428b725ae77Skettenis       int reg;
429b725ae77Skettenis       /* Per above, the value is never more than 8 bytes long.  */
430b725ae77Skettenis       gdb_assert (TYPE_LENGTH (valtype) <= 8);
431b725ae77Skettenis       /* Xfer 2 bytes at a time.  */
432b725ae77Skettenis       for (reg = 0; (reg * 2) + 1 < TYPE_LENGTH (valtype); reg++)
433b725ae77Skettenis 	{
434b725ae77Skettenis 	  if (readbuf)
435b725ae77Skettenis 	    regcache_cooked_read (regcache, R0_REGNUM + reg,
436b725ae77Skettenis 				  (bfd_byte *) readbuf + reg * 2);
437b725ae77Skettenis 	  if (writebuf)
438b725ae77Skettenis 	    regcache_cooked_write (regcache, R0_REGNUM + reg,
439b725ae77Skettenis 				   (bfd_byte *) writebuf + reg * 2);
440b725ae77Skettenis 	}
441b725ae77Skettenis       /* Any trailing byte ends up _left_ aligned.  */
442b725ae77Skettenis       if ((reg * 2) < TYPE_LENGTH (valtype))
443b725ae77Skettenis 	{
444b725ae77Skettenis 	  if (readbuf)
445b725ae77Skettenis 	    regcache_cooked_read_part (regcache, R0_REGNUM + reg,
446b725ae77Skettenis 				       0, 1, (bfd_byte *) readbuf + reg * 2);
447b725ae77Skettenis 	  if (writebuf)
448b725ae77Skettenis 	    regcache_cooked_write_part (regcache, R0_REGNUM + reg,
449b725ae77Skettenis 					0, 1, (bfd_byte *) writebuf + reg * 2);
450b725ae77Skettenis 	}
451b725ae77Skettenis     }
452b725ae77Skettenis   return RETURN_VALUE_REGISTER_CONVENTION;
453b725ae77Skettenis }
454b725ae77Skettenis 
455b725ae77Skettenis static int
check_prologue(unsigned short op)456b725ae77Skettenis check_prologue (unsigned short op)
457b725ae77Skettenis {
458b725ae77Skettenis   /* st  rn, @-sp */
459b725ae77Skettenis   if ((op & 0x7E1F) == 0x6C1F)
460b725ae77Skettenis     return 1;
461b725ae77Skettenis 
462b725ae77Skettenis   /* st2w  rn, @-sp */
463b725ae77Skettenis   if ((op & 0x7E3F) == 0x6E1F)
464b725ae77Skettenis     return 1;
465b725ae77Skettenis 
466b725ae77Skettenis   /* subi  sp, n */
467b725ae77Skettenis   if ((op & 0x7FE1) == 0x01E1)
468b725ae77Skettenis     return 1;
469b725ae77Skettenis 
470b725ae77Skettenis   /* mv  r11, sp */
471b725ae77Skettenis   if (op == 0x417E)
472b725ae77Skettenis     return 1;
473b725ae77Skettenis 
474b725ae77Skettenis   /* nop */
475b725ae77Skettenis   if (op == 0x5E00)
476b725ae77Skettenis     return 1;
477b725ae77Skettenis 
478b725ae77Skettenis   /* st  rn, @sp */
479b725ae77Skettenis   if ((op & 0x7E1F) == 0x681E)
480b725ae77Skettenis     return 1;
481b725ae77Skettenis 
482b725ae77Skettenis   /* st2w  rn, @sp */
483b725ae77Skettenis   if ((op & 0x7E3F) == 0x3A1E)
484b725ae77Skettenis     return 1;
485b725ae77Skettenis 
486b725ae77Skettenis   return 0;
487b725ae77Skettenis }
488b725ae77Skettenis 
489b725ae77Skettenis static CORE_ADDR
d10v_skip_prologue(CORE_ADDR pc)490b725ae77Skettenis d10v_skip_prologue (CORE_ADDR pc)
491b725ae77Skettenis {
492b725ae77Skettenis   unsigned long op;
493b725ae77Skettenis   unsigned short op1, op2;
494b725ae77Skettenis   CORE_ADDR func_addr, func_end;
495b725ae77Skettenis   struct symtab_and_line sal;
496b725ae77Skettenis 
497b725ae77Skettenis   /* If we have line debugging information, then the end of the prologue
498b725ae77Skettenis      should be the first assembly instruction of the first source line.  */
499b725ae77Skettenis   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
500b725ae77Skettenis     {
501b725ae77Skettenis       sal = find_pc_line (func_addr, 0);
502b725ae77Skettenis       if (sal.end && sal.end < func_end)
503b725ae77Skettenis 	return sal.end;
504b725ae77Skettenis     }
505b725ae77Skettenis 
506b725ae77Skettenis   if (target_read_memory (pc, (char *) &op, 4))
507b725ae77Skettenis     return pc;			/* Can't access it -- assume no prologue.  */
508b725ae77Skettenis 
509b725ae77Skettenis   while (1)
510b725ae77Skettenis     {
511b725ae77Skettenis       op = (unsigned long) read_memory_integer (pc, 4);
512b725ae77Skettenis       if ((op & 0xC0000000) == 0xC0000000)
513b725ae77Skettenis 	{
514b725ae77Skettenis 	  /* long instruction */
515b725ae77Skettenis 	  if (((op & 0x3FFF0000) != 0x01FF0000) &&	/* add3 sp,sp,n */
516b725ae77Skettenis 	      ((op & 0x3F0F0000) != 0x340F0000) &&	/* st  rn, @(offset,sp) */
517b725ae77Skettenis 	      ((op & 0x3F1F0000) != 0x350F0000))	/* st2w  rn, @(offset,sp) */
518b725ae77Skettenis 	    break;
519b725ae77Skettenis 	}
520b725ae77Skettenis       else
521b725ae77Skettenis 	{
522b725ae77Skettenis 	  /* short instructions */
523b725ae77Skettenis 	  if ((op & 0xC0000000) == 0x80000000)
524b725ae77Skettenis 	    {
525b725ae77Skettenis 	      op2 = (op & 0x3FFF8000) >> 15;
526b725ae77Skettenis 	      op1 = op & 0x7FFF;
527b725ae77Skettenis 	    }
528b725ae77Skettenis 	  else
529b725ae77Skettenis 	    {
530b725ae77Skettenis 	      op1 = (op & 0x3FFF8000) >> 15;
531b725ae77Skettenis 	      op2 = op & 0x7FFF;
532b725ae77Skettenis 	    }
533b725ae77Skettenis 	  if (check_prologue (op1))
534b725ae77Skettenis 	    {
535b725ae77Skettenis 	      if (!check_prologue (op2))
536b725ae77Skettenis 		{
537b725ae77Skettenis 		  /* If the previous opcode was really part of the
538b725ae77Skettenis 		     prologue and not just a NOP, then we want to
539b725ae77Skettenis 		     break after both instructions.  */
540b725ae77Skettenis 		  if (op1 != 0x5E00)
541b725ae77Skettenis 		    pc += 4;
542b725ae77Skettenis 		  break;
543b725ae77Skettenis 		}
544b725ae77Skettenis 	    }
545b725ae77Skettenis 	  else
546b725ae77Skettenis 	    break;
547b725ae77Skettenis 	}
548b725ae77Skettenis       pc += 4;
549b725ae77Skettenis     }
550b725ae77Skettenis   return pc;
551b725ae77Skettenis }
552b725ae77Skettenis 
553b725ae77Skettenis struct d10v_unwind_cache
554b725ae77Skettenis {
555b725ae77Skettenis   /* The previous frame's inner most stack address.  Used as this
556b725ae77Skettenis      frame ID's stack_addr.  */
557b725ae77Skettenis   CORE_ADDR prev_sp;
558b725ae77Skettenis   /* The frame's base, optionally used by the high-level debug info.  */
559b725ae77Skettenis   CORE_ADDR base;
560b725ae77Skettenis   int size;
561b725ae77Skettenis   /* How far the SP and r11 (FP) have been offset from the start of
562b725ae77Skettenis      the stack frame (as defined by the previous frame's stack
563b725ae77Skettenis      pointer).  */
564b725ae77Skettenis   LONGEST sp_offset;
565b725ae77Skettenis   LONGEST r11_offset;
566b725ae77Skettenis   int uses_frame;
567b725ae77Skettenis   /* Table indicating the location of each and every register.  */
568b725ae77Skettenis   struct trad_frame_saved_reg *saved_regs;
569b725ae77Skettenis };
570b725ae77Skettenis 
571b725ae77Skettenis static int
prologue_find_regs(struct d10v_unwind_cache * info,unsigned short op,CORE_ADDR addr)572b725ae77Skettenis prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
573b725ae77Skettenis 		    CORE_ADDR addr)
574b725ae77Skettenis {
575b725ae77Skettenis   int n;
576b725ae77Skettenis 
577b725ae77Skettenis   /* st  rn, @-sp */
578b725ae77Skettenis   if ((op & 0x7E1F) == 0x6C1F)
579b725ae77Skettenis     {
580b725ae77Skettenis       n = (op & 0x1E0) >> 5;
581b725ae77Skettenis       info->sp_offset -= 2;
582b725ae77Skettenis       info->saved_regs[n].addr = info->sp_offset;
583b725ae77Skettenis       return 1;
584b725ae77Skettenis     }
585b725ae77Skettenis 
586b725ae77Skettenis   /* st2w  rn, @-sp */
587b725ae77Skettenis   else if ((op & 0x7E3F) == 0x6E1F)
588b725ae77Skettenis     {
589b725ae77Skettenis       n = (op & 0x1E0) >> 5;
590b725ae77Skettenis       info->sp_offset -= 4;
591b725ae77Skettenis       info->saved_regs[n + 0].addr = info->sp_offset + 0;
592b725ae77Skettenis       info->saved_regs[n + 1].addr = info->sp_offset + 2;
593b725ae77Skettenis       return 1;
594b725ae77Skettenis     }
595b725ae77Skettenis 
596b725ae77Skettenis   /* subi  sp, n */
597b725ae77Skettenis   if ((op & 0x7FE1) == 0x01E1)
598b725ae77Skettenis     {
599b725ae77Skettenis       n = (op & 0x1E) >> 1;
600b725ae77Skettenis       if (n == 0)
601b725ae77Skettenis 	n = 16;
602b725ae77Skettenis       info->sp_offset -= n;
603b725ae77Skettenis       return 1;
604b725ae77Skettenis     }
605b725ae77Skettenis 
606b725ae77Skettenis   /* mv  r11, sp */
607b725ae77Skettenis   if (op == 0x417E)
608b725ae77Skettenis     {
609b725ae77Skettenis       info->uses_frame = 1;
610b725ae77Skettenis       info->r11_offset = info->sp_offset;
611b725ae77Skettenis       return 1;
612b725ae77Skettenis     }
613b725ae77Skettenis 
614b725ae77Skettenis   /* st  rn, @r11 */
615b725ae77Skettenis   if ((op & 0x7E1F) == 0x6816)
616b725ae77Skettenis     {
617b725ae77Skettenis       n = (op & 0x1E0) >> 5;
618b725ae77Skettenis       info->saved_regs[n].addr = info->r11_offset;
619b725ae77Skettenis       return 1;
620b725ae77Skettenis     }
621b725ae77Skettenis 
622b725ae77Skettenis   /* nop */
623b725ae77Skettenis   if (op == 0x5E00)
624b725ae77Skettenis     return 1;
625b725ae77Skettenis 
626b725ae77Skettenis   /* st  rn, @sp */
627b725ae77Skettenis   if ((op & 0x7E1F) == 0x681E)
628b725ae77Skettenis     {
629b725ae77Skettenis       n = (op & 0x1E0) >> 5;
630b725ae77Skettenis       info->saved_regs[n].addr = info->sp_offset;
631b725ae77Skettenis       return 1;
632b725ae77Skettenis     }
633b725ae77Skettenis 
634b725ae77Skettenis   /* st2w  rn, @sp */
635b725ae77Skettenis   if ((op & 0x7E3F) == 0x3A1E)
636b725ae77Skettenis     {
637b725ae77Skettenis       n = (op & 0x1E0) >> 5;
638b725ae77Skettenis       info->saved_regs[n + 0].addr = info->sp_offset + 0;
639b725ae77Skettenis       info->saved_regs[n + 1].addr = info->sp_offset + 2;
640b725ae77Skettenis       return 1;
641b725ae77Skettenis     }
642b725ae77Skettenis 
643b725ae77Skettenis   return 0;
644b725ae77Skettenis }
645b725ae77Skettenis 
646b725ae77Skettenis /* Put here the code to store, into fi->saved_regs, the addresses of
647b725ae77Skettenis    the saved registers of frame described by FRAME_INFO.  This
648b725ae77Skettenis    includes special registers such as pc and fp saved in special ways
649b725ae77Skettenis    in the stack frame.  sp is even more special: the address we return
650b725ae77Skettenis    for it IS the sp for the next frame.  */
651b725ae77Skettenis 
652b725ae77Skettenis static struct d10v_unwind_cache *
d10v_frame_unwind_cache(struct frame_info * next_frame,void ** this_prologue_cache)653b725ae77Skettenis d10v_frame_unwind_cache (struct frame_info *next_frame,
654b725ae77Skettenis 			 void **this_prologue_cache)
655b725ae77Skettenis {
656b725ae77Skettenis   struct gdbarch *gdbarch = get_frame_arch (next_frame);
657b725ae77Skettenis   CORE_ADDR pc;
658b725ae77Skettenis   ULONGEST prev_sp;
659b725ae77Skettenis   ULONGEST this_base;
660b725ae77Skettenis   unsigned long op;
661b725ae77Skettenis   unsigned short op1, op2;
662b725ae77Skettenis   int i;
663b725ae77Skettenis   struct d10v_unwind_cache *info;
664b725ae77Skettenis 
665b725ae77Skettenis   if ((*this_prologue_cache))
666b725ae77Skettenis     return (*this_prologue_cache);
667b725ae77Skettenis 
668b725ae77Skettenis   info = FRAME_OBSTACK_ZALLOC (struct d10v_unwind_cache);
669b725ae77Skettenis   (*this_prologue_cache) = info;
670b725ae77Skettenis   info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
671b725ae77Skettenis 
672b725ae77Skettenis   info->size = 0;
673b725ae77Skettenis   info->sp_offset = 0;
674b725ae77Skettenis 
675b725ae77Skettenis   info->uses_frame = 0;
676b725ae77Skettenis   for (pc = frame_func_unwind (next_frame);
677b725ae77Skettenis        pc > 0 && pc < frame_pc_unwind (next_frame);
678b725ae77Skettenis        pc += 4)
679b725ae77Skettenis     {
680b725ae77Skettenis       op = get_frame_memory_unsigned (next_frame, pc, 4);
681b725ae77Skettenis       if ((op & 0xC0000000) == 0xC0000000)
682b725ae77Skettenis 	{
683b725ae77Skettenis 	  /* long instruction */
684b725ae77Skettenis 	  if ((op & 0x3FFF0000) == 0x01FF0000)
685b725ae77Skettenis 	    {
686b725ae77Skettenis 	      /* add3 sp,sp,n */
687b725ae77Skettenis 	      short n = op & 0xFFFF;
688b725ae77Skettenis 	      info->sp_offset += n;
689b725ae77Skettenis 	    }
690b725ae77Skettenis 	  else if ((op & 0x3F0F0000) == 0x340F0000)
691b725ae77Skettenis 	    {
692b725ae77Skettenis 	      /* st  rn, @(offset,sp) */
693b725ae77Skettenis 	      short offset = op & 0xFFFF;
694b725ae77Skettenis 	      short n = (op >> 20) & 0xF;
695b725ae77Skettenis 	      info->saved_regs[n].addr = info->sp_offset + offset;
696b725ae77Skettenis 	    }
697b725ae77Skettenis 	  else if ((op & 0x3F1F0000) == 0x350F0000)
698b725ae77Skettenis 	    {
699b725ae77Skettenis 	      /* st2w  rn, @(offset,sp) */
700b725ae77Skettenis 	      short offset = op & 0xFFFF;
701b725ae77Skettenis 	      short n = (op >> 20) & 0xF;
702b725ae77Skettenis 	      info->saved_regs[n + 0].addr = info->sp_offset + offset + 0;
703b725ae77Skettenis 	      info->saved_regs[n + 1].addr = info->sp_offset + offset + 2;
704b725ae77Skettenis 	    }
705b725ae77Skettenis 	  else
706b725ae77Skettenis 	    break;
707b725ae77Skettenis 	}
708b725ae77Skettenis       else
709b725ae77Skettenis 	{
710b725ae77Skettenis 	  /* short instructions */
711b725ae77Skettenis 	  if ((op & 0xC0000000) == 0x80000000)
712b725ae77Skettenis 	    {
713b725ae77Skettenis 	      op2 = (op & 0x3FFF8000) >> 15;
714b725ae77Skettenis 	      op1 = op & 0x7FFF;
715b725ae77Skettenis 	    }
716b725ae77Skettenis 	  else
717b725ae77Skettenis 	    {
718b725ae77Skettenis 	      op1 = (op & 0x3FFF8000) >> 15;
719b725ae77Skettenis 	      op2 = op & 0x7FFF;
720b725ae77Skettenis 	    }
721b725ae77Skettenis 	  if (!prologue_find_regs (info, op1, pc)
722b725ae77Skettenis 	      || !prologue_find_regs (info, op2, pc))
723b725ae77Skettenis 	    break;
724b725ae77Skettenis 	}
725b725ae77Skettenis     }
726b725ae77Skettenis 
727b725ae77Skettenis   info->size = -info->sp_offset;
728b725ae77Skettenis 
729b725ae77Skettenis   /* Compute the previous frame's stack pointer (which is also the
730b725ae77Skettenis      frame's ID's stack address), and this frame's base pointer.  */
731b725ae77Skettenis   if (info->uses_frame)
732b725ae77Skettenis     {
733b725ae77Skettenis       /* The SP was moved to the FP.  This indicates that a new frame
734b725ae77Skettenis          was created.  Get THIS frame's FP value by unwinding it from
735b725ae77Skettenis          the next frame.  */
736b725ae77Skettenis       frame_unwind_unsigned_register (next_frame, D10V_FP_REGNUM, &this_base);
737b725ae77Skettenis       /* The FP points at the last saved register.  Adjust the FP back
738b725ae77Skettenis          to before the first saved register giving the SP.  */
739b725ae77Skettenis       prev_sp = this_base + info->size;
740b725ae77Skettenis     }
741b725ae77Skettenis   else
742b725ae77Skettenis     {
743b725ae77Skettenis       /* Assume that the FP is this frame's SP but with that pushed
744b725ae77Skettenis          stack space added back.  */
745b725ae77Skettenis       frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &this_base);
746b725ae77Skettenis       prev_sp = this_base + info->size;
747b725ae77Skettenis     }
748b725ae77Skettenis 
749b725ae77Skettenis   /* Convert that SP/BASE into real addresses.  */
750b725ae77Skettenis   info->prev_sp =  d10v_make_daddr (prev_sp);
751b725ae77Skettenis   info->base = d10v_make_daddr (this_base);
752b725ae77Skettenis 
753b725ae77Skettenis   /* Adjust all the saved registers so that they contain addresses and
754b725ae77Skettenis      not offsets.  */
755b725ae77Skettenis   for (i = 0; i < NUM_REGS - 1; i++)
756b725ae77Skettenis     if (trad_frame_addr_p (info->saved_regs, i))
757b725ae77Skettenis       {
758b725ae77Skettenis 	info->saved_regs[i].addr = (info->prev_sp + info->saved_regs[i].addr);
759b725ae77Skettenis       }
760b725ae77Skettenis 
761b725ae77Skettenis   /* The call instruction moves the caller's PC in the callee's LR.
762b725ae77Skettenis      Since this is an unwind, do the reverse.  Copy the location of LR
763b725ae77Skettenis      into PC (the address / regnum) so that a request for PC will be
764b725ae77Skettenis      converted into a request for the LR.  */
765b725ae77Skettenis   info->saved_regs[D10V_PC_REGNUM] = info->saved_regs[LR_REGNUM];
766b725ae77Skettenis 
767b725ae77Skettenis   /* The previous frame's SP needed to be computed.  Save the computed
768b725ae77Skettenis      value.  */
769b725ae77Skettenis   trad_frame_set_value (info->saved_regs, D10V_SP_REGNUM,
770b725ae77Skettenis 			d10v_make_daddr (prev_sp));
771b725ae77Skettenis 
772b725ae77Skettenis   return info;
773b725ae77Skettenis }
774b725ae77Skettenis 
775b725ae77Skettenis static void
d10v_print_registers_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,int regnum,int all)776b725ae77Skettenis d10v_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
777b725ae77Skettenis 			   struct frame_info *frame, int regnum, int all)
778b725ae77Skettenis {
779b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
780b725ae77Skettenis   if (regnum >= 0)
781b725ae77Skettenis     {
782b725ae77Skettenis       default_print_registers_info (gdbarch, file, frame, regnum, all);
783b725ae77Skettenis       return;
784b725ae77Skettenis     }
785b725ae77Skettenis 
786b725ae77Skettenis   {
787b725ae77Skettenis     ULONGEST pc, psw, rpt_s, rpt_e, rpt_c;
788b725ae77Skettenis     pc = get_frame_register_unsigned (frame, D10V_PC_REGNUM);
789b725ae77Skettenis     psw = get_frame_register_unsigned (frame, PSW_REGNUM);
790b725ae77Skettenis     rpt_s = get_frame_register_unsigned (frame, frame_map_name_to_regnum (frame, "rpt_s", -1));
791b725ae77Skettenis     rpt_e = get_frame_register_unsigned (frame, frame_map_name_to_regnum (frame, "rpt_e", -1));
792b725ae77Skettenis     rpt_c = get_frame_register_unsigned (frame, frame_map_name_to_regnum (frame, "rpt_c", -1));
793b725ae77Skettenis     fprintf_filtered (file, "PC=%04lx (0x%lx) PSW=%04lx RPT_S=%04lx RPT_E=%04lx RPT_C=%04lx\n",
794b725ae77Skettenis 		     (long) pc, (long) d10v_make_iaddr (pc), (long) psw,
795b725ae77Skettenis 		     (long) rpt_s, (long) rpt_e, (long) rpt_c);
796b725ae77Skettenis   }
797b725ae77Skettenis 
798b725ae77Skettenis   {
799b725ae77Skettenis     int group;
800b725ae77Skettenis     for (group = 0; group < 16; group += 8)
801b725ae77Skettenis       {
802b725ae77Skettenis 	int r;
803b725ae77Skettenis 	fprintf_filtered (file, "R%d-R%-2d", group, group + 7);
804b725ae77Skettenis 	for (r = group; r < group + 8; r++)
805b725ae77Skettenis 	  {
806b725ae77Skettenis 	    ULONGEST tmp;
807b725ae77Skettenis 	    tmp = get_frame_register_unsigned (frame, r);
808b725ae77Skettenis 	    fprintf_filtered (file, " %04lx", (long) tmp);
809b725ae77Skettenis 	  }
810b725ae77Skettenis 	fprintf_filtered (file, "\n");
811b725ae77Skettenis       }
812b725ae77Skettenis   }
813b725ae77Skettenis 
814b725ae77Skettenis   /* Note: The IMAP/DMAP registers don't participate in function
815b725ae77Skettenis      calls.  Don't bother trying to unwind them.  */
816b725ae77Skettenis 
817b725ae77Skettenis   {
818b725ae77Skettenis     int a;
819b725ae77Skettenis     for (a = 0; a < NR_IMAP_REGS; a++)
820b725ae77Skettenis       {
821b725ae77Skettenis 	if (a > 0)
822b725ae77Skettenis 	  fprintf_filtered (file, "    ");
823b725ae77Skettenis 	fprintf_filtered (file, "IMAP%d %04lx", a,
824b725ae77Skettenis 			  tdep->imap_register (current_regcache, a));
825b725ae77Skettenis       }
826b725ae77Skettenis     if (nr_dmap_regs (gdbarch) == 1)
827b725ae77Skettenis       /* Registers DMAP0 and DMAP1 are constant.  Just return dmap2.  */
828b725ae77Skettenis       fprintf_filtered (file, "    DMAP %04lx\n",
829b725ae77Skettenis 			tdep->dmap_register (current_regcache, 2));
830b725ae77Skettenis     else
831b725ae77Skettenis       {
832b725ae77Skettenis 	for (a = 0; a < nr_dmap_regs (gdbarch); a++)
833b725ae77Skettenis 	  {
834b725ae77Skettenis 	    fprintf_filtered (file, "    DMAP%d %04lx", a,
835b725ae77Skettenis 			      tdep->dmap_register (current_regcache, a));
836b725ae77Skettenis 	  }
837b725ae77Skettenis 	fprintf_filtered (file, "\n");
838b725ae77Skettenis       }
839b725ae77Skettenis   }
840b725ae77Skettenis 
841b725ae77Skettenis   {
842b725ae77Skettenis     char num[MAX_REGISTER_SIZE];
843b725ae77Skettenis     int a;
844b725ae77Skettenis     fprintf_filtered (file, "A0-A%d", NR_A_REGS - 1);
845b725ae77Skettenis     for (a = a0_regnum (gdbarch); a < a0_regnum (gdbarch) + NR_A_REGS; a++)
846b725ae77Skettenis       {
847b725ae77Skettenis 	int i;
848b725ae77Skettenis 	fprintf_filtered (file, "  ");
849b725ae77Skettenis 	get_frame_register (frame, a, num);
850b725ae77Skettenis 	for (i = 0; i < register_size (gdbarch, a); i++)
851b725ae77Skettenis 	  {
852b725ae77Skettenis 	    fprintf_filtered (file, "%02x", (num[i] & 0xff));
853b725ae77Skettenis 	  }
854b725ae77Skettenis       }
855b725ae77Skettenis   }
856b725ae77Skettenis   fprintf_filtered (file, "\n");
857b725ae77Skettenis }
858b725ae77Skettenis 
859b725ae77Skettenis static void
show_regs(char * args,int from_tty)860b725ae77Skettenis show_regs (char *args, int from_tty)
861b725ae77Skettenis {
862b725ae77Skettenis   d10v_print_registers_info (current_gdbarch, gdb_stdout,
863b725ae77Skettenis 			     get_current_frame (), -1, 1);
864b725ae77Skettenis }
865b725ae77Skettenis 
866b725ae77Skettenis static CORE_ADDR
d10v_read_pc(ptid_t ptid)867b725ae77Skettenis d10v_read_pc (ptid_t ptid)
868b725ae77Skettenis {
869b725ae77Skettenis   ptid_t save_ptid;
870b725ae77Skettenis   CORE_ADDR pc;
871b725ae77Skettenis   CORE_ADDR retval;
872b725ae77Skettenis 
873b725ae77Skettenis   save_ptid = inferior_ptid;
874b725ae77Skettenis   inferior_ptid = ptid;
875b725ae77Skettenis   pc = (int) read_register (D10V_PC_REGNUM);
876b725ae77Skettenis   inferior_ptid = save_ptid;
877b725ae77Skettenis   retval = d10v_make_iaddr (pc);
878b725ae77Skettenis   return retval;
879b725ae77Skettenis }
880b725ae77Skettenis 
881b725ae77Skettenis static void
d10v_write_pc(CORE_ADDR val,ptid_t ptid)882b725ae77Skettenis d10v_write_pc (CORE_ADDR val, ptid_t ptid)
883b725ae77Skettenis {
884b725ae77Skettenis   ptid_t save_ptid;
885b725ae77Skettenis 
886b725ae77Skettenis   save_ptid = inferior_ptid;
887b725ae77Skettenis   inferior_ptid = ptid;
888b725ae77Skettenis   write_register (D10V_PC_REGNUM, d10v_convert_iaddr_to_raw (val));
889b725ae77Skettenis   inferior_ptid = save_ptid;
890b725ae77Skettenis }
891b725ae77Skettenis 
892b725ae77Skettenis static CORE_ADDR
d10v_unwind_sp(struct gdbarch * gdbarch,struct frame_info * next_frame)893b725ae77Skettenis d10v_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
894b725ae77Skettenis {
895b725ae77Skettenis   ULONGEST sp;
896b725ae77Skettenis   frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &sp);
897b725ae77Skettenis   return d10v_make_daddr (sp);
898b725ae77Skettenis }
899b725ae77Skettenis 
900b725ae77Skettenis /* When arguments must be pushed onto the stack, they go on in reverse
901b725ae77Skettenis    order.  The below implements a FILO (stack) to do this.  */
902b725ae77Skettenis 
903b725ae77Skettenis struct stack_item
904b725ae77Skettenis {
905b725ae77Skettenis   int len;
906b725ae77Skettenis   struct stack_item *prev;
907b725ae77Skettenis   void *data;
908b725ae77Skettenis };
909b725ae77Skettenis 
910b725ae77Skettenis static struct stack_item *push_stack_item (struct stack_item *prev,
911b725ae77Skettenis 					   void *contents, int len);
912b725ae77Skettenis static struct stack_item *
push_stack_item(struct stack_item * prev,void * contents,int len)913b725ae77Skettenis push_stack_item (struct stack_item *prev, void *contents, int len)
914b725ae77Skettenis {
915b725ae77Skettenis   struct stack_item *si;
916b725ae77Skettenis   si = xmalloc (sizeof (struct stack_item));
917b725ae77Skettenis   si->data = xmalloc (len);
918b725ae77Skettenis   si->len = len;
919b725ae77Skettenis   si->prev = prev;
920b725ae77Skettenis   memcpy (si->data, contents, len);
921b725ae77Skettenis   return si;
922b725ae77Skettenis }
923b725ae77Skettenis 
924b725ae77Skettenis static struct stack_item *pop_stack_item (struct stack_item *si);
925b725ae77Skettenis static struct stack_item *
pop_stack_item(struct stack_item * si)926b725ae77Skettenis pop_stack_item (struct stack_item *si)
927b725ae77Skettenis {
928b725ae77Skettenis   struct stack_item *dead = si;
929b725ae77Skettenis   si = si->prev;
930b725ae77Skettenis   xfree (dead->data);
931b725ae77Skettenis   xfree (dead);
932b725ae77Skettenis   return si;
933b725ae77Skettenis }
934b725ae77Skettenis 
935b725ae77Skettenis 
936b725ae77Skettenis static CORE_ADDR
d10v_push_dummy_code(struct gdbarch * gdbarch,CORE_ADDR sp,CORE_ADDR funaddr,int using_gcc,struct value ** args,int nargs,struct type * value_type,CORE_ADDR * real_pc,CORE_ADDR * bp_addr)937b725ae77Skettenis d10v_push_dummy_code (struct gdbarch *gdbarch,
938b725ae77Skettenis 		      CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
939b725ae77Skettenis 		      struct value **args, int nargs,
940b725ae77Skettenis 		      struct type *value_type,
941b725ae77Skettenis 		      CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
942b725ae77Skettenis {
943b725ae77Skettenis   /* Allocate space sufficient for a breakpoint.  */
944b725ae77Skettenis   sp = (sp - 4) & ~3;
945b725ae77Skettenis   /* Store the address of that breakpoint taking care to first convert
946b725ae77Skettenis      it into a code (IADDR) address from a stack (DADDR) address.
947b725ae77Skettenis      This of course assumes that the two virtual addresses map onto
948b725ae77Skettenis      the same real address.  */
949b725ae77Skettenis   (*bp_addr) = d10v_make_iaddr (d10v_convert_iaddr_to_raw (sp));
950b725ae77Skettenis   /* d10v always starts the call at the callee's entry point.  */
951b725ae77Skettenis   (*real_pc) = funaddr;
952b725ae77Skettenis   return sp;
953b725ae77Skettenis }
954b725ae77Skettenis 
955b725ae77Skettenis static CORE_ADDR
d10v_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)956*11efff7fSkettenis d10v_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
957b725ae77Skettenis 		      struct regcache *regcache, CORE_ADDR bp_addr,
958b725ae77Skettenis 		      int nargs, struct value **args, CORE_ADDR sp,
959b725ae77Skettenis 		      int struct_return, CORE_ADDR struct_addr)
960b725ae77Skettenis {
961b725ae77Skettenis   int i;
962b725ae77Skettenis   int regnum = ARG1_REGNUM;
963b725ae77Skettenis   struct stack_item *si = NULL;
964b725ae77Skettenis   long val;
965b725ae77Skettenis 
966b725ae77Skettenis   /* Set the return address.  For the d10v, the return breakpoint is
967b725ae77Skettenis      always at BP_ADDR.  */
968b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, LR_REGNUM,
969b725ae77Skettenis 				  d10v_convert_iaddr_to_raw (bp_addr));
970b725ae77Skettenis 
971b725ae77Skettenis   /* If STRUCT_RETURN is true, then the struct return address (in
972b725ae77Skettenis      STRUCT_ADDR) will consume the first argument-passing register.
973b725ae77Skettenis      Both adjust the register count and store that value.  */
974b725ae77Skettenis   if (struct_return)
975b725ae77Skettenis     {
976b725ae77Skettenis       regcache_cooked_write_unsigned (regcache, regnum, struct_addr);
977b725ae77Skettenis       regnum++;
978b725ae77Skettenis     }
979b725ae77Skettenis 
980b725ae77Skettenis   /* Fill in registers and arg lists */
981b725ae77Skettenis   for (i = 0; i < nargs; i++)
982b725ae77Skettenis     {
983b725ae77Skettenis       struct value *arg = args[i];
984b725ae77Skettenis       struct type *type = check_typedef (VALUE_TYPE (arg));
985b725ae77Skettenis       char *contents = VALUE_CONTENTS (arg);
986b725ae77Skettenis       int len = TYPE_LENGTH (type);
987b725ae77Skettenis       int aligned_regnum = (regnum + 1) & ~1;
988b725ae77Skettenis 
989b725ae77Skettenis       /* printf ("push: type=%d len=%d\n", TYPE_CODE (type), len); */
990b725ae77Skettenis       if (len <= 2 && regnum <= ARGN_REGNUM)
991b725ae77Skettenis 	/* fits in a single register, do not align */
992b725ae77Skettenis 	{
993b725ae77Skettenis 	  val = extract_unsigned_integer (contents, len);
994b725ae77Skettenis 	  regcache_cooked_write_unsigned (regcache, regnum++, val);
995b725ae77Skettenis 	}
996b725ae77Skettenis       else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
997b725ae77Skettenis 	/* value fits in remaining registers, store keeping left
998b725ae77Skettenis 	   aligned */
999b725ae77Skettenis 	{
1000b725ae77Skettenis 	  int b;
1001b725ae77Skettenis 	  regnum = aligned_regnum;
1002b725ae77Skettenis 	  for (b = 0; b < (len & ~1); b += 2)
1003b725ae77Skettenis 	    {
1004b725ae77Skettenis 	      val = extract_unsigned_integer (&contents[b], 2);
1005b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, regnum++, val);
1006b725ae77Skettenis 	    }
1007b725ae77Skettenis 	  if (b < len)
1008b725ae77Skettenis 	    {
1009b725ae77Skettenis 	      val = extract_unsigned_integer (&contents[b], 1);
1010b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, regnum++, (val << 8));
1011b725ae77Skettenis 	    }
1012b725ae77Skettenis 	}
1013b725ae77Skettenis       else
1014b725ae77Skettenis 	{
1015b725ae77Skettenis 	  /* arg will go onto stack */
1016b725ae77Skettenis 	  regnum = ARGN_REGNUM + 1;
1017b725ae77Skettenis 	  si = push_stack_item (si, contents, len);
1018b725ae77Skettenis 	}
1019b725ae77Skettenis     }
1020b725ae77Skettenis 
1021b725ae77Skettenis   while (si)
1022b725ae77Skettenis     {
1023b725ae77Skettenis       sp = (sp - si->len) & ~1;
1024b725ae77Skettenis       write_memory (sp, si->data, si->len);
1025b725ae77Skettenis       si = pop_stack_item (si);
1026b725ae77Skettenis     }
1027b725ae77Skettenis 
1028b725ae77Skettenis   /* Finally, update the SP register.  */
1029b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, D10V_SP_REGNUM,
1030b725ae77Skettenis 				  d10v_convert_daddr_to_raw (sp));
1031b725ae77Skettenis 
1032b725ae77Skettenis   return sp;
1033b725ae77Skettenis }
1034b725ae77Skettenis 
1035b725ae77Skettenis /* Translate a GDB virtual ADDR/LEN into a format the remote target
1036b725ae77Skettenis    understands.  Returns number of bytes that can be transfered
1037b725ae77Skettenis    starting at TARG_ADDR.  Return ZERO if no bytes can be transfered
1038b725ae77Skettenis    (segmentation fault).  Since the simulator knows all about how the
1039b725ae77Skettenis    VM system works, we just call that to do the translation.  */
1040b725ae77Skettenis 
1041b725ae77Skettenis static void
remote_d10v_translate_xfer_address(struct gdbarch * gdbarch,struct regcache * regcache,CORE_ADDR memaddr,int nr_bytes,CORE_ADDR * targ_addr,int * targ_len)1042b725ae77Skettenis remote_d10v_translate_xfer_address (struct gdbarch *gdbarch,
1043b725ae77Skettenis 				    struct regcache *regcache,
1044b725ae77Skettenis 				    CORE_ADDR memaddr, int nr_bytes,
1045b725ae77Skettenis 				    CORE_ADDR *targ_addr, int *targ_len)
1046b725ae77Skettenis {
1047b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1048b725ae77Skettenis   long out_addr;
1049b725ae77Skettenis   long out_len;
1050b725ae77Skettenis   out_len = sim_d10v_translate_addr (memaddr, nr_bytes, &out_addr, regcache,
1051b725ae77Skettenis 				     tdep->dmap_register, tdep->imap_register);
1052b725ae77Skettenis   *targ_addr = out_addr;
1053b725ae77Skettenis   *targ_len = out_len;
1054b725ae77Skettenis }
1055b725ae77Skettenis 
1056b725ae77Skettenis 
1057b725ae77Skettenis /* The following code implements access to, and display of, the D10V's
1058b725ae77Skettenis    instruction trace buffer.  The buffer consists of 64K or more
1059b725ae77Skettenis    4-byte words of data, of which each words includes an 8-bit count,
1060b725ae77Skettenis    an 8-bit segment number, and a 16-bit instruction address.
1061b725ae77Skettenis 
1062b725ae77Skettenis    In theory, the trace buffer is continuously capturing instruction
1063b725ae77Skettenis    data that the CPU presents on its "debug bus", but in practice, the
1064b725ae77Skettenis    ROMified GDB stub only enables tracing when it continues or steps
1065b725ae77Skettenis    the program, and stops tracing when the program stops; so it
1066b725ae77Skettenis    actually works for GDB to read the buffer counter out of memory and
1067b725ae77Skettenis    then read each trace word.  The counter records where the tracing
1068b725ae77Skettenis    stops, but there is no record of where it started, so we remember
1069b725ae77Skettenis    the PC when we resumed and then search backwards in the trace
1070b725ae77Skettenis    buffer for a word that includes that address.  This is not perfect,
1071b725ae77Skettenis    because you will miss trace data if the resumption PC is the target
1072b725ae77Skettenis    of a branch.  (The value of the buffer counter is semi-random, any
1073b725ae77Skettenis    trace data from a previous program stop is gone.)  */
1074b725ae77Skettenis 
1075b725ae77Skettenis /* The address of the last word recorded in the trace buffer.  */
1076b725ae77Skettenis 
1077b725ae77Skettenis #define DBBC_ADDR (0xd80000)
1078b725ae77Skettenis 
1079b725ae77Skettenis /* The base of the trace buffer, at least for the "Board_0".  */
1080b725ae77Skettenis 
1081b725ae77Skettenis #define TRACE_BUFFER_BASE (0xf40000)
1082b725ae77Skettenis 
1083b725ae77Skettenis static void trace_command (char *, int);
1084b725ae77Skettenis 
1085b725ae77Skettenis static void untrace_command (char *, int);
1086b725ae77Skettenis 
1087b725ae77Skettenis static void trace_info (char *, int);
1088b725ae77Skettenis 
1089b725ae77Skettenis static void tdisassemble_command (char *, int);
1090b725ae77Skettenis 
1091b725ae77Skettenis static void display_trace (int, int);
1092b725ae77Skettenis 
1093b725ae77Skettenis /* True when instruction traces are being collected.  */
1094b725ae77Skettenis 
1095b725ae77Skettenis static int tracing;
1096b725ae77Skettenis 
1097b725ae77Skettenis /* Remembered PC.  */
1098b725ae77Skettenis 
1099b725ae77Skettenis static CORE_ADDR last_pc;
1100b725ae77Skettenis 
1101b725ae77Skettenis /* True when trace output should be displayed whenever program stops.  */
1102b725ae77Skettenis 
1103b725ae77Skettenis static int trace_display;
1104b725ae77Skettenis 
1105b725ae77Skettenis /* True when trace listing should include source lines.  */
1106b725ae77Skettenis 
1107b725ae77Skettenis static int default_trace_show_source = 1;
1108b725ae77Skettenis 
1109b725ae77Skettenis struct trace_buffer
1110b725ae77Skettenis   {
1111b725ae77Skettenis     int size;
1112b725ae77Skettenis     short *counts;
1113b725ae77Skettenis     CORE_ADDR *addrs;
1114b725ae77Skettenis   }
1115b725ae77Skettenis trace_data;
1116b725ae77Skettenis 
1117b725ae77Skettenis static void
trace_command(char * args,int from_tty)1118b725ae77Skettenis trace_command (char *args, int from_tty)
1119b725ae77Skettenis {
1120b725ae77Skettenis   /* Clear the host-side trace buffer, allocating space if needed.  */
1121b725ae77Skettenis   trace_data.size = 0;
1122b725ae77Skettenis   if (trace_data.counts == NULL)
1123b725ae77Skettenis     trace_data.counts = XCALLOC (65536, short);
1124b725ae77Skettenis   if (trace_data.addrs == NULL)
1125b725ae77Skettenis     trace_data.addrs = XCALLOC (65536, CORE_ADDR);
1126b725ae77Skettenis 
1127b725ae77Skettenis   tracing = 1;
1128b725ae77Skettenis 
1129b725ae77Skettenis   printf_filtered ("Tracing is now on.\n");
1130b725ae77Skettenis }
1131b725ae77Skettenis 
1132b725ae77Skettenis static void
untrace_command(char * args,int from_tty)1133b725ae77Skettenis untrace_command (char *args, int from_tty)
1134b725ae77Skettenis {
1135b725ae77Skettenis   tracing = 0;
1136b725ae77Skettenis 
1137b725ae77Skettenis   printf_filtered ("Tracing is now off.\n");
1138b725ae77Skettenis }
1139b725ae77Skettenis 
1140b725ae77Skettenis static void
trace_info(char * args,int from_tty)1141b725ae77Skettenis trace_info (char *args, int from_tty)
1142b725ae77Skettenis {
1143b725ae77Skettenis   int i;
1144b725ae77Skettenis 
1145b725ae77Skettenis   if (trace_data.size)
1146b725ae77Skettenis     {
1147b725ae77Skettenis       printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
1148b725ae77Skettenis 
1149b725ae77Skettenis       for (i = 0; i < trace_data.size; ++i)
1150b725ae77Skettenis 	{
1151b725ae77Skettenis 	  printf_filtered ("%d: %d instruction%s at 0x%s\n",
1152b725ae77Skettenis 			   i,
1153b725ae77Skettenis 			   trace_data.counts[i],
1154b725ae77Skettenis 			   (trace_data.counts[i] == 1 ? "" : "s"),
1155b725ae77Skettenis 			   paddr_nz (trace_data.addrs[i]));
1156b725ae77Skettenis 	}
1157b725ae77Skettenis     }
1158b725ae77Skettenis   else
1159b725ae77Skettenis     printf_filtered ("No entries in trace buffer.\n");
1160b725ae77Skettenis 
1161b725ae77Skettenis   printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
1162b725ae77Skettenis }
1163b725ae77Skettenis 
1164b725ae77Skettenis static void
d10v_eva_prepare_to_trace(void)1165b725ae77Skettenis d10v_eva_prepare_to_trace (void)
1166b725ae77Skettenis {
1167b725ae77Skettenis   if (!tracing)
1168b725ae77Skettenis     return;
1169b725ae77Skettenis 
1170b725ae77Skettenis   last_pc = read_register (D10V_PC_REGNUM);
1171b725ae77Skettenis }
1172b725ae77Skettenis 
1173b725ae77Skettenis /* Collect trace data from the target board and format it into a form
1174b725ae77Skettenis    more useful for display.  */
1175b725ae77Skettenis 
1176b725ae77Skettenis static void
d10v_eva_get_trace_data(void)1177b725ae77Skettenis d10v_eva_get_trace_data (void)
1178b725ae77Skettenis {
1179b725ae77Skettenis   int count, i, j, oldsize;
1180b725ae77Skettenis   int trace_addr, trace_seg, trace_cnt, next_cnt;
1181b725ae77Skettenis   unsigned int last_trace, trace_word, next_word;
1182b725ae77Skettenis   unsigned int *tmpspace;
1183b725ae77Skettenis 
1184b725ae77Skettenis   if (!tracing)
1185b725ae77Skettenis     return;
1186b725ae77Skettenis 
1187b725ae77Skettenis   tmpspace = xmalloc (65536 * sizeof (unsigned int));
1188b725ae77Skettenis 
1189b725ae77Skettenis   last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
1190b725ae77Skettenis 
1191b725ae77Skettenis   /* Collect buffer contents from the target, stopping when we reach
1192b725ae77Skettenis      the word recorded when execution resumed.  */
1193b725ae77Skettenis 
1194b725ae77Skettenis   count = 0;
1195b725ae77Skettenis   while (last_trace > 0)
1196b725ae77Skettenis     {
1197b725ae77Skettenis       QUIT;
1198b725ae77Skettenis       trace_word =
1199b725ae77Skettenis 	read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
1200b725ae77Skettenis       trace_addr = trace_word & 0xffff;
1201b725ae77Skettenis       last_trace -= 4;
1202b725ae77Skettenis       /* Ignore an apparently nonsensical entry.  */
1203b725ae77Skettenis       if (trace_addr == 0xffd5)
1204b725ae77Skettenis 	continue;
1205b725ae77Skettenis       tmpspace[count++] = trace_word;
1206b725ae77Skettenis       if (trace_addr == last_pc)
1207b725ae77Skettenis 	break;
1208b725ae77Skettenis       if (count > 65535)
1209b725ae77Skettenis 	break;
1210b725ae77Skettenis     }
1211b725ae77Skettenis 
1212b725ae77Skettenis   /* Move the data to the host-side trace buffer, adjusting counts to
1213b725ae77Skettenis      include the last instruction executed and transforming the address
1214b725ae77Skettenis      into something that GDB likes.  */
1215b725ae77Skettenis 
1216b725ae77Skettenis   for (i = 0; i < count; ++i)
1217b725ae77Skettenis     {
1218b725ae77Skettenis       trace_word = tmpspace[i];
1219b725ae77Skettenis       next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
1220b725ae77Skettenis       trace_addr = trace_word & 0xffff;
1221b725ae77Skettenis       next_cnt = (next_word >> 24) & 0xff;
1222b725ae77Skettenis       j = trace_data.size + count - i - 1;
1223b725ae77Skettenis       trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
1224b725ae77Skettenis       trace_data.counts[j] = next_cnt + 1;
1225b725ae77Skettenis     }
1226b725ae77Skettenis 
1227b725ae77Skettenis   oldsize = trace_data.size;
1228b725ae77Skettenis   trace_data.size += count;
1229b725ae77Skettenis 
1230b725ae77Skettenis   xfree (tmpspace);
1231b725ae77Skettenis 
1232b725ae77Skettenis   if (trace_display)
1233b725ae77Skettenis     display_trace (oldsize, trace_data.size);
1234b725ae77Skettenis }
1235b725ae77Skettenis 
1236b725ae77Skettenis static void
tdisassemble_command(char * arg,int from_tty)1237b725ae77Skettenis tdisassemble_command (char *arg, int from_tty)
1238b725ae77Skettenis {
1239b725ae77Skettenis   int i, count;
1240b725ae77Skettenis   CORE_ADDR low, high;
1241b725ae77Skettenis 
1242b725ae77Skettenis   if (!arg)
1243b725ae77Skettenis     {
1244b725ae77Skettenis       low = 0;
1245b725ae77Skettenis       high = trace_data.size;
1246b725ae77Skettenis     }
1247b725ae77Skettenis   else
1248b725ae77Skettenis     {
1249b725ae77Skettenis       char *space_index = strchr (arg, ' ');
1250b725ae77Skettenis       if (space_index == NULL)
1251b725ae77Skettenis 	{
1252b725ae77Skettenis 	  low = parse_and_eval_address (arg);
1253b725ae77Skettenis 	  high = low + 5;
1254b725ae77Skettenis 	}
1255b725ae77Skettenis       else
1256b725ae77Skettenis 	{
1257b725ae77Skettenis 	  /* Two arguments.  */
1258b725ae77Skettenis 	  *space_index = '\0';
1259b725ae77Skettenis 	  low = parse_and_eval_address (arg);
1260b725ae77Skettenis 	  high = parse_and_eval_address (space_index + 1);
1261b725ae77Skettenis 	  if (high < low)
1262b725ae77Skettenis 	    high = low;
1263b725ae77Skettenis 	}
1264b725ae77Skettenis     }
1265b725ae77Skettenis 
1266b725ae77Skettenis   printf_filtered ("Dump of trace from %s to %s:\n",
1267b725ae77Skettenis 		   paddr_u (low), paddr_u (high));
1268b725ae77Skettenis 
1269b725ae77Skettenis   display_trace (low, high);
1270b725ae77Skettenis 
1271b725ae77Skettenis   printf_filtered ("End of trace dump.\n");
1272b725ae77Skettenis   gdb_flush (gdb_stdout);
1273b725ae77Skettenis }
1274b725ae77Skettenis 
1275b725ae77Skettenis static void
display_trace(int low,int high)1276b725ae77Skettenis display_trace (int low, int high)
1277b725ae77Skettenis {
1278b725ae77Skettenis   int i, count, trace_show_source, first, suppress;
1279b725ae77Skettenis   CORE_ADDR next_address;
1280b725ae77Skettenis 
1281b725ae77Skettenis   trace_show_source = default_trace_show_source;
1282b725ae77Skettenis   if (!have_full_symbols () && !have_partial_symbols ())
1283b725ae77Skettenis     {
1284b725ae77Skettenis       trace_show_source = 0;
1285b725ae77Skettenis       printf_filtered ("No symbol table is loaded.  Use the \"file\" command.\n");
1286b725ae77Skettenis       printf_filtered ("Trace will not display any source.\n");
1287b725ae77Skettenis     }
1288b725ae77Skettenis 
1289b725ae77Skettenis   first = 1;
1290b725ae77Skettenis   suppress = 0;
1291b725ae77Skettenis   for (i = low; i < high; ++i)
1292b725ae77Skettenis     {
1293b725ae77Skettenis       next_address = trace_data.addrs[i];
1294b725ae77Skettenis       count = trace_data.counts[i];
1295b725ae77Skettenis       while (count-- > 0)
1296b725ae77Skettenis 	{
1297b725ae77Skettenis 	  QUIT;
1298b725ae77Skettenis 	  if (trace_show_source)
1299b725ae77Skettenis 	    {
1300b725ae77Skettenis 	      struct symtab_and_line sal, sal_prev;
1301b725ae77Skettenis 
1302b725ae77Skettenis 	      sal_prev = find_pc_line (next_address - 4, 0);
1303b725ae77Skettenis 	      sal = find_pc_line (next_address, 0);
1304b725ae77Skettenis 
1305b725ae77Skettenis 	      if (sal.symtab)
1306b725ae77Skettenis 		{
1307b725ae77Skettenis 		  if (first || sal.line != sal_prev.line)
1308b725ae77Skettenis 		    print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
1309b725ae77Skettenis 		  suppress = 0;
1310b725ae77Skettenis 		}
1311b725ae77Skettenis 	      else
1312b725ae77Skettenis 		{
1313b725ae77Skettenis 		  if (!suppress)
1314b725ae77Skettenis 		    /* FIXME-32x64--assumes sal.pc fits in long.  */
1315b725ae77Skettenis 		    printf_filtered ("No source file for address %s.\n",
1316*11efff7fSkettenis 				     hex_string ((unsigned long) sal.pc));
1317b725ae77Skettenis 		  suppress = 1;
1318b725ae77Skettenis 		}
1319b725ae77Skettenis 	    }
1320b725ae77Skettenis 	  first = 0;
1321b725ae77Skettenis 	  print_address (next_address, gdb_stdout);
1322b725ae77Skettenis 	  printf_filtered (":");
1323b725ae77Skettenis 	  printf_filtered ("\t");
1324b725ae77Skettenis 	  wrap_here ("    ");
1325b725ae77Skettenis 	  next_address += gdb_print_insn (next_address, gdb_stdout);
1326b725ae77Skettenis 	  printf_filtered ("\n");
1327b725ae77Skettenis 	  gdb_flush (gdb_stdout);
1328b725ae77Skettenis 	}
1329b725ae77Skettenis     }
1330b725ae77Skettenis }
1331b725ae77Skettenis 
1332b725ae77Skettenis static CORE_ADDR
d10v_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)1333b725ae77Skettenis d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
1334b725ae77Skettenis {
1335b725ae77Skettenis   ULONGEST pc;
1336b725ae77Skettenis   frame_unwind_unsigned_register (next_frame, D10V_PC_REGNUM, &pc);
1337b725ae77Skettenis   return d10v_make_iaddr (pc);
1338b725ae77Skettenis }
1339b725ae77Skettenis 
1340b725ae77Skettenis /* Given a GDB frame, determine the address of the calling function's
1341b725ae77Skettenis    frame.  This will be used to create a new GDB frame struct.  */
1342b725ae77Skettenis 
1343b725ae77Skettenis static void
d10v_frame_this_id(struct frame_info * next_frame,void ** this_prologue_cache,struct frame_id * this_id)1344b725ae77Skettenis d10v_frame_this_id (struct frame_info *next_frame,
1345b725ae77Skettenis 		    void **this_prologue_cache,
1346b725ae77Skettenis 		    struct frame_id *this_id)
1347b725ae77Skettenis {
1348b725ae77Skettenis   struct d10v_unwind_cache *info
1349b725ae77Skettenis     = d10v_frame_unwind_cache (next_frame, this_prologue_cache);
1350b725ae77Skettenis   CORE_ADDR base;
1351b725ae77Skettenis   CORE_ADDR func;
1352b725ae77Skettenis   struct frame_id id;
1353b725ae77Skettenis 
1354b725ae77Skettenis   /* The FUNC is easy.  */
1355b725ae77Skettenis   func = frame_func_unwind (next_frame);
1356b725ae77Skettenis 
1357b725ae77Skettenis   /* Hopefully the prologue analysis either correctly determined the
1358b725ae77Skettenis      frame's base (which is the SP from the previous frame), or set
1359b725ae77Skettenis      that base to "NULL".  */
1360b725ae77Skettenis   base = info->prev_sp;
1361b725ae77Skettenis   if (base == STACK_START || base == 0)
1362b725ae77Skettenis     return;
1363b725ae77Skettenis 
1364b725ae77Skettenis   id = frame_id_build (base, func);
1365b725ae77Skettenis 
1366b725ae77Skettenis   (*this_id) = id;
1367b725ae77Skettenis }
1368b725ae77Skettenis 
1369b725ae77Skettenis static void
d10v_frame_prev_register(struct frame_info * next_frame,void ** this_prologue_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * bufferp)1370b725ae77Skettenis d10v_frame_prev_register (struct frame_info *next_frame,
1371b725ae77Skettenis 			  void **this_prologue_cache,
1372b725ae77Skettenis 			  int regnum, int *optimizedp,
1373b725ae77Skettenis 			  enum lval_type *lvalp, CORE_ADDR *addrp,
1374b725ae77Skettenis 			  int *realnump, void *bufferp)
1375b725ae77Skettenis {
1376b725ae77Skettenis   struct d10v_unwind_cache *info
1377b725ae77Skettenis     = d10v_frame_unwind_cache (next_frame, this_prologue_cache);
1378*11efff7fSkettenis   trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
1379b725ae77Skettenis 				optimizedp, lvalp, addrp, realnump, bufferp);
1380b725ae77Skettenis }
1381b725ae77Skettenis 
1382b725ae77Skettenis static const struct frame_unwind d10v_frame_unwind = {
1383b725ae77Skettenis   NORMAL_FRAME,
1384b725ae77Skettenis   d10v_frame_this_id,
1385b725ae77Skettenis   d10v_frame_prev_register
1386b725ae77Skettenis };
1387b725ae77Skettenis 
1388b725ae77Skettenis static const struct frame_unwind *
d10v_frame_sniffer(struct frame_info * next_frame)1389b725ae77Skettenis d10v_frame_sniffer (struct frame_info *next_frame)
1390b725ae77Skettenis {
1391b725ae77Skettenis   return &d10v_frame_unwind;
1392b725ae77Skettenis }
1393b725ae77Skettenis 
1394b725ae77Skettenis static CORE_ADDR
d10v_frame_base_address(struct frame_info * next_frame,void ** this_cache)1395b725ae77Skettenis d10v_frame_base_address (struct frame_info *next_frame, void **this_cache)
1396b725ae77Skettenis {
1397b725ae77Skettenis   struct d10v_unwind_cache *info
1398b725ae77Skettenis     = d10v_frame_unwind_cache (next_frame, this_cache);
1399b725ae77Skettenis   return info->base;
1400b725ae77Skettenis }
1401b725ae77Skettenis 
1402b725ae77Skettenis static const struct frame_base d10v_frame_base = {
1403b725ae77Skettenis   &d10v_frame_unwind,
1404b725ae77Skettenis   d10v_frame_base_address,
1405b725ae77Skettenis   d10v_frame_base_address,
1406b725ae77Skettenis   d10v_frame_base_address
1407b725ae77Skettenis };
1408b725ae77Skettenis 
1409b725ae77Skettenis /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
1410b725ae77Skettenis    dummy frame.  The frame ID's base needs to match the TOS value
1411b725ae77Skettenis    saved by save_dummy_frame_tos(), and the PC match the dummy frame's
1412b725ae77Skettenis    breakpoint.  */
1413b725ae77Skettenis 
1414b725ae77Skettenis static struct frame_id
d10v_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)1415b725ae77Skettenis d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
1416b725ae77Skettenis {
1417b725ae77Skettenis   return frame_id_build (d10v_unwind_sp (gdbarch, next_frame),
1418b725ae77Skettenis 			 frame_pc_unwind (next_frame));
1419b725ae77Skettenis }
1420b725ae77Skettenis 
1421b725ae77Skettenis static gdbarch_init_ftype d10v_gdbarch_init;
1422b725ae77Skettenis 
1423b725ae77Skettenis static struct gdbarch *
d10v_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)1424b725ae77Skettenis d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1425b725ae77Skettenis {
1426b725ae77Skettenis   struct gdbarch *gdbarch;
1427b725ae77Skettenis   int d10v_num_regs;
1428b725ae77Skettenis   struct gdbarch_tdep *tdep;
1429b725ae77Skettenis   gdbarch_register_name_ftype *d10v_register_name;
1430b725ae77Skettenis   gdbarch_register_sim_regno_ftype *d10v_register_sim_regno;
1431b725ae77Skettenis 
1432b725ae77Skettenis   /* Find a candidate among the list of pre-declared architectures.  */
1433b725ae77Skettenis   arches = gdbarch_list_lookup_by_info (arches, &info);
1434b725ae77Skettenis   if (arches != NULL)
1435b725ae77Skettenis     return arches->gdbarch;
1436b725ae77Skettenis 
1437b725ae77Skettenis   /* None found, create a new architecture from the information
1438b725ae77Skettenis      provided.  */
1439b725ae77Skettenis   tdep = XMALLOC (struct gdbarch_tdep);
1440b725ae77Skettenis   gdbarch = gdbarch_alloc (&info, tdep);
1441b725ae77Skettenis 
1442b725ae77Skettenis   switch (info.bfd_arch_info->mach)
1443b725ae77Skettenis     {
1444b725ae77Skettenis     case bfd_mach_d10v_ts2:
1445b725ae77Skettenis       d10v_num_regs = 37;
1446b725ae77Skettenis       d10v_register_name = d10v_ts2_register_name;
1447b725ae77Skettenis       d10v_register_sim_regno = d10v_ts2_register_sim_regno;
1448b725ae77Skettenis       tdep->a0_regnum = TS2_A0_REGNUM;
1449b725ae77Skettenis       tdep->nr_dmap_regs = TS2_NR_DMAP_REGS;
1450b725ae77Skettenis       tdep->dmap_register = d10v_ts2_dmap_register;
1451b725ae77Skettenis       tdep->imap_register = d10v_ts2_imap_register;
1452b725ae77Skettenis       break;
1453b725ae77Skettenis     default:
1454b725ae77Skettenis     case bfd_mach_d10v_ts3:
1455b725ae77Skettenis       d10v_num_regs = 42;
1456b725ae77Skettenis       d10v_register_name = d10v_ts3_register_name;
1457b725ae77Skettenis       d10v_register_sim_regno = d10v_ts3_register_sim_regno;
1458b725ae77Skettenis       tdep->a0_regnum = TS3_A0_REGNUM;
1459b725ae77Skettenis       tdep->nr_dmap_regs = TS3_NR_DMAP_REGS;
1460b725ae77Skettenis       tdep->dmap_register = d10v_ts3_dmap_register;
1461b725ae77Skettenis       tdep->imap_register = d10v_ts3_imap_register;
1462b725ae77Skettenis       break;
1463b725ae77Skettenis     }
1464b725ae77Skettenis 
1465b725ae77Skettenis   set_gdbarch_read_pc (gdbarch, d10v_read_pc);
1466b725ae77Skettenis   set_gdbarch_write_pc (gdbarch, d10v_write_pc);
1467b725ae77Skettenis   set_gdbarch_unwind_sp (gdbarch, d10v_unwind_sp);
1468b725ae77Skettenis 
1469b725ae77Skettenis   set_gdbarch_num_regs (gdbarch, d10v_num_regs);
1470b725ae77Skettenis   set_gdbarch_sp_regnum (gdbarch, D10V_SP_REGNUM);
1471b725ae77Skettenis   set_gdbarch_register_name (gdbarch, d10v_register_name);
1472b725ae77Skettenis   set_gdbarch_register_type (gdbarch, d10v_register_type);
1473b725ae77Skettenis 
1474b725ae77Skettenis   set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1475b725ae77Skettenis   set_gdbarch_addr_bit (gdbarch, 32);
1476b725ae77Skettenis   set_gdbarch_address_to_pointer (gdbarch, d10v_address_to_pointer);
1477b725ae77Skettenis   set_gdbarch_pointer_to_address (gdbarch, d10v_pointer_to_address);
1478b725ae77Skettenis   set_gdbarch_integer_to_address (gdbarch, d10v_integer_to_address);
1479b725ae77Skettenis   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1480b725ae77Skettenis   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1481b725ae77Skettenis   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1482b725ae77Skettenis   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1483b725ae77Skettenis   /* NOTE: The d10v as a 32 bit ``float'' and ``double''. ``long
1484b725ae77Skettenis      double'' is 64 bits.  */
1485b725ae77Skettenis   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1486b725ae77Skettenis   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1487b725ae77Skettenis   set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1488b725ae77Skettenis   switch (info.byte_order)
1489b725ae77Skettenis     {
1490b725ae77Skettenis     case BFD_ENDIAN_BIG:
1491b725ae77Skettenis       set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
1492b725ae77Skettenis       set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_big);
1493b725ae77Skettenis       set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
1494b725ae77Skettenis       break;
1495b725ae77Skettenis     case BFD_ENDIAN_LITTLE:
1496b725ae77Skettenis       set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
1497b725ae77Skettenis       set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
1498b725ae77Skettenis       set_gdbarch_long_double_format (gdbarch,
1499b725ae77Skettenis 				      &floatformat_ieee_double_little);
1500b725ae77Skettenis       break;
1501b725ae77Skettenis     default:
1502b725ae77Skettenis       internal_error (__FILE__, __LINE__,
1503b725ae77Skettenis 		      "d10v_gdbarch_init: bad byte order for float format");
1504b725ae77Skettenis     }
1505b725ae77Skettenis 
1506b725ae77Skettenis   set_gdbarch_return_value (gdbarch, d10v_return_value);
1507b725ae77Skettenis   set_gdbarch_push_dummy_code (gdbarch, d10v_push_dummy_code);
1508b725ae77Skettenis   set_gdbarch_push_dummy_call (gdbarch, d10v_push_dummy_call);
1509b725ae77Skettenis 
1510b725ae77Skettenis   set_gdbarch_skip_prologue (gdbarch, d10v_skip_prologue);
1511b725ae77Skettenis   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1512b725ae77Skettenis   set_gdbarch_decr_pc_after_break (gdbarch, 4);
1513b725ae77Skettenis   set_gdbarch_breakpoint_from_pc (gdbarch, d10v_breakpoint_from_pc);
1514b725ae77Skettenis 
1515b725ae77Skettenis   set_gdbarch_remote_translate_xfer_address (gdbarch,
1516b725ae77Skettenis 					     remote_d10v_translate_xfer_address);
1517b725ae77Skettenis 
1518b725ae77Skettenis   set_gdbarch_frame_align (gdbarch, d10v_frame_align);
1519b725ae77Skettenis 
1520b725ae77Skettenis   set_gdbarch_register_sim_regno (gdbarch, d10v_register_sim_regno);
1521b725ae77Skettenis 
1522b725ae77Skettenis   set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
1523b725ae77Skettenis 
1524b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, d10v_frame_sniffer);
1525b725ae77Skettenis   frame_base_set_default (gdbarch, &d10v_frame_base);
1526b725ae77Skettenis 
1527b725ae77Skettenis   /* Methods for saving / extracting a dummy frame's ID.  The ID's
1528b725ae77Skettenis      stack address must match the SP value returned by
1529b725ae77Skettenis      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
1530b725ae77Skettenis   set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
1531b725ae77Skettenis 
1532b725ae77Skettenis   /* Return the unwound PC value.  */
1533b725ae77Skettenis   set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc);
1534b725ae77Skettenis 
1535b725ae77Skettenis   set_gdbarch_print_insn (gdbarch, print_insn_d10v);
1536b725ae77Skettenis 
1537b725ae77Skettenis   return gdbarch;
1538b725ae77Skettenis }
1539b725ae77Skettenis 
1540b725ae77Skettenis void
_initialize_d10v_tdep(void)1541b725ae77Skettenis _initialize_d10v_tdep (void)
1542b725ae77Skettenis {
1543b725ae77Skettenis   register_gdbarch_init (bfd_arch_d10v, d10v_gdbarch_init);
1544b725ae77Skettenis 
1545*11efff7fSkettenis   deprecated_target_resume_hook = d10v_eva_prepare_to_trace;
1546*11efff7fSkettenis   deprecated_target_wait_loop_hook = d10v_eva_get_trace_data;
1547b725ae77Skettenis 
1548b725ae77Skettenis   deprecate_cmd (add_com ("regs", class_vars, show_regs,
1549b725ae77Skettenis 			  "Print all registers"),
1550b725ae77Skettenis 		 "info registers");
1551b725ae77Skettenis 
1552b725ae77Skettenis   add_com ("itrace", class_support, trace_command,
1553b725ae77Skettenis 	   "Enable tracing of instruction execution.");
1554b725ae77Skettenis 
1555b725ae77Skettenis   add_com ("iuntrace", class_support, untrace_command,
1556b725ae77Skettenis 	   "Disable tracing of instruction execution.");
1557b725ae77Skettenis 
1558b725ae77Skettenis   add_com ("itdisassemble", class_vars, tdisassemble_command,
1559b725ae77Skettenis 	   "Disassemble the trace buffer.\n\
1560b725ae77Skettenis Two optional arguments specify a range of trace buffer entries\n\
1561b725ae77Skettenis as reported by info trace (NOT addresses!).");
1562b725ae77Skettenis 
1563b725ae77Skettenis   add_info ("itrace", trace_info,
1564b725ae77Skettenis 	    "Display info about the trace data buffer.");
1565b725ae77Skettenis 
1566*11efff7fSkettenis   add_setshow_boolean_cmd ("itracedisplay", no_class, &trace_display, "\
1567*11efff7fSkettenis Set automatic display of trace.", "\
1568*11efff7fSkettenis Show automatic display of trace.", "\
1569*11efff7fSkettenis Controls the display of d10v specific instruction trace information.", "\
1570*11efff7fSkettenis Automatic display of trace is %s.",
1571b725ae77Skettenis 			   NULL, NULL, &setlist, &showlist);
1572b725ae77Skettenis   add_setshow_boolean_cmd ("itracesource", no_class,
1573*11efff7fSkettenis 			   &default_trace_show_source, "\
1574*11efff7fSkettenis Set display of source code with trace.", "\
1575*11efff7fSkettenis Show display of source code with trace.", "\
1576*11efff7fSkettenis When on source code is included in the d10v instruction trace display.", "\
1577*11efff7fSkettenis Display of source code with trace is %s.",
1578b725ae77Skettenis 			   NULL, NULL, &setlist, &showlist);
1579b725ae77Skettenis }
1580