* config/tc-m68k.c (add_fix): Treat a width of '3' like 'B'.
[deliverable/binutils-gdb.git] / gdb / d10v-tdep.c
CommitLineData
7b3fa778
MH
1/* Target-dependent code for MItsubishi D10V, for GDB.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3This file is part of GDB.
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program; if not, write to the Free Software
14Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15
16/* Contributed by Martin Hunt, hunt@cygnus.com */
17
18#include "defs.h"
19#include "frame.h"
20#include "obstack.h"
21#include "symtab.h"
22#include "gdbtypes.h"
23#include "gdbcmd.h"
24#include "gdbcore.h"
81dc176f 25#include "gdb_string.h"
7b3fa778
MH
26#include "value.h"
27#include "inferior.h"
28#include "dis-asm.h"
29
e05bda9f
MH
30void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi, struct frame_saved_regs *fsr));
31
32/* Discard from the stack the innermost frame,
33 restoring all saved registers. */
34
7b3fa778
MH
35void
36d10v_pop_frame ()
37{
e05bda9f 38 struct frame_info *frame = get_current_frame ();
81dc176f 39 int fp, r13;
e05bda9f
MH
40 int regnum;
41 struct frame_saved_regs fsr;
42 char raw_buffer[8];
43
81dc176f 44 fp = (int)FRAME_FP (frame);
e05bda9f
MH
45
46 /* fill out fsr with the address of where each */
47 /* register was stored in the frame */
48 get_frame_saved_regs (frame, &fsr);
49
50 /* r13 contains the old PC. save it. */
81dc176f 51 r13 = (int)read_register (13);
e05bda9f
MH
52
53 /* now update the current registers with the old values */
54 for (regnum = A0_REGNUM; regnum < A0_REGNUM+2 ; regnum++)
55 {
56 if (fsr.regs[regnum])
57 {
81dc176f 58 read_memory (fsr.regs[regnum], raw_buffer, 8);
e05bda9f
MH
59 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 8);
60 }
61 }
62 for (regnum = 0; regnum < SP_REGNUM; regnum++)
63 {
64 if (fsr.regs[regnum])
65 {
81dc176f 66 write_register (regnum, read_memory_unsigned_integer (fsr.regs[regnum], 2));
e05bda9f
MH
67 }
68 }
69 if (fsr.regs[PSW_REGNUM])
70 {
81dc176f 71 write_register (PSW_REGNUM, read_memory_unsigned_integer (fsr.regs[PSW_REGNUM], 2));
e05bda9f
MH
72 }
73
74 /* PC is set to r13 */
81dc176f 75 write_register (PC_REGNUM, (LONGEST)r13);
e05bda9f
MH
76 write_register (SP_REGNUM, fp - frame->size);
77 flush_cached_frames ();
78}
79
80static int
81check_prologue (op)
82 unsigned short op;
83{
84 /* st rn, @-sp */
85 if ((op & 0x7E1F) == 0x6C1F)
86 return 1;
87
88 /* st2w rn, @-sp */
89 if ((op & 0x7E3F) == 0x6E1F)
90 return 1;
91
92 /* subi sp, n */
93 if ((op & 0x7FE1) == 0x01E1)
94 return 1;
95
96 /* mv r11, sp */
97 if (op == 0x417E)
98 return 1;
99
100 /* nop */
101 if (op == 0x5E00)
102 return 1;
103
104 /* st rn, @sp */
105 if ((op & 0x7E1F) == 0x681E)
106 return 1;
107
108 /* st2w rn, @sp */
109 if ((op & 0x7E3F) == 0x3A1E)
110 return 1;
111
e05bda9f 112 return 0;
7b3fa778
MH
113}
114
115CORE_ADDR
e05bda9f
MH
116d10v_skip_prologue (pc)
117 CORE_ADDR pc;
7b3fa778 118{
e05bda9f
MH
119 unsigned long op;
120 unsigned short op1, op2;
121
122 if (target_read_memory (pc, (char *)&op, 4))
123 return pc; /* Can't access it -- assume no prologue. */
124
125 while (1)
126 {
81dc176f 127 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
128 if ((op & 0xC0000000) == 0xC0000000)
129 {
130 /* long instruction */
131 if ( ((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */
132 ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */
133 ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */
134 break;
135 }
136 else
137 {
138 /* short instructions */
139 op1 = (op & 0x3FFF8000) >> 15;
140 op2 = op & 0x7FFF;
141 if (!check_prologue(op1) || !check_prologue(op2))
142 break;
143 }
144 pc += 4;
145 }
146 return pc;
7b3fa778
MH
147}
148
e05bda9f
MH
149/* Given a GDB frame, determine the address of the calling function's frame.
150 This will be used to create a new GDB frame struct, and then
151 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
81dc176f 152*/
e05bda9f 153
7b3fa778
MH
154CORE_ADDR
155d10v_frame_chain (frame)
156 struct frame_info *frame;
157{
e05bda9f 158 struct frame_saved_regs fsr;
e05bda9f 159 d10v_frame_find_saved_regs (frame, &fsr);
81dc176f 160 return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],2);
7b3fa778
MH
161}
162
e05bda9f
MH
163static int next_addr;
164
165static int
166prologue_find_regs (op, fsr, addr)
167 unsigned short op;
168 struct frame_saved_regs *fsr;
169 CORE_ADDR addr;
170{
171 int n;
172
173 /* st rn, @-sp */
174 if ((op & 0x7E1F) == 0x6C1F)
175 {
176 n = (op & 0x1E0) >> 5;
177 next_addr -= 2;
178 fsr->regs[n] = next_addr;
179 return 1;
180 }
181
182 /* st2w rn, @-sp */
183 else if ((op & 0x7E3F) == 0x6E1F)
184 {
185 n = (op & 0x1E0) >> 5;
186 next_addr -= 4;
187 fsr->regs[n] = next_addr;
188 fsr->regs[n+1] = next_addr+2;
189 return 1;
190 }
191
192 /* subi sp, n */
193 if ((op & 0x7FE1) == 0x01E1)
194 {
195 n = (op & 0x1E) >> 1;
196 if (n == 0)
197 n = 16;
198 next_addr -= n;
199 return 1;
200 }
201
202 /* mv r11, sp */
203 if (op == 0x417E)
204 return 1;
205
206 /* nop */
207 if (op == 0x5E00)
208 return 1;
209
210 /* st rn, @sp */
211 if ((op & 0x7E1F) == 0x681E)
212 {
213 n = (op & 0x1E0) >> 5;
214 fsr->regs[n] = next_addr;
215 return 1;
216 }
217
218 /* st2w rn, @sp */
219 if ((op & 0x7E3F) == 0x3A1E)
220 {
221 n = (op & 0x1E0) >> 5;
222 fsr->regs[n] = next_addr;
223 fsr->regs[n+1] = next_addr+2;
224 return 1;
225 }
226
227 return 0;
228}
229
7b3fa778
MH
230/* Put here the code to store, into a struct frame_saved_regs, the
231 addresses of the saved registers of frame described by FRAME_INFO.
232 This includes special registers such as pc and fp saved in special
233 ways in the stack frame. sp is even more special: the address we
234 return for it IS the sp for the next frame. */
235void
236d10v_frame_find_saved_regs (fi, fsr)
237 struct frame_info *fi;
238 struct frame_saved_regs *fsr;
e05bda9f
MH
239{
240 CORE_ADDR fp, pc;
241 unsigned long op;
242 unsigned short op1, op2;
243 int i;
244
245 fp = fi->frame;
246 memset (fsr, 0, sizeof (*fsr));
247 next_addr = 0;
248
249 pc = get_pc_function_start (fi->pc);
250
251 while (1)
252 {
81dc176f 253 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
254 if ((op & 0xC0000000) == 0xC0000000)
255 {
256 /* long instruction */
257 if ((op & 0x3FFF0000) == 0x01FF0000)
258 {
259 /* add3 sp,sp,n */
260 short n = op & 0xFFFF;
261 next_addr += n;
262 }
263 else if ((op & 0x3F0F0000) == 0x340F0000)
264 {
265 /* st rn, @(offset,sp) */
266 short offset = op & 0xFFFF;
267 short n = (op >> 20) & 0xF;
268 fsr->regs[n] = next_addr + offset;
269 }
270 else if ((op & 0x3F1F0000) == 0x350F0000)
271 {
272 /* st2w rn, @(offset,sp) */
273 short offset = op & 0xFFFF;
274 short n = (op >> 20) & 0xF;
275 fsr->regs[n] = next_addr + offset;
276 fsr->regs[n+1] = next_addr + offset + 2;
277 }
278 else
279 break;
280 }
281 else
282 {
283 /* short instructions */
284 op1 = (op & 0x3FFF8000) >> 15;
285 op2 = op & 0x7FFF;
286 if (!prologue_find_regs(op1,fsr,pc) || !prologue_find_regs(op2,fsr,pc))
287 break;
288 }
289 pc += 4;
290 }
291
292 fi->size = -next_addr;
e05bda9f
MH
293
294 for (i=0; i<NUM_REGS; i++)
295 if (fsr->regs[i])
296 {
297 fsr->regs[i] = fp - (next_addr - fsr->regs[i]);
e05bda9f 298 }
81dc176f
MH
299
300 if (fsr->regs[13])
301 fi->return_pc = (read_memory_unsigned_integer(fsr->regs[13],2)-1) << 2;
302 else
303 fi->return_pc = (read_register(13) - 1) << 2;
7b3fa778
MH
304}
305
306void
307d10v_init_extra_frame_info (fromleaf, fi)
308 int fromleaf;
309 struct frame_info *fi;
310{
311 struct frame_saved_regs dummy;
e05bda9f 312
81dc176f
MH
313 if (fi->next && (fi->pc == 0))
314 fi->pc = fi->next->return_pc;
315
e05bda9f 316 d10v_frame_find_saved_regs (fi, &dummy);
7b3fa778
MH
317}
318
319static void
320show_regs (args, from_tty)
321 char *args;
322 int from_tty;
323{
324 long long num1, num2;
325 printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
326 read_register (PC_REGNUM), read_register (PC_REGNUM) << 2,
327 read_register (PSW_REGNUM),
328 read_register (24),
329 read_register (25),
330 read_register (23));
331 printf_filtered ("R0-R7 %04x %04x %04x %04x %04x %04x %04x %04x\n",
332 read_register (0),
333 read_register (1),
334 read_register (2),
335 read_register (3),
336 read_register (4),
337 read_register (5),
338 read_register (6),
339 read_register (7));
340 printf_filtered ("R8-R15 %04x %04x %04x %04x %04x %04x %04x %04x\n",
341 read_register (8),
342 read_register (9),
343 read_register (10),
344 read_register (11),
345 read_register (12),
346 read_register (13),
347 read_register (14),
348 read_register (15));
349 read_register_gen (A0_REGNUM, (char *)&num1);
350 read_register_gen (A0_REGNUM+1, (char *)&num2);
351 printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
81dc176f 352}
7b3fa778
MH
353
354void
355_initialize_d10v_tdep ()
356{
7b3fa778
MH
357 tm_print_insn = print_insn_d10v;
358 add_com ("regs", class_vars, show_regs, "Print all registers");
359}
360
361CORE_ADDR
362d10v_read_register_pid (regno, pid)
363 int regno, pid;
364{
365 int save_pid;
366 CORE_ADDR retval;
367
368 if (pid == inferior_pid)
369 return (read_register(regno)) << 2;
370
371 save_pid = inferior_pid;
372 inferior_pid = pid;
373 retval = read_register (regno);
374 inferior_pid = save_pid;
375 return (retval << 2);
376}
377
378void
379d10v_write_register_pid (regno, val, pid)
380 int regno;
381 LONGEST val;
382 int pid;
383{
384 int save_pid;
385
386 val >>= 2;
387
388 if (pid == inferior_pid)
389 {
390 write_register (regno, val);
391 return;
392 }
393
394 save_pid = inferior_pid;
395 inferior_pid = pid;
396 write_register (regno, val);
397 inferior_pid = save_pid;
398}
This page took 0.04027 seconds and 4 git commands to generate.