1b725ae77Skettenis /* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
4b725ae77Skettenis Software Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "inferior.h"
26b725ae77Skettenis #include "target.h"
27b725ae77Skettenis #include "value.h"
28b725ae77Skettenis #include "bfd.h"
29b725ae77Skettenis #include "gdb_string.h"
30b725ae77Skettenis #include "gdbcore.h"
31b725ae77Skettenis #include "objfiles.h"
32b725ae77Skettenis #include "arch-utils.h"
33b725ae77Skettenis #include "regcache.h"
34b725ae77Skettenis #include "symtab.h"
35b725ae77Skettenis #include "dis-asm.h"
36b725ae77Skettenis
37b725ae77Skettenis struct gdbarch_tdep
38b725ae77Skettenis {
39b725ae77Skettenis /* gdbarch target dependent data here. Currently unused for v850. */
40b725ae77Skettenis };
41b725ae77Skettenis
42b725ae77Skettenis /* Extra info which is saved in each frame_info. */
43b725ae77Skettenis struct frame_extra_info
44b725ae77Skettenis {
45b725ae77Skettenis };
46b725ae77Skettenis
47b725ae77Skettenis enum {
48b725ae77Skettenis E_R0_REGNUM,
49b725ae77Skettenis E_R1_REGNUM,
50b725ae77Skettenis E_R2_REGNUM, E_SAVE1_START_REGNUM = E_R2_REGNUM, E_SAVE1_END_REGNUM = E_R2_REGNUM,
51b725ae77Skettenis E_R3_REGNUM, E_SP_REGNUM = E_R3_REGNUM,
52b725ae77Skettenis E_R4_REGNUM,
53b725ae77Skettenis E_R5_REGNUM,
54b725ae77Skettenis E_R6_REGNUM, E_ARG0_REGNUM = E_R6_REGNUM,
55b725ae77Skettenis E_R7_REGNUM,
56b725ae77Skettenis E_R8_REGNUM,
57b725ae77Skettenis E_R9_REGNUM, E_ARGLAST_REGNUM = E_R9_REGNUM,
58b725ae77Skettenis E_R10_REGNUM, E_V0_REGNUM = E_R10_REGNUM,
59b725ae77Skettenis E_R11_REGNUM, E_V1_REGNUM = E_R11_REGNUM,
60b725ae77Skettenis E_R12_REGNUM,
61b725ae77Skettenis E_R13_REGNUM,
62b725ae77Skettenis E_R14_REGNUM,
63b725ae77Skettenis E_R15_REGNUM,
64b725ae77Skettenis E_R16_REGNUM,
65b725ae77Skettenis E_R17_REGNUM,
66b725ae77Skettenis E_R18_REGNUM,
67b725ae77Skettenis E_R19_REGNUM,
68b725ae77Skettenis E_R20_REGNUM, E_SAVE2_START_REGNUM = E_R20_REGNUM,
69b725ae77Skettenis E_R21_REGNUM,
70b725ae77Skettenis E_R22_REGNUM,
71b725ae77Skettenis E_R23_REGNUM,
72b725ae77Skettenis E_R24_REGNUM,
73b725ae77Skettenis E_R25_REGNUM,
74b725ae77Skettenis E_R26_REGNUM,
75b725ae77Skettenis E_R27_REGNUM,
76b725ae77Skettenis E_R28_REGNUM,
77b725ae77Skettenis E_R29_REGNUM, E_SAVE2_END_REGNUM = E_R29_REGNUM, E_FP_RAW_REGNUM = E_R29_REGNUM,
78b725ae77Skettenis E_R30_REGNUM, E_EP_REGNUM = E_R30_REGNUM,
79b725ae77Skettenis E_R31_REGNUM, E_SAVE3_START_REGNUM = E_R31_REGNUM, E_SAVE3_END_REGNUM = E_R31_REGNUM, E_RP_REGNUM = E_R31_REGNUM,
80b725ae77Skettenis E_R32_REGNUM, E_SR0_REGNUM = E_R32_REGNUM,
81b725ae77Skettenis E_R33_REGNUM,
82b725ae77Skettenis E_R34_REGNUM,
83b725ae77Skettenis E_R35_REGNUM,
84b725ae77Skettenis E_R36_REGNUM,
85b725ae77Skettenis E_R37_REGNUM, E_PS_REGNUM = E_R37_REGNUM,
86b725ae77Skettenis E_R38_REGNUM,
87b725ae77Skettenis E_R39_REGNUM,
88b725ae77Skettenis E_R40_REGNUM,
89b725ae77Skettenis E_R41_REGNUM,
90b725ae77Skettenis E_R42_REGNUM,
91b725ae77Skettenis E_R43_REGNUM,
92b725ae77Skettenis E_R44_REGNUM,
93b725ae77Skettenis E_R45_REGNUM,
94b725ae77Skettenis E_R46_REGNUM,
95b725ae77Skettenis E_R47_REGNUM,
96b725ae77Skettenis E_R48_REGNUM,
97b725ae77Skettenis E_R49_REGNUM,
98b725ae77Skettenis E_R50_REGNUM,
99b725ae77Skettenis E_R51_REGNUM,
100b725ae77Skettenis E_R52_REGNUM, E_CTBP_REGNUM = E_R52_REGNUM,
101b725ae77Skettenis E_R53_REGNUM,
102b725ae77Skettenis E_R54_REGNUM,
103b725ae77Skettenis E_R55_REGNUM,
104b725ae77Skettenis E_R56_REGNUM,
105b725ae77Skettenis E_R57_REGNUM,
106b725ae77Skettenis E_R58_REGNUM,
107b725ae77Skettenis E_R59_REGNUM,
108b725ae77Skettenis E_R60_REGNUM,
109b725ae77Skettenis E_R61_REGNUM,
110b725ae77Skettenis E_R62_REGNUM,
111b725ae77Skettenis E_R63_REGNUM,
112b725ae77Skettenis E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
113b725ae77Skettenis E_R65_REGNUM, E_FP_REGNUM = E_R65_REGNUM,
114b725ae77Skettenis E_NUM_REGS
115b725ae77Skettenis };
116b725ae77Skettenis
117b725ae77Skettenis enum
118b725ae77Skettenis {
119b725ae77Skettenis v850_reg_size = 4
120b725ae77Skettenis };
121b725ae77Skettenis
122b725ae77Skettenis /* Size of all registers as a whole. */
123b725ae77Skettenis enum
124b725ae77Skettenis {
125b725ae77Skettenis E_ALL_REGS_SIZE = (E_NUM_REGS) * v850_reg_size
126b725ae77Skettenis };
127b725ae77Skettenis
128b725ae77Skettenis /* Size of return datatype which fits into all return registers. */
129b725ae77Skettenis enum
130b725ae77Skettenis {
131b725ae77Skettenis E_MAX_RETTYPE_SIZE_IN_REGS = 2 * v850_reg_size
132b725ae77Skettenis };
133b725ae77Skettenis
134b725ae77Skettenis static LONGEST call_dummy_nil[] = {0};
135b725ae77Skettenis
136b725ae77Skettenis static char *v850_generic_reg_names[] =
137b725ae77Skettenis { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
138b725ae77Skettenis "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
139b725ae77Skettenis "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
140b725ae77Skettenis "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
141b725ae77Skettenis "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
142b725ae77Skettenis "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
143b725ae77Skettenis "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
144b725ae77Skettenis "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
145b725ae77Skettenis "pc", "fp"
146b725ae77Skettenis };
147b725ae77Skettenis
148b725ae77Skettenis static char *v850e_reg_names[] =
149b725ae77Skettenis {
150b725ae77Skettenis "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
151b725ae77Skettenis "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
152b725ae77Skettenis "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
153b725ae77Skettenis "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
154b725ae77Skettenis "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
155b725ae77Skettenis "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
156b725ae77Skettenis "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
157b725ae77Skettenis "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
158b725ae77Skettenis "pc", "fp"
159b725ae77Skettenis };
160b725ae77Skettenis
161b725ae77Skettenis char **v850_register_names = v850_generic_reg_names;
162b725ae77Skettenis
163b725ae77Skettenis struct
164b725ae77Skettenis {
165b725ae77Skettenis char **regnames;
166b725ae77Skettenis int mach;
167b725ae77Skettenis }
168b725ae77Skettenis v850_processor_type_table[] =
169b725ae77Skettenis {
170b725ae77Skettenis {
171b725ae77Skettenis v850_generic_reg_names, bfd_mach_v850
172b725ae77Skettenis }
173b725ae77Skettenis ,
174b725ae77Skettenis {
175b725ae77Skettenis v850e_reg_names, bfd_mach_v850e
176b725ae77Skettenis }
177b725ae77Skettenis ,
178b725ae77Skettenis {
179b725ae77Skettenis v850e_reg_names, bfd_mach_v850e1
180b725ae77Skettenis }
181b725ae77Skettenis ,
182b725ae77Skettenis {
183b725ae77Skettenis NULL, 0
184b725ae77Skettenis }
185b725ae77Skettenis };
186b725ae77Skettenis
187b725ae77Skettenis /* Info gleaned from scanning a function's prologue. */
188b725ae77Skettenis
189b725ae77Skettenis struct pifsr /* Info about one saved reg */
190b725ae77Skettenis {
191b725ae77Skettenis int framereg; /* Frame reg (SP or FP) */
192b725ae77Skettenis int offset; /* Offset from framereg */
193b725ae77Skettenis int cur_frameoffset; /* Current frameoffset */
194b725ae77Skettenis int reg; /* Saved register number */
195b725ae77Skettenis };
196b725ae77Skettenis
197b725ae77Skettenis struct prologue_info
198b725ae77Skettenis {
199b725ae77Skettenis int framereg;
200b725ae77Skettenis int frameoffset;
201b725ae77Skettenis int start_function;
202b725ae77Skettenis struct pifsr *pifsrs;
203b725ae77Skettenis };
204b725ae77Skettenis
205b725ae77Skettenis static CORE_ADDR v850_scan_prologue (CORE_ADDR pc, struct prologue_info *fs);
206b725ae77Skettenis
207b725ae77Skettenis /* Function: v850_register_name
208b725ae77Skettenis Returns the name of the v850/v850e register N. */
209b725ae77Skettenis
210b725ae77Skettenis static const char *
v850_register_name(int regnum)211b725ae77Skettenis v850_register_name (int regnum)
212b725ae77Skettenis {
213b725ae77Skettenis if (regnum < 0 || regnum >= E_NUM_REGS)
214b725ae77Skettenis internal_error (__FILE__, __LINE__,
215b725ae77Skettenis "v850_register_name: illegal register number %d",
216b725ae77Skettenis regnum);
217b725ae77Skettenis else
218b725ae77Skettenis return v850_register_names[regnum];
219b725ae77Skettenis
220b725ae77Skettenis }
221b725ae77Skettenis
222b725ae77Skettenis /* Function: v850_register_byte
223b725ae77Skettenis Returns the byte position in the register cache for register N. */
224b725ae77Skettenis
225b725ae77Skettenis static int
v850_register_byte(int regnum)226b725ae77Skettenis v850_register_byte (int regnum)
227b725ae77Skettenis {
228b725ae77Skettenis if (regnum < 0 || regnum >= E_NUM_REGS)
229b725ae77Skettenis internal_error (__FILE__, __LINE__,
230b725ae77Skettenis "v850_register_byte: illegal register number %d",
231b725ae77Skettenis regnum);
232b725ae77Skettenis else
233b725ae77Skettenis return regnum * v850_reg_size;
234b725ae77Skettenis }
235b725ae77Skettenis
236b725ae77Skettenis /* Function: v850_register_raw_size
237b725ae77Skettenis Returns the number of bytes occupied by the register on the target. */
238b725ae77Skettenis
239b725ae77Skettenis static int
v850_register_raw_size(int regnum)240b725ae77Skettenis v850_register_raw_size (int regnum)
241b725ae77Skettenis {
242b725ae77Skettenis if (regnum < 0 || regnum >= E_NUM_REGS)
243b725ae77Skettenis internal_error (__FILE__, __LINE__,
244b725ae77Skettenis "v850_register_raw_size: illegal register number %d",
245b725ae77Skettenis regnum);
246b725ae77Skettenis /* Only the PC has 4 Byte, all other registers 2 Byte. */
247b725ae77Skettenis else
248b725ae77Skettenis return v850_reg_size;
249b725ae77Skettenis }
250b725ae77Skettenis
251b725ae77Skettenis /* Function: v850_reg_virtual_type
252b725ae77Skettenis Returns the default type for register N. */
253b725ae77Skettenis
254b725ae77Skettenis static struct type *
v850_reg_virtual_type(int regnum)255b725ae77Skettenis v850_reg_virtual_type (int regnum)
256b725ae77Skettenis {
257b725ae77Skettenis if (regnum < 0 || regnum >= E_NUM_REGS)
258b725ae77Skettenis internal_error (__FILE__, __LINE__,
259b725ae77Skettenis "v850_register_virtual_type: illegal register number %d",
260b725ae77Skettenis regnum);
261b725ae77Skettenis else if (regnum == E_PC_REGNUM)
262b725ae77Skettenis return builtin_type_uint32;
263b725ae77Skettenis else
264b725ae77Skettenis return builtin_type_int32;
265b725ae77Skettenis }
266b725ae77Skettenis
267b725ae77Skettenis static int
v850_type_is_scalar(struct type * t)268b725ae77Skettenis v850_type_is_scalar (struct type *t)
269b725ae77Skettenis {
270b725ae77Skettenis return (TYPE_CODE (t) != TYPE_CODE_STRUCT
271b725ae77Skettenis && TYPE_CODE (t) != TYPE_CODE_UNION
272b725ae77Skettenis && TYPE_CODE (t) != TYPE_CODE_ARRAY);
273b725ae77Skettenis }
274b725ae77Skettenis
275b725ae77Skettenis /* Should call_function allocate stack space for a struct return? */
276b725ae77Skettenis static int
v850_use_struct_convention(int gcc_p,struct type * type)277b725ae77Skettenis v850_use_struct_convention (int gcc_p, struct type *type)
278b725ae77Skettenis {
279b725ae77Skettenis /* According to ABI:
280b725ae77Skettenis * return TYPE_LENGTH (type) > 8);
281b725ae77Skettenis */
282b725ae77Skettenis
283b725ae77Skettenis /* Current implementation in gcc: */
284b725ae77Skettenis
285b725ae77Skettenis int i;
286b725ae77Skettenis struct type *fld_type, *tgt_type;
287b725ae77Skettenis
288b725ae77Skettenis /* 1. The value is greater than 8 bytes -> returned by copying */
289b725ae77Skettenis if (TYPE_LENGTH (type) > 8)
290b725ae77Skettenis return 1;
291b725ae77Skettenis
292b725ae77Skettenis /* 2. The value is a single basic type -> returned in register */
293b725ae77Skettenis if (v850_type_is_scalar (type))
294b725ae77Skettenis return 0;
295b725ae77Skettenis
296b725ae77Skettenis /* The value is a structure or union with a single element
297b725ae77Skettenis * and that element is either a single basic type or an array of
298b725ae77Skettenis * a single basic type whoes size is greater than or equal to 4
299b725ae77Skettenis * -> returned in register */
300b725ae77Skettenis if ((TYPE_CODE (type) == TYPE_CODE_STRUCT
301b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_UNION)
302b725ae77Skettenis && TYPE_NFIELDS (type) == 1)
303b725ae77Skettenis {
304b725ae77Skettenis fld_type = TYPE_FIELD_TYPE (type, 0);
305b725ae77Skettenis if (v850_type_is_scalar (fld_type) && TYPE_LENGTH (fld_type) >= 4)
306b725ae77Skettenis return 0;
307b725ae77Skettenis
308b725ae77Skettenis if (TYPE_CODE (fld_type) == TYPE_CODE_ARRAY)
309b725ae77Skettenis {
310b725ae77Skettenis tgt_type = TYPE_TARGET_TYPE (fld_type);
311b725ae77Skettenis if (v850_type_is_scalar (tgt_type) && TYPE_LENGTH (tgt_type) >= 4)
312b725ae77Skettenis return 0;
313b725ae77Skettenis }
314b725ae77Skettenis }
315b725ae77Skettenis
316b725ae77Skettenis /* The value is a structure whose first element is an integer or
317b725ae77Skettenis * a float, and which contains no arrays of more than two elements
318b725ae77Skettenis * -> returned in register */
319b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_STRUCT
320b725ae77Skettenis && v850_type_is_scalar (TYPE_FIELD_TYPE (type, 0))
321b725ae77Skettenis && TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == 4)
322b725ae77Skettenis {
323b725ae77Skettenis for (i = 1; i < TYPE_NFIELDS (type); ++i)
324b725ae77Skettenis {
325b725ae77Skettenis fld_type = TYPE_FIELD_TYPE (type, 0);
326b725ae77Skettenis if (TYPE_CODE (fld_type) == TYPE_CODE_ARRAY)
327b725ae77Skettenis {
328b725ae77Skettenis tgt_type = TYPE_TARGET_TYPE (fld_type);
329b725ae77Skettenis if (TYPE_LENGTH (fld_type) >= 0 && TYPE_LENGTH (tgt_type) >= 0
330b725ae77Skettenis && TYPE_LENGTH (fld_type) / TYPE_LENGTH (tgt_type) > 2)
331b725ae77Skettenis return 1;
332b725ae77Skettenis }
333b725ae77Skettenis }
334b725ae77Skettenis return 0;
335b725ae77Skettenis }
336b725ae77Skettenis
337b725ae77Skettenis /* The value is a union which contains at least one field which
338b725ae77Skettenis * would be returned in registers according to these rules
339b725ae77Skettenis * -> returned in register */
340b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_UNION)
341b725ae77Skettenis {
342b725ae77Skettenis for (i = 0; i < TYPE_NFIELDS (type); ++i)
343b725ae77Skettenis {
344b725ae77Skettenis fld_type = TYPE_FIELD_TYPE (type, 0);
345b725ae77Skettenis if (!v850_use_struct_convention (0, fld_type))
346b725ae77Skettenis return 0;
347b725ae77Skettenis }
348b725ae77Skettenis }
349b725ae77Skettenis
350b725ae77Skettenis return 1;
351b725ae77Skettenis }
352b725ae77Skettenis
353b725ae77Skettenis
354b725ae77Skettenis
355b725ae77Skettenis /* Structure for mapping bits in register lists to register numbers. */
356b725ae77Skettenis struct reg_list
357b725ae77Skettenis {
358b725ae77Skettenis long mask;
359b725ae77Skettenis int regno;
360b725ae77Skettenis };
361b725ae77Skettenis
362b725ae77Skettenis /* Helper function for v850_scan_prologue to handle prepare instruction. */
363b725ae77Skettenis
364b725ae77Skettenis static void
handle_prepare(int insn,int insn2,CORE_ADDR * current_pc_ptr,struct prologue_info * pi,struct pifsr ** pifsr_ptr)365b725ae77Skettenis handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr,
366b725ae77Skettenis struct prologue_info *pi, struct pifsr **pifsr_ptr)
367b725ae77Skettenis {
368b725ae77Skettenis CORE_ADDR current_pc = *current_pc_ptr;
369b725ae77Skettenis struct pifsr *pifsr = *pifsr_ptr;
370b725ae77Skettenis long next = insn2 & 0xffff;
371b725ae77Skettenis long list12 = ((insn & 1) << 16) + (next & 0xffe0);
372b725ae77Skettenis long offset = (insn & 0x3e) << 1;
373b725ae77Skettenis static struct reg_list reg_table[] =
374b725ae77Skettenis {
375b725ae77Skettenis {0x00800, 20}, /* r20 */
376b725ae77Skettenis {0x00400, 21}, /* r21 */
377b725ae77Skettenis {0x00200, 22}, /* r22 */
378b725ae77Skettenis {0x00100, 23}, /* r23 */
379b725ae77Skettenis {0x08000, 24}, /* r24 */
380b725ae77Skettenis {0x04000, 25}, /* r25 */
381b725ae77Skettenis {0x02000, 26}, /* r26 */
382b725ae77Skettenis {0x01000, 27}, /* r27 */
383b725ae77Skettenis {0x00080, 28}, /* r28 */
384b725ae77Skettenis {0x00040, 29}, /* r29 */
385b725ae77Skettenis {0x10000, 30}, /* ep */
386b725ae77Skettenis {0x00020, 31}, /* lp */
387b725ae77Skettenis {0, 0} /* end of table */
388b725ae77Skettenis };
389b725ae77Skettenis int i;
390b725ae77Skettenis
391b725ae77Skettenis if ((next & 0x1f) == 0x0b) /* skip imm16 argument */
392b725ae77Skettenis current_pc += 2;
393b725ae77Skettenis else if ((next & 0x1f) == 0x13) /* skip imm16 argument */
394b725ae77Skettenis current_pc += 2;
395b725ae77Skettenis else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */
396b725ae77Skettenis current_pc += 4;
397b725ae77Skettenis
398b725ae77Skettenis /* Calculate the total size of the saved registers, and add it
399b725ae77Skettenis it to the immediate value used to adjust SP. */
400b725ae77Skettenis for (i = 0; reg_table[i].mask != 0; i++)
401b725ae77Skettenis if (list12 & reg_table[i].mask)
402b725ae77Skettenis offset += v850_register_raw_size (reg_table[i].regno);
403b725ae77Skettenis pi->frameoffset -= offset;
404b725ae77Skettenis
405b725ae77Skettenis /* Calculate the offsets of the registers relative to the value
406b725ae77Skettenis the SP will have after the registers have been pushed and the
407b725ae77Skettenis imm5 value has been subtracted from it. */
408b725ae77Skettenis if (pifsr)
409b725ae77Skettenis {
410b725ae77Skettenis for (i = 0; reg_table[i].mask != 0; i++)
411b725ae77Skettenis {
412b725ae77Skettenis if (list12 & reg_table[i].mask)
413b725ae77Skettenis {
414b725ae77Skettenis int reg = reg_table[i].regno;
415b725ae77Skettenis offset -= v850_register_raw_size (reg);
416b725ae77Skettenis pifsr->reg = reg;
417b725ae77Skettenis pifsr->offset = offset;
418b725ae77Skettenis pifsr->cur_frameoffset = pi->frameoffset;
419b725ae77Skettenis #ifdef DEBUG
420b725ae77Skettenis printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
421b725ae77Skettenis #endif
422b725ae77Skettenis pifsr++;
423b725ae77Skettenis }
424b725ae77Skettenis }
425b725ae77Skettenis }
426b725ae77Skettenis #ifdef DEBUG
427b725ae77Skettenis printf_filtered ("\tfound ctret after regsave func");
428b725ae77Skettenis #endif
429b725ae77Skettenis
430b725ae77Skettenis /* Set result parameters. */
431b725ae77Skettenis *current_pc_ptr = current_pc;
432b725ae77Skettenis *pifsr_ptr = pifsr;
433b725ae77Skettenis }
434b725ae77Skettenis
435b725ae77Skettenis
436b725ae77Skettenis /* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
437b725ae77Skettenis FIXME: the SR bit of the register list is not supported; must check
438b725ae77Skettenis that the compiler does not ever generate this bit. */
439b725ae77Skettenis
440b725ae77Skettenis static void
handle_pushm(int insn,int insn2,struct prologue_info * pi,struct pifsr ** pifsr_ptr)441b725ae77Skettenis handle_pushm (int insn, int insn2, struct prologue_info *pi,
442b725ae77Skettenis struct pifsr **pifsr_ptr)
443b725ae77Skettenis {
444b725ae77Skettenis struct pifsr *pifsr = *pifsr_ptr;
445b725ae77Skettenis long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
446b725ae77Skettenis long offset = 0;
447b725ae77Skettenis static struct reg_list pushml_reg_table[] =
448b725ae77Skettenis {
449b725ae77Skettenis {0x80000, E_PS_REGNUM}, /* PSW */
450b725ae77Skettenis {0x40000, 1}, /* r1 */
451b725ae77Skettenis {0x20000, 2}, /* r2 */
452b725ae77Skettenis {0x10000, 3}, /* r3 */
453b725ae77Skettenis {0x00800, 4}, /* r4 */
454b725ae77Skettenis {0x00400, 5}, /* r5 */
455b725ae77Skettenis {0x00200, 6}, /* r6 */
456b725ae77Skettenis {0x00100, 7}, /* r7 */
457b725ae77Skettenis {0x08000, 8}, /* r8 */
458b725ae77Skettenis {0x04000, 9}, /* r9 */
459b725ae77Skettenis {0x02000, 10}, /* r10 */
460b725ae77Skettenis {0x01000, 11}, /* r11 */
461b725ae77Skettenis {0x00080, 12}, /* r12 */
462b725ae77Skettenis {0x00040, 13}, /* r13 */
463b725ae77Skettenis {0x00020, 14}, /* r14 */
464b725ae77Skettenis {0x00010, 15}, /* r15 */
465b725ae77Skettenis {0, 0} /* end of table */
466b725ae77Skettenis };
467b725ae77Skettenis static struct reg_list pushmh_reg_table[] =
468b725ae77Skettenis {
469b725ae77Skettenis {0x80000, 16}, /* r16 */
470b725ae77Skettenis {0x40000, 17}, /* r17 */
471b725ae77Skettenis {0x20000, 18}, /* r18 */
472b725ae77Skettenis {0x10000, 19}, /* r19 */
473b725ae77Skettenis {0x00800, 20}, /* r20 */
474b725ae77Skettenis {0x00400, 21}, /* r21 */
475b725ae77Skettenis {0x00200, 22}, /* r22 */
476b725ae77Skettenis {0x00100, 23}, /* r23 */
477b725ae77Skettenis {0x08000, 24}, /* r24 */
478b725ae77Skettenis {0x04000, 25}, /* r25 */
479b725ae77Skettenis {0x02000, 26}, /* r26 */
480b725ae77Skettenis {0x01000, 27}, /* r27 */
481b725ae77Skettenis {0x00080, 28}, /* r28 */
482b725ae77Skettenis {0x00040, 29}, /* r29 */
483b725ae77Skettenis {0x00010, 30}, /* r30 */
484b725ae77Skettenis {0x00020, 31}, /* r31 */
485b725ae77Skettenis {0, 0} /* end of table */
486b725ae77Skettenis };
487b725ae77Skettenis struct reg_list *reg_table;
488b725ae77Skettenis int i;
489b725ae77Skettenis
490b725ae77Skettenis /* Is this a pushml or a pushmh? */
491b725ae77Skettenis if ((insn2 & 7) == 1)
492b725ae77Skettenis reg_table = pushml_reg_table;
493b725ae77Skettenis else
494b725ae77Skettenis reg_table = pushmh_reg_table;
495b725ae77Skettenis
496b725ae77Skettenis /* Calculate the total size of the saved registers, and add it
497b725ae77Skettenis it to the immediate value used to adjust SP. */
498b725ae77Skettenis for (i = 0; reg_table[i].mask != 0; i++)
499b725ae77Skettenis if (list12 & reg_table[i].mask)
500b725ae77Skettenis offset += v850_register_raw_size (reg_table[i].regno);
501b725ae77Skettenis pi->frameoffset -= offset;
502b725ae77Skettenis
503b725ae77Skettenis /* Calculate the offsets of the registers relative to the value
504b725ae77Skettenis the SP will have after the registers have been pushed and the
505b725ae77Skettenis imm5 value is subtracted from it. */
506b725ae77Skettenis if (pifsr)
507b725ae77Skettenis {
508b725ae77Skettenis for (i = 0; reg_table[i].mask != 0; i++)
509b725ae77Skettenis {
510b725ae77Skettenis if (list12 & reg_table[i].mask)
511b725ae77Skettenis {
512b725ae77Skettenis int reg = reg_table[i].regno;
513b725ae77Skettenis offset -= v850_register_raw_size (reg);
514b725ae77Skettenis pifsr->reg = reg;
515b725ae77Skettenis pifsr->offset = offset;
516b725ae77Skettenis pifsr->cur_frameoffset = pi->frameoffset;
517b725ae77Skettenis #ifdef DEBUG
518b725ae77Skettenis printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
519b725ae77Skettenis #endif
520b725ae77Skettenis pifsr++;
521b725ae77Skettenis }
522b725ae77Skettenis }
523b725ae77Skettenis }
524b725ae77Skettenis #ifdef DEBUG
525b725ae77Skettenis printf_filtered ("\tfound ctret after regsave func");
526b725ae77Skettenis #endif
527b725ae77Skettenis
528b725ae77Skettenis /* Set result parameters. */
529b725ae77Skettenis *pifsr_ptr = pifsr;
530b725ae77Skettenis }
531b725ae77Skettenis
532b725ae77Skettenis
533b725ae77Skettenis
534b725ae77Skettenis
535b725ae77Skettenis /* Function: scan_prologue
536b725ae77Skettenis Scan the prologue of the function that contains PC, and record what
537b725ae77Skettenis we find in PI. Returns the pc after the prologue. Note that the
538b725ae77Skettenis addresses saved in frame->saved_regs are just frame relative (negative
539b725ae77Skettenis offsets from the frame pointer). This is because we don't know the
540b725ae77Skettenis actual value of the frame pointer yet. In some circumstances, the
541b725ae77Skettenis frame pointer can't be determined till after we have scanned the
542b725ae77Skettenis prologue. */
543b725ae77Skettenis
544b725ae77Skettenis static CORE_ADDR
v850_scan_prologue(CORE_ADDR pc,struct prologue_info * pi)545b725ae77Skettenis v850_scan_prologue (CORE_ADDR pc, struct prologue_info *pi)
546b725ae77Skettenis {
547b725ae77Skettenis CORE_ADDR func_addr, prologue_end, current_pc;
548b725ae77Skettenis struct pifsr *pifsr, *pifsr_tmp;
549b725ae77Skettenis int fp_used;
550b725ae77Skettenis int ep_used;
551b725ae77Skettenis int reg;
552b725ae77Skettenis CORE_ADDR save_pc, save_end;
553b725ae77Skettenis int regsave_func_p;
554b725ae77Skettenis int r12_tmp;
555b725ae77Skettenis
556b725ae77Skettenis /* First, figure out the bounds of the prologue so that we can limit the
557b725ae77Skettenis search to something reasonable. */
558b725ae77Skettenis
559b725ae77Skettenis if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
560b725ae77Skettenis {
561b725ae77Skettenis struct symtab_and_line sal;
562b725ae77Skettenis
563b725ae77Skettenis sal = find_pc_line (func_addr, 0);
564b725ae77Skettenis
565b725ae77Skettenis if (func_addr == entry_point_address ())
566b725ae77Skettenis pi->start_function = 1;
567b725ae77Skettenis else
568b725ae77Skettenis pi->start_function = 0;
569b725ae77Skettenis
570b725ae77Skettenis #if 0
571b725ae77Skettenis if (sal.line == 0)
572b725ae77Skettenis prologue_end = pc;
573b725ae77Skettenis else
574b725ae77Skettenis prologue_end = sal.end;
575b725ae77Skettenis #else
576b725ae77Skettenis prologue_end = pc;
577b725ae77Skettenis #endif
578b725ae77Skettenis }
579b725ae77Skettenis else
580b725ae77Skettenis { /* We're in the boondocks */
581b725ae77Skettenis func_addr = pc - 100;
582b725ae77Skettenis prologue_end = pc;
583b725ae77Skettenis }
584b725ae77Skettenis
585b725ae77Skettenis prologue_end = min (prologue_end, pc);
586b725ae77Skettenis
587b725ae77Skettenis /* Now, search the prologue looking for instructions that setup fp, save
588b725ae77Skettenis rp, adjust sp and such. We also record the frame offset of any saved
589b725ae77Skettenis registers. */
590b725ae77Skettenis
591b725ae77Skettenis pi->frameoffset = 0;
592b725ae77Skettenis pi->framereg = E_SP_REGNUM;
593b725ae77Skettenis fp_used = 0;
594b725ae77Skettenis ep_used = 0;
595b725ae77Skettenis pifsr = pi->pifsrs;
596b725ae77Skettenis regsave_func_p = 0;
597b725ae77Skettenis save_pc = 0;
598b725ae77Skettenis save_end = 0;
599b725ae77Skettenis r12_tmp = 0;
600b725ae77Skettenis
601b725ae77Skettenis #ifdef DEBUG
602b725ae77Skettenis printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n",
603b725ae77Skettenis (long) func_addr, (long) prologue_end);
604b725ae77Skettenis #endif
605b725ae77Skettenis
606b725ae77Skettenis for (current_pc = func_addr; current_pc < prologue_end;)
607b725ae77Skettenis {
608b725ae77Skettenis int insn;
609b725ae77Skettenis int insn2 = -1; /* dummy value */
610b725ae77Skettenis
611b725ae77Skettenis #ifdef DEBUG
612b725ae77Skettenis fprintf_filtered (gdb_stdlog, "0x%.8lx ", (long) current_pc);
613b725ae77Skettenis gdb_print_insn (current_pc, gdb_stdlog);
614b725ae77Skettenis #endif
615b725ae77Skettenis
616b725ae77Skettenis insn = read_memory_unsigned_integer (current_pc, 2);
617b725ae77Skettenis current_pc += 2;
618b725ae77Skettenis if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
619b725ae77Skettenis {
620b725ae77Skettenis insn2 = read_memory_unsigned_integer (current_pc, 2);
621b725ae77Skettenis current_pc += 2;
622b725ae77Skettenis }
623b725ae77Skettenis
624b725ae77Skettenis if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
625b725ae77Skettenis { /* jarl <func>,10 */
626b725ae77Skettenis long low_disp = insn2 & ~(long) 1;
627b725ae77Skettenis long disp = (((((insn & 0x3f) << 16) + low_disp)
628b725ae77Skettenis & ~(long) 1) ^ 0x00200000) - 0x00200000;
629b725ae77Skettenis
630b725ae77Skettenis save_pc = current_pc;
631b725ae77Skettenis save_end = prologue_end;
632b725ae77Skettenis regsave_func_p = 1;
633b725ae77Skettenis current_pc += disp - 4;
634b725ae77Skettenis prologue_end = (current_pc
635b725ae77Skettenis + (2 * 3) /* moves to/from ep */
636b725ae77Skettenis + 4 /* addi <const>,sp,sp */
637b725ae77Skettenis + 2 /* jmp [r10] */
638b725ae77Skettenis + (2 * 12) /* sst.w to save r2, r20-r29, r31 */
639b725ae77Skettenis + 20); /* slop area */
640b725ae77Skettenis
641b725ae77Skettenis #ifdef DEBUG
642b725ae77Skettenis printf_filtered ("\tfound jarl <func>,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n",
643b725ae77Skettenis disp, low_disp, (long) current_pc + 2);
644b725ae77Skettenis #endif
645b725ae77Skettenis continue;
646b725ae77Skettenis }
647b725ae77Skettenis else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p)
648b725ae77Skettenis { /* callt <imm6> */
649b725ae77Skettenis long ctbp = read_register (E_CTBP_REGNUM);
650b725ae77Skettenis long adr = ctbp + ((insn & 0x3f) << 1);
651b725ae77Skettenis
652b725ae77Skettenis save_pc = current_pc;
653b725ae77Skettenis save_end = prologue_end;
654b725ae77Skettenis regsave_func_p = 1;
655b725ae77Skettenis current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff);
656b725ae77Skettenis prologue_end = (current_pc
657b725ae77Skettenis + (2 * 3) /* prepare list2,imm5,sp/imm */
658b725ae77Skettenis + 4 /* ctret */
659b725ae77Skettenis + 20); /* slop area */
660b725ae77Skettenis
661b725ae77Skettenis #ifdef DEBUG
662b725ae77Skettenis printf_filtered ("\tfound callt, ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n",
663b725ae77Skettenis ctbp, adr, (long) current_pc);
664b725ae77Skettenis #endif
665b725ae77Skettenis continue;
666b725ae77Skettenis }
667b725ae77Skettenis else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */
668b725ae77Skettenis {
669b725ae77Skettenis handle_prepare (insn, insn2, ¤t_pc, pi, &pifsr);
670b725ae77Skettenis continue;
671b725ae77Skettenis }
672b725ae77Skettenis else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144)
673b725ae77Skettenis { /* ctret after processing register save function */
674b725ae77Skettenis current_pc = save_pc;
675b725ae77Skettenis prologue_end = save_end;
676b725ae77Skettenis regsave_func_p = 0;
677b725ae77Skettenis #ifdef DEBUG
678b725ae77Skettenis printf_filtered ("\tfound ctret after regsave func");
679b725ae77Skettenis #endif
680b725ae77Skettenis continue;
681b725ae77Skettenis }
682b725ae77Skettenis else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1)
683b725ae77Skettenis { /* pushml, pushmh */
684b725ae77Skettenis handle_pushm (insn, insn2, pi, &pifsr);
685b725ae77Skettenis continue;
686b725ae77Skettenis }
687b725ae77Skettenis else if ((insn & 0xffe0) == 0x0060 && regsave_func_p)
688b725ae77Skettenis { /* jmp after processing register save function */
689b725ae77Skettenis current_pc = save_pc;
690b725ae77Skettenis prologue_end = save_end;
691b725ae77Skettenis regsave_func_p = 0;
692b725ae77Skettenis #ifdef DEBUG
693b725ae77Skettenis printf_filtered ("\tfound jmp after regsave func");
694b725ae77Skettenis #endif
695b725ae77Skettenis continue;
696b725ae77Skettenis }
697b725ae77Skettenis else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */
698b725ae77Skettenis || (insn & 0xffe0) == 0x0060 /* jmp */
699b725ae77Skettenis || (insn & 0x0780) == 0x0580) /* branch */
700b725ae77Skettenis {
701b725ae77Skettenis #ifdef DEBUG
702b725ae77Skettenis printf_filtered ("\n");
703b725ae77Skettenis #endif
704b725ae77Skettenis break; /* Ran into end of prologue */
705b725ae77Skettenis }
706b725ae77Skettenis
707b725ae77Skettenis else if ((insn & 0xffe0) == ((E_SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
708b725ae77Skettenis pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10;
709b725ae77Skettenis else if (insn == ((E_SP_REGNUM << 11) | 0x0600 | E_SP_REGNUM)) /* addi <imm>,sp,sp */
710b725ae77Skettenis pi->frameoffset += insn2;
711b725ae77Skettenis else if (insn == ((E_FP_RAW_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,fp */
712b725ae77Skettenis {
713b725ae77Skettenis fp_used = 1;
714b725ae77Skettenis pi->framereg = E_FP_RAW_REGNUM;
715b725ae77Skettenis }
716b725ae77Skettenis
717b725ae77Skettenis else if (insn == ((E_R12_REGNUM << 11) | 0x0640 | E_R0_REGNUM)) /* movhi hi(const),r0,r12 */
718b725ae77Skettenis r12_tmp = insn2 << 16;
719b725ae77Skettenis else if (insn == ((E_R12_REGNUM << 11) | 0x0620 | E_R12_REGNUM)) /* movea lo(const),r12,r12 */
720b725ae77Skettenis r12_tmp += insn2;
721b725ae77Skettenis else if (insn == ((E_SP_REGNUM << 11) | 0x01c0 | E_R12_REGNUM) && r12_tmp) /* add r12,sp */
722b725ae77Skettenis pi->frameoffset = r12_tmp;
723b725ae77Skettenis else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,ep */
724b725ae77Skettenis ep_used = 1;
725b725ae77Skettenis else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_R1_REGNUM)) /* mov r1,ep */
726b725ae77Skettenis ep_used = 0;
727b725ae77Skettenis else if (((insn & 0x07ff) == (0x0760 | E_SP_REGNUM) /* st.w <reg>,<offset>[sp] */
728b725ae77Skettenis || (fp_used
729b725ae77Skettenis && (insn & 0x07ff) == (0x0760 | E_FP_RAW_REGNUM))) /* st.w <reg>,<offset>[fp] */
730b725ae77Skettenis && pifsr
731b725ae77Skettenis && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
732b725ae77Skettenis || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
733b725ae77Skettenis || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
734b725ae77Skettenis {
735b725ae77Skettenis pifsr->reg = reg;
736b725ae77Skettenis pifsr->offset = insn2 & ~1;
737b725ae77Skettenis pifsr->cur_frameoffset = pi->frameoffset;
738b725ae77Skettenis #ifdef DEBUG
739b725ae77Skettenis printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
740b725ae77Skettenis #endif
741b725ae77Skettenis pifsr++;
742b725ae77Skettenis }
743b725ae77Skettenis
744b725ae77Skettenis else if (ep_used /* sst.w <reg>,<offset>[ep] */
745b725ae77Skettenis && ((insn & 0x0781) == 0x0501)
746b725ae77Skettenis && pifsr
747b725ae77Skettenis && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
748b725ae77Skettenis || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
749b725ae77Skettenis || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
750b725ae77Skettenis {
751b725ae77Skettenis pifsr->reg = reg;
752b725ae77Skettenis pifsr->offset = (insn & 0x007e) << 1;
753b725ae77Skettenis pifsr->cur_frameoffset = pi->frameoffset;
754b725ae77Skettenis #ifdef DEBUG
755b725ae77Skettenis printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
756b725ae77Skettenis #endif
757b725ae77Skettenis pifsr++;
758b725ae77Skettenis }
759b725ae77Skettenis
760b725ae77Skettenis #ifdef DEBUG
761b725ae77Skettenis printf_filtered ("\n");
762b725ae77Skettenis #endif
763b725ae77Skettenis }
764b725ae77Skettenis
765b725ae77Skettenis if (pifsr)
766b725ae77Skettenis pifsr->framereg = 0; /* Tie off last entry */
767b725ae77Skettenis
768b725ae77Skettenis /* Fix up any offsets to the final offset. If a frame pointer was created, use it
769b725ae77Skettenis instead of the stack pointer. */
770b725ae77Skettenis for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++)
771b725ae77Skettenis {
772b725ae77Skettenis pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset;
773b725ae77Skettenis pifsr_tmp->framereg = pi->framereg;
774b725ae77Skettenis
775b725ae77Skettenis #ifdef DEBUG
776b725ae77Skettenis printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n",
777b725ae77Skettenis pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg);
778b725ae77Skettenis #endif
779b725ae77Skettenis }
780b725ae77Skettenis
781b725ae77Skettenis #ifdef DEBUG
782b725ae77Skettenis printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset);
783b725ae77Skettenis #endif
784b725ae77Skettenis
785b725ae77Skettenis return current_pc;
786b725ae77Skettenis }
787b725ae77Skettenis
788b725ae77Skettenis /* Function: find_callers_reg
789b725ae77Skettenis Find REGNUM on the stack. Otherwise, it's in an active register.
790b725ae77Skettenis One thing we might want to do here is to check REGNUM against the
791b725ae77Skettenis clobber mask, and somehow flag it as invalid if it isn't saved on
792b725ae77Skettenis the stack somewhere. This would provide a graceful failure mode
793b725ae77Skettenis when trying to get the value of caller-saves registers for an inner
794b725ae77Skettenis frame. */
795b725ae77Skettenis
796b725ae77Skettenis static CORE_ADDR
v850_find_callers_reg(struct frame_info * fi,int regnum)797b725ae77Skettenis v850_find_callers_reg (struct frame_info *fi, int regnum)
798b725ae77Skettenis {
799b725ae77Skettenis for (; fi; fi = get_next_frame (fi))
800*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
801b725ae77Skettenis return deprecated_read_register_dummy (get_frame_pc (fi),
802b725ae77Skettenis get_frame_base (fi), regnum);
803b725ae77Skettenis else if (deprecated_get_frame_saved_regs (fi)[regnum] != 0)
804b725ae77Skettenis return read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[regnum],
805b725ae77Skettenis v850_register_raw_size (regnum));
806b725ae77Skettenis
807b725ae77Skettenis return read_register (regnum);
808b725ae77Skettenis }
809b725ae77Skettenis
810b725ae77Skettenis /* Function: frame_chain
811b725ae77Skettenis Figure out the frame prior to FI. Unfortunately, this involves
812b725ae77Skettenis scanning the prologue of the caller, which will also be done
813b725ae77Skettenis shortly by v850_init_extra_frame_info. For the dummy frame, we
814b725ae77Skettenis just return the stack pointer that was in use at the time the
815b725ae77Skettenis function call was made. */
816b725ae77Skettenis
817b725ae77Skettenis static CORE_ADDR
v850_frame_chain(struct frame_info * fi)818b725ae77Skettenis v850_frame_chain (struct frame_info *fi)
819b725ae77Skettenis {
820b725ae77Skettenis struct prologue_info pi;
821b725ae77Skettenis CORE_ADDR callers_pc, fp;
822b725ae77Skettenis
823b725ae77Skettenis /* First, find out who called us */
824b725ae77Skettenis callers_pc = DEPRECATED_FRAME_SAVED_PC (fi);
825b725ae77Skettenis /* If caller is a call-dummy, then our FP bears no relation to his FP! */
826b725ae77Skettenis fp = v850_find_callers_reg (fi, E_FP_RAW_REGNUM);
827*11efff7fSkettenis if (deprecated_pc_in_call_dummy (callers_pc))
828b725ae77Skettenis return fp; /* caller is call-dummy: return oldest value of FP */
829b725ae77Skettenis
830b725ae77Skettenis /* Caller is NOT a call-dummy, so everything else should just work.
831b725ae77Skettenis Even if THIS frame is a call-dummy! */
832b725ae77Skettenis pi.pifsrs = NULL;
833b725ae77Skettenis
834b725ae77Skettenis v850_scan_prologue (callers_pc, &pi);
835b725ae77Skettenis
836b725ae77Skettenis if (pi.start_function)
837b725ae77Skettenis return 0; /* Don't chain beyond the start function */
838b725ae77Skettenis
839b725ae77Skettenis if (pi.framereg == E_FP_RAW_REGNUM)
840b725ae77Skettenis return v850_find_callers_reg (fi, pi.framereg);
841b725ae77Skettenis
842b725ae77Skettenis return get_frame_base (fi) - pi.frameoffset;
843b725ae77Skettenis }
844b725ae77Skettenis
845b725ae77Skettenis /* Function: skip_prologue
846b725ae77Skettenis Return the address of the first code past the prologue of the function. */
847b725ae77Skettenis
848b725ae77Skettenis static CORE_ADDR
v850_skip_prologue(CORE_ADDR pc)849b725ae77Skettenis v850_skip_prologue (CORE_ADDR pc)
850b725ae77Skettenis {
851b725ae77Skettenis CORE_ADDR func_addr, func_end;
852b725ae77Skettenis
853b725ae77Skettenis /* See what the symbol table says */
854b725ae77Skettenis
855b725ae77Skettenis if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
856b725ae77Skettenis {
857b725ae77Skettenis struct symtab_and_line sal;
858b725ae77Skettenis
859b725ae77Skettenis sal = find_pc_line (func_addr, 0);
860b725ae77Skettenis
861b725ae77Skettenis if (sal.line != 0 && sal.end < func_end)
862b725ae77Skettenis return sal.end;
863b725ae77Skettenis else
864b725ae77Skettenis /* Either there's no line info, or the line after the prologue is after
865b725ae77Skettenis the end of the function. In this case, there probably isn't a
866b725ae77Skettenis prologue. */
867b725ae77Skettenis return pc;
868b725ae77Skettenis }
869b725ae77Skettenis
870b725ae77Skettenis /* We can't find the start of this function, so there's nothing we can do. */
871b725ae77Skettenis return pc;
872b725ae77Skettenis }
873b725ae77Skettenis
874b725ae77Skettenis /* Function: pop_frame
875b725ae77Skettenis This routine gets called when either the user uses the `return'
876b725ae77Skettenis command, or the call dummy breakpoint gets hit. */
877b725ae77Skettenis
878b725ae77Skettenis static void
v850_pop_frame(void)879b725ae77Skettenis v850_pop_frame (void)
880b725ae77Skettenis {
881b725ae77Skettenis struct frame_info *frame = get_current_frame ();
882b725ae77Skettenis int regnum;
883b725ae77Skettenis
884*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
885*11efff7fSkettenis deprecated_pop_dummy_frame ();
886b725ae77Skettenis else
887b725ae77Skettenis {
888b725ae77Skettenis write_register (E_PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
889b725ae77Skettenis
890b725ae77Skettenis for (regnum = 0; regnum < E_NUM_REGS; regnum++)
891b725ae77Skettenis if (deprecated_get_frame_saved_regs (frame)[regnum] != 0)
892b725ae77Skettenis write_register (regnum,
893b725ae77Skettenis read_memory_unsigned_integer (deprecated_get_frame_saved_regs (frame)[regnum],
894b725ae77Skettenis v850_register_raw_size (regnum)));
895b725ae77Skettenis
896b725ae77Skettenis write_register (E_SP_REGNUM, get_frame_base (frame));
897b725ae77Skettenis }
898b725ae77Skettenis
899b725ae77Skettenis flush_cached_frames ();
900b725ae77Skettenis }
901b725ae77Skettenis
902b725ae77Skettenis /* Function: push_arguments
903b725ae77Skettenis Setup arguments and RP for a call to the target. First four args
904b725ae77Skettenis go in R6->R9, subsequent args go into sp + 16 -> sp + ... Structs
905b725ae77Skettenis are passed by reference. 64 bit quantities (doubles and long
906b725ae77Skettenis longs) may be split between the regs and the stack. When calling a
907b725ae77Skettenis function that returns a struct, a pointer to the struct is passed
908b725ae77Skettenis in as a secret first argument (always in R6).
909b725ae77Skettenis
910b725ae77Skettenis Stack space for the args has NOT been allocated: that job is up to us.
911b725ae77Skettenis */
912b725ae77Skettenis
913b725ae77Skettenis static CORE_ADDR
v850_push_arguments(int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)914b725ae77Skettenis v850_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
915b725ae77Skettenis int struct_return, CORE_ADDR struct_addr)
916b725ae77Skettenis {
917b725ae77Skettenis int argreg;
918b725ae77Skettenis int argnum;
919b725ae77Skettenis int len = 0;
920b725ae77Skettenis int stack_offset;
921b725ae77Skettenis
922b725ae77Skettenis /* First, just for safety, make sure stack is aligned */
923b725ae77Skettenis sp &= ~3;
924b725ae77Skettenis
925b725ae77Skettenis /* The offset onto the stack at which we will start copying parameters
926b725ae77Skettenis (after the registers are used up) begins at 16 rather than at zero.
927b725ae77Skettenis I don't really know why, that's just the way it seems to work. */
928b725ae77Skettenis stack_offset = 16;
929b725ae77Skettenis
930b725ae77Skettenis /* Now make space on the stack for the args. */
931b725ae77Skettenis for (argnum = 0; argnum < nargs; argnum++)
932b725ae77Skettenis len += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
933b725ae77Skettenis sp -= len + stack_offset; /* possibly over-allocating, but it works... */
934b725ae77Skettenis /* (you might think we could allocate 16 bytes */
935b725ae77Skettenis /* less, but the ABI seems to use it all! ) */
936b725ae77Skettenis
937b725ae77Skettenis argreg = E_ARG0_REGNUM;
938b725ae77Skettenis /* the struct_return pointer occupies the first parameter-passing reg */
939b725ae77Skettenis if (struct_return)
940b725ae77Skettenis argreg++;
941b725ae77Skettenis
942b725ae77Skettenis /* Now load as many as possible of the first arguments into
943b725ae77Skettenis registers, and push the rest onto the stack. There are 16 bytes
944b725ae77Skettenis in four registers available. Loop thru args from first to last. */
945b725ae77Skettenis for (argnum = 0; argnum < nargs; argnum++)
946b725ae77Skettenis {
947b725ae77Skettenis int len;
948b725ae77Skettenis char *val;
949b725ae77Skettenis char valbuf[v850_register_raw_size (E_ARG0_REGNUM)];
950b725ae77Skettenis
951b725ae77Skettenis if (!v850_type_is_scalar (VALUE_TYPE (*args))
952b725ae77Skettenis && TYPE_LENGTH (VALUE_TYPE (*args)) > E_MAX_RETTYPE_SIZE_IN_REGS)
953b725ae77Skettenis {
954b725ae77Skettenis store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (*args));
955b725ae77Skettenis len = 4;
956b725ae77Skettenis val = valbuf;
957b725ae77Skettenis }
958b725ae77Skettenis else
959b725ae77Skettenis {
960b725ae77Skettenis len = TYPE_LENGTH (VALUE_TYPE (*args));
961b725ae77Skettenis val = (char *) VALUE_CONTENTS (*args);
962b725ae77Skettenis }
963b725ae77Skettenis
964b725ae77Skettenis while (len > 0)
965b725ae77Skettenis if (argreg <= E_ARGLAST_REGNUM)
966b725ae77Skettenis {
967b725ae77Skettenis CORE_ADDR regval;
968b725ae77Skettenis
969b725ae77Skettenis regval = extract_unsigned_integer (val, v850_register_raw_size (argreg));
970b725ae77Skettenis write_register (argreg, regval);
971b725ae77Skettenis
972b725ae77Skettenis len -= v850_register_raw_size (argreg);
973b725ae77Skettenis val += v850_register_raw_size (argreg);
974b725ae77Skettenis argreg++;
975b725ae77Skettenis }
976b725ae77Skettenis else
977b725ae77Skettenis {
978b725ae77Skettenis write_memory (sp + stack_offset, val, 4);
979b725ae77Skettenis
980b725ae77Skettenis len -= 4;
981b725ae77Skettenis val += 4;
982b725ae77Skettenis stack_offset += 4;
983b725ae77Skettenis }
984b725ae77Skettenis args++;
985b725ae77Skettenis }
986b725ae77Skettenis return sp;
987b725ae77Skettenis }
988b725ae77Skettenis
989b725ae77Skettenis /* Function: push_return_address (pc)
990b725ae77Skettenis Set up the return address for the inferior function call.
991b725ae77Skettenis Needed for targets where we don't actually execute a JSR/BSR instruction */
992b725ae77Skettenis
993b725ae77Skettenis static CORE_ADDR
v850_push_return_address(CORE_ADDR pc,CORE_ADDR sp)994b725ae77Skettenis v850_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
995b725ae77Skettenis {
996b725ae77Skettenis write_register (E_RP_REGNUM, entry_point_address ());
997b725ae77Skettenis return sp;
998b725ae77Skettenis }
999b725ae77Skettenis
1000b725ae77Skettenis /* Function: frame_saved_pc
1001b725ae77Skettenis Find the caller of this frame. We do this by seeing if E_RP_REGNUM
1002b725ae77Skettenis is saved in the stack anywhere, otherwise we get it from the
1003b725ae77Skettenis registers. If the inner frame is a dummy frame, return its PC
1004b725ae77Skettenis instead of RP, because that's where "caller" of the dummy-frame
1005b725ae77Skettenis will be found. */
1006b725ae77Skettenis
1007b725ae77Skettenis static CORE_ADDR
v850_frame_saved_pc(struct frame_info * fi)1008b725ae77Skettenis v850_frame_saved_pc (struct frame_info *fi)
1009b725ae77Skettenis {
1010*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
1011b725ae77Skettenis return deprecated_read_register_dummy (get_frame_pc (fi),
1012b725ae77Skettenis get_frame_base (fi), E_PC_REGNUM);
1013b725ae77Skettenis else
1014b725ae77Skettenis return v850_find_callers_reg (fi, E_RP_REGNUM);
1015b725ae77Skettenis }
1016b725ae77Skettenis
1017b725ae77Skettenis
1018b725ae77Skettenis static CORE_ADDR
v850_saved_pc_after_call(struct frame_info * ignore)1019b725ae77Skettenis v850_saved_pc_after_call (struct frame_info *ignore)
1020b725ae77Skettenis {
1021b725ae77Skettenis return read_register (E_RP_REGNUM);
1022b725ae77Skettenis }
1023b725ae77Skettenis
1024b725ae77Skettenis static void
v850_extract_return_value(struct type * type,char * regbuf,char * valbuf)1025b725ae77Skettenis v850_extract_return_value (struct type *type, char *regbuf, char *valbuf)
1026b725ae77Skettenis {
1027b725ae77Skettenis CORE_ADDR return_buffer;
1028b725ae77Skettenis
1029b725ae77Skettenis if (!v850_use_struct_convention (0, type))
1030b725ae77Skettenis {
1031b725ae77Skettenis /* Scalar return values of <= 8 bytes are returned in
1032b725ae77Skettenis E_V0_REGNUM to E_V1_REGNUM. */
1033b725ae77Skettenis memcpy (valbuf,
1034b725ae77Skettenis ®buf[DEPRECATED_REGISTER_BYTE (E_V0_REGNUM)],
1035b725ae77Skettenis TYPE_LENGTH (type));
1036b725ae77Skettenis }
1037b725ae77Skettenis else
1038b725ae77Skettenis {
1039b725ae77Skettenis /* Aggregates and return values > 8 bytes are returned in memory,
1040b725ae77Skettenis pointed to by R6. */
1041b725ae77Skettenis return_buffer =
1042b725ae77Skettenis extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (E_V0_REGNUM),
1043*11efff7fSkettenis register_size (current_gdbarch, E_V0_REGNUM));
1044b725ae77Skettenis
1045b725ae77Skettenis read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
1046b725ae77Skettenis }
1047b725ae77Skettenis }
1048b725ae77Skettenis
1049b725ae77Skettenis const static unsigned char *
v850_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)1050b725ae77Skettenis v850_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
1051b725ae77Skettenis {
1052b725ae77Skettenis static unsigned char breakpoint[] = { 0x85, 0x05 };
1053b725ae77Skettenis *lenptr = sizeof (breakpoint);
1054b725ae77Skettenis return breakpoint;
1055b725ae77Skettenis }
1056b725ae77Skettenis
1057b725ae77Skettenis static void
v850_store_return_value(struct type * type,char * valbuf)1058b725ae77Skettenis v850_store_return_value (struct type *type, char *valbuf)
1059b725ae77Skettenis {
1060b725ae77Skettenis CORE_ADDR return_buffer;
1061b725ae77Skettenis
1062b725ae77Skettenis if (!v850_use_struct_convention (0, type))
1063b725ae77Skettenis deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (E_V0_REGNUM), valbuf,
1064b725ae77Skettenis TYPE_LENGTH (type));
1065b725ae77Skettenis else
1066b725ae77Skettenis {
1067b725ae77Skettenis return_buffer = read_register (E_V0_REGNUM);
1068b725ae77Skettenis write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
1069b725ae77Skettenis }
1070b725ae77Skettenis }
1071b725ae77Skettenis
1072b725ae77Skettenis static void
v850_frame_init_saved_regs(struct frame_info * fi)1073b725ae77Skettenis v850_frame_init_saved_regs (struct frame_info *fi)
1074b725ae77Skettenis {
1075b725ae77Skettenis struct prologue_info pi;
1076b725ae77Skettenis struct pifsr pifsrs[E_NUM_REGS + 1], *pifsr;
1077b725ae77Skettenis CORE_ADDR func_addr, func_end;
1078b725ae77Skettenis
1079b725ae77Skettenis if (!deprecated_get_frame_saved_regs (fi))
1080b725ae77Skettenis {
1081b725ae77Skettenis frame_saved_regs_zalloc (fi);
1082b725ae77Skettenis
1083b725ae77Skettenis /* The call dummy doesn't save any registers on the stack, so we
1084b725ae77Skettenis can return now. */
1085*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
1086b725ae77Skettenis return;
1087b725ae77Skettenis
1088b725ae77Skettenis /* Find the beginning of this function, so we can analyze its
1089b725ae77Skettenis prologue. */
1090b725ae77Skettenis if (find_pc_partial_function (get_frame_pc (fi), NULL, &func_addr, &func_end))
1091b725ae77Skettenis {
1092b725ae77Skettenis pi.pifsrs = pifsrs;
1093b725ae77Skettenis
1094b725ae77Skettenis v850_scan_prologue (get_frame_pc (fi), &pi);
1095b725ae77Skettenis
1096b725ae77Skettenis if (!get_next_frame (fi) && pi.framereg == E_SP_REGNUM)
1097b725ae77Skettenis deprecated_update_frame_base_hack (fi, read_register (pi.framereg) - pi.frameoffset);
1098b725ae77Skettenis
1099b725ae77Skettenis for (pifsr = pifsrs; pifsr->framereg; pifsr++)
1100b725ae77Skettenis {
1101b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[pifsr->reg] = pifsr->offset + get_frame_base (fi);
1102b725ae77Skettenis
1103b725ae77Skettenis if (pifsr->framereg == E_SP_REGNUM)
1104b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[pifsr->reg] += pi.frameoffset;
1105b725ae77Skettenis }
1106b725ae77Skettenis }
1107b725ae77Skettenis /* Else we're out of luck (can't debug completely stripped code).
1108b725ae77Skettenis FIXME. */
1109b725ae77Skettenis }
1110b725ae77Skettenis }
1111b725ae77Skettenis
1112b725ae77Skettenis /* Function: init_extra_frame_info
1113b725ae77Skettenis Setup the frame's frame pointer, pc, and frame addresses for saved
1114b725ae77Skettenis registers. Most of the work is done in scan_prologue().
1115b725ae77Skettenis
1116b725ae77Skettenis Note that when we are called for the last frame (currently active frame),
1117b725ae77Skettenis that get_frame_pc (fi) and fi->frame will already be setup. However, fi->frame will
1118b725ae77Skettenis be valid only if this routine uses FP. For previous frames, fi-frame will
1119b725ae77Skettenis always be correct (since that is derived from v850_frame_chain ()).
1120b725ae77Skettenis
1121b725ae77Skettenis We can be called with the PC in the call dummy under two
1122b725ae77Skettenis circumstances. First, during normal backtracing, second, while
1123b725ae77Skettenis figuring out the frame pointer just prior to calling the target
1124b725ae77Skettenis function (see call_function_by_hand). */
1125b725ae77Skettenis
1126b725ae77Skettenis static void
v850_init_extra_frame_info(int fromleaf,struct frame_info * fi)1127b725ae77Skettenis v850_init_extra_frame_info (int fromleaf, struct frame_info *fi)
1128b725ae77Skettenis {
1129b725ae77Skettenis struct prologue_info pi;
1130b725ae77Skettenis
1131b725ae77Skettenis if (get_next_frame (fi))
1132b725ae77Skettenis deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
1133b725ae77Skettenis
1134b725ae77Skettenis v850_frame_init_saved_regs (fi);
1135b725ae77Skettenis }
1136b725ae77Skettenis
1137b725ae77Skettenis static void
v850_store_struct_return(CORE_ADDR addr,CORE_ADDR sp)1138b725ae77Skettenis v850_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
1139b725ae77Skettenis {
1140b725ae77Skettenis write_register (E_ARG0_REGNUM, addr);
1141b725ae77Skettenis }
1142b725ae77Skettenis
1143b725ae77Skettenis static CORE_ADDR
v850_target_read_fp(void)1144b725ae77Skettenis v850_target_read_fp (void)
1145b725ae77Skettenis {
1146b725ae77Skettenis return read_register (E_FP_RAW_REGNUM);
1147b725ae77Skettenis }
1148b725ae77Skettenis
1149b725ae77Skettenis static struct gdbarch *
v850_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)1150b725ae77Skettenis v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1151b725ae77Skettenis {
1152b725ae77Skettenis struct gdbarch_tdep *tdep = NULL;
1153b725ae77Skettenis struct gdbarch *gdbarch;
1154b725ae77Skettenis int i;
1155b725ae77Skettenis
1156b725ae77Skettenis /* find a candidate among the list of pre-declared architectures. */
1157b725ae77Skettenis arches = gdbarch_list_lookup_by_info (arches, &info);
1158b725ae77Skettenis if (arches != NULL)
1159b725ae77Skettenis return (arches->gdbarch);
1160b725ae77Skettenis
1161b725ae77Skettenis #if 0
1162b725ae77Skettenis tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1163b725ae77Skettenis #endif
1164b725ae77Skettenis
1165b725ae77Skettenis /* Change the register names based on the current machine type. */
1166b725ae77Skettenis if (info.bfd_arch_info->arch != bfd_arch_v850)
1167b725ae77Skettenis return 0;
1168b725ae77Skettenis
1169b725ae77Skettenis gdbarch = gdbarch_alloc (&info, 0);
1170b725ae77Skettenis
1171b725ae77Skettenis /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
1172b725ae77Skettenis ready to unwind the PC first (see frame.c:get_prev_frame()). */
1173b725ae77Skettenis set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
1174b725ae77Skettenis
1175b725ae77Skettenis for (i = 0; v850_processor_type_table[i].regnames != NULL; i++)
1176b725ae77Skettenis {
1177b725ae77Skettenis if (v850_processor_type_table[i].mach == info.bfd_arch_info->mach)
1178b725ae77Skettenis {
1179b725ae77Skettenis v850_register_names = v850_processor_type_table[i].regnames;
1180b725ae77Skettenis break;
1181b725ae77Skettenis }
1182b725ae77Skettenis }
1183b725ae77Skettenis
1184b725ae77Skettenis /*
1185b725ae77Skettenis * Basic register fields and methods.
1186b725ae77Skettenis */
1187b725ae77Skettenis set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
1188b725ae77Skettenis set_gdbarch_num_pseudo_regs (gdbarch, 0);
1189b725ae77Skettenis set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
1190b725ae77Skettenis set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
1191b725ae77Skettenis set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1192b725ae77Skettenis set_gdbarch_register_name (gdbarch, v850_register_name);
1193b725ae77Skettenis set_gdbarch_deprecated_register_size (gdbarch, v850_reg_size);
1194b725ae77Skettenis set_gdbarch_deprecated_register_byte (gdbarch, v850_register_byte);
1195*11efff7fSkettenis set_gdbarch_deprecated_register_raw_size (current_gdbarch, gdbarch, v850_register_raw_size);
1196b725ae77Skettenis set_gdbarch_deprecated_register_virtual_size (gdbarch, v850_register_raw_size);
1197b725ae77Skettenis set_gdbarch_deprecated_register_virtual_type (gdbarch, v850_reg_virtual_type);
1198b725ae77Skettenis
1199b725ae77Skettenis set_gdbarch_deprecated_target_read_fp (gdbarch, v850_target_read_fp);
1200b725ae77Skettenis
1201b725ae77Skettenis /*
1202b725ae77Skettenis * Frame Info
1203b725ae77Skettenis */
1204b725ae77Skettenis set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, v850_frame_init_saved_regs);
1205b725ae77Skettenis set_gdbarch_deprecated_init_extra_frame_info (gdbarch, v850_init_extra_frame_info);
1206b725ae77Skettenis set_gdbarch_deprecated_frame_chain (gdbarch, v850_frame_chain);
1207b725ae77Skettenis set_gdbarch_deprecated_saved_pc_after_call (gdbarch, v850_saved_pc_after_call);
1208b725ae77Skettenis set_gdbarch_deprecated_frame_saved_pc (gdbarch, v850_frame_saved_pc);
1209b725ae77Skettenis set_gdbarch_skip_prologue (gdbarch, v850_skip_prologue);
1210b725ae77Skettenis
1211b725ae77Skettenis /*
1212b725ae77Skettenis * Miscelany
1213b725ae77Skettenis */
1214b725ae77Skettenis /* Stack grows up. */
1215b725ae77Skettenis set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1216b725ae77Skettenis
1217b725ae77Skettenis /*
1218b725ae77Skettenis * Call Dummies
1219b725ae77Skettenis *
1220b725ae77Skettenis * These values and methods are used when gdb calls a target function. */
1221b725ae77Skettenis set_gdbarch_deprecated_push_return_address (gdbarch, v850_push_return_address);
1222b725ae77Skettenis set_gdbarch_deprecated_extract_return_value (gdbarch, v850_extract_return_value);
1223b725ae77Skettenis set_gdbarch_deprecated_push_arguments (gdbarch, v850_push_arguments);
1224b725ae77Skettenis set_gdbarch_deprecated_pop_frame (gdbarch, v850_pop_frame);
1225b725ae77Skettenis set_gdbarch_deprecated_store_struct_return (gdbarch, v850_store_struct_return);
1226b725ae77Skettenis set_gdbarch_deprecated_store_return_value (gdbarch, v850_store_return_value);
1227*11efff7fSkettenis set_gdbarch_deprecated_use_struct_convention (gdbarch, v850_use_struct_convention);
1228b725ae77Skettenis set_gdbarch_breakpoint_from_pc (gdbarch, v850_breakpoint_from_pc);
1229b725ae77Skettenis
1230b725ae77Skettenis set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1231b725ae77Skettenis set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1232b725ae77Skettenis set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1233b725ae77Skettenis set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1234b725ae77Skettenis
1235b725ae77Skettenis /* Should be using push_dummy_call. */
1236b725ae77Skettenis set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
1237b725ae77Skettenis
1238b725ae77Skettenis set_gdbarch_print_insn (gdbarch, print_insn_v850);
1239b725ae77Skettenis
1240b725ae77Skettenis return gdbarch;
1241b725ae77Skettenis }
1242b725ae77Skettenis
1243b725ae77Skettenis extern initialize_file_ftype _initialize_v850_tdep; /* -Wmissing-prototypes */
1244b725ae77Skettenis
1245b725ae77Skettenis void
_initialize_v850_tdep(void)1246b725ae77Skettenis _initialize_v850_tdep (void)
1247b725ae77Skettenis {
1248b725ae77Skettenis register_gdbarch_init (bfd_arch_v850, v850_gdbarch_init);
1249b725ae77Skettenis }
1250