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, ®);
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, ®);
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, ®);
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, ®);
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 ®val);
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