* interp.c (CHECKHILO): Don't set HIACCESS, LOACCESS, or HLPC.
[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"
25#include "value.h"
26#include "inferior.h"
27#include "dis-asm.h"
28
e05bda9f
MH
29void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi, struct frame_saved_regs *fsr));
30
31/* Discard from the stack the innermost frame,
32 restoring all saved registers. */
33
7b3fa778
MH
34void
35d10v_pop_frame ()
36{
e05bda9f
MH
37 struct frame_info *frame = get_current_frame ();
38 CORE_ADDR fp, r13;
39 int regnum;
40 struct frame_saved_regs fsr;
41 char raw_buffer[8];
42
43 fp = FRAME_FP (frame);
44 /* printf("pop_frame 0x%x\n",fp); */
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. */
51 r13 = read_register (13);
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 {
58 read_memory (fsr.regs[regnum] & 0xFFFF, raw_buffer, 8);
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 {
66 write_register (regnum, read_memory_integer (fsr.regs[regnum] & 0xFFFF, 2));
67 }
68 }
69 if (fsr.regs[PSW_REGNUM])
70 {
71 write_register (PSW_REGNUM, read_memory_integer (fsr.regs[PSW_REGNUM] & 0xFFFF, 2));
72 }
73
74 /* PC is set to r13 */
75 write_register (PC_REGNUM, r13);
76 /* printf("setting stack to %x\n",fp - frame->size); */
77 write_register (SP_REGNUM, fp - frame->size);
78 flush_cached_frames ();
79}
80
81static int
82check_prologue (op)
83 unsigned short op;
84{
85 /* st rn, @-sp */
86 if ((op & 0x7E1F) == 0x6C1F)
87 return 1;
88
89 /* st2w rn, @-sp */
90 if ((op & 0x7E3F) == 0x6E1F)
91 return 1;
92
93 /* subi sp, n */
94 if ((op & 0x7FE1) == 0x01E1)
95 return 1;
96
97 /* mv r11, sp */
98 if (op == 0x417E)
99 return 1;
100
101 /* nop */
102 if (op == 0x5E00)
103 return 1;
104
105 /* st rn, @sp */
106 if ((op & 0x7E1F) == 0x681E)
107 return 1;
108
109 /* st2w rn, @sp */
110 if ((op & 0x7E3F) == 0x3A1E)
111 return 1;
112
113
114 return 0;
7b3fa778
MH
115}
116
117CORE_ADDR
e05bda9f
MH
118d10v_skip_prologue (pc)
119 CORE_ADDR pc;
7b3fa778 120{
e05bda9f
MH
121 unsigned long op;
122 unsigned short op1, op2;
123
124 if (target_read_memory (pc, (char *)&op, 4))
125 return pc; /* Can't access it -- assume no prologue. */
126
127 while (1)
128 {
129 op = read_memory_integer (pc, 4);
130 if ((op & 0xC0000000) == 0xC0000000)
131 {
132 /* long instruction */
133 if ( ((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */
134 ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */
135 ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */
136 break;
137 }
138 else
139 {
140 /* short instructions */
141 op1 = (op & 0x3FFF8000) >> 15;
142 op2 = op & 0x7FFF;
143 if (!check_prologue(op1) || !check_prologue(op2))
144 break;
145 }
146 pc += 4;
147 }
148 return pc;
7b3fa778
MH
149}
150
e05bda9f
MH
151/* Given a GDB frame, determine the address of the calling function's frame.
152 This will be used to create a new GDB frame struct, and then
153 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
154
155 For us, the frame address is its stack pointer value, so we look up
156 the function prologue to determine the caller's sp value, and return it. */
157
7b3fa778
MH
158CORE_ADDR
159d10v_frame_chain (frame)
160 struct frame_info *frame;
161{
e05bda9f
MH
162 struct frame_saved_regs fsr;
163 /* printf("frame_chain %x\n",frame->frame); */
164 d10v_frame_find_saved_regs (frame, &fsr);
165 /* printf("pc=%x\n",fsr.regs[PC_REGNUM]);
166 printf("fp=%x (%x)\n",fsr.regs[FP_REGNUM],read_memory_integer(fsr.regs[FP_REGNUM],2) & 0xffff); */
167 return read_memory_integer(fsr.regs[FP_REGNUM],2) & 0xffff;
7b3fa778
MH
168}
169
e05bda9f
MH
170static int next_addr;
171
172static int
173prologue_find_regs (op, fsr, addr)
174 unsigned short op;
175 struct frame_saved_regs *fsr;
176 CORE_ADDR addr;
177{
178 int n;
179
180 /* st rn, @-sp */
181 if ((op & 0x7E1F) == 0x6C1F)
182 {
183 n = (op & 0x1E0) >> 5;
184 next_addr -= 2;
185 fsr->regs[n] = next_addr;
186 return 1;
187 }
188
189 /* st2w rn, @-sp */
190 else if ((op & 0x7E3F) == 0x6E1F)
191 {
192 n = (op & 0x1E0) >> 5;
193 next_addr -= 4;
194 fsr->regs[n] = next_addr;
195 fsr->regs[n+1] = next_addr+2;
196 return 1;
197 }
198
199 /* subi sp, n */
200 if ((op & 0x7FE1) == 0x01E1)
201 {
202 n = (op & 0x1E) >> 1;
203 if (n == 0)
204 n = 16;
205 next_addr -= n;
206 return 1;
207 }
208
209 /* mv r11, sp */
210 if (op == 0x417E)
211 return 1;
212
213 /* nop */
214 if (op == 0x5E00)
215 return 1;
216
217 /* st rn, @sp */
218 if ((op & 0x7E1F) == 0x681E)
219 {
220 n = (op & 0x1E0) >> 5;
221 fsr->regs[n] = next_addr;
222 return 1;
223 }
224
225 /* st2w rn, @sp */
226 if ((op & 0x7E3F) == 0x3A1E)
227 {
228 n = (op & 0x1E0) >> 5;
229 fsr->regs[n] = next_addr;
230 fsr->regs[n+1] = next_addr+2;
231 return 1;
232 }
233
234 return 0;
235}
236
7b3fa778
MH
237/* Put here the code to store, into a struct frame_saved_regs, the
238 addresses of the saved registers of frame described by FRAME_INFO.
239 This includes special registers such as pc and fp saved in special
240 ways in the stack frame. sp is even more special: the address we
241 return for it IS the sp for the next frame. */
242void
243d10v_frame_find_saved_regs (fi, fsr)
244 struct frame_info *fi;
245 struct frame_saved_regs *fsr;
e05bda9f
MH
246{
247 CORE_ADDR fp, pc;
248 unsigned long op;
249 unsigned short op1, op2;
250 int i;
251
252 fp = fi->frame;
253 memset (fsr, 0, sizeof (*fsr));
254 next_addr = 0;
255
256 pc = get_pc_function_start (fi->pc);
257
258 while (1)
259 {
260 op = read_memory_integer (pc, 4);
261 if ((op & 0xC0000000) == 0xC0000000)
262 {
263 /* long instruction */
264 if ((op & 0x3FFF0000) == 0x01FF0000)
265 {
266 /* add3 sp,sp,n */
267 short n = op & 0xFFFF;
268 next_addr += n;
269 }
270 else if ((op & 0x3F0F0000) == 0x340F0000)
271 {
272 /* st rn, @(offset,sp) */
273 short offset = op & 0xFFFF;
274 short n = (op >> 20) & 0xF;
275 fsr->regs[n] = next_addr + offset;
276 }
277 else if ((op & 0x3F1F0000) == 0x350F0000)
278 {
279 /* st2w rn, @(offset,sp) */
280 short offset = op & 0xFFFF;
281 short n = (op >> 20) & 0xF;
282 fsr->regs[n] = next_addr + offset;
283 fsr->regs[n+1] = next_addr + offset + 2;
284 }
285 else
286 break;
287 }
288 else
289 {
290 /* short instructions */
291 op1 = (op & 0x3FFF8000) >> 15;
292 op2 = op & 0x7FFF;
293 if (!prologue_find_regs(op1,fsr,pc) || !prologue_find_regs(op2,fsr,pc))
294 break;
295 }
296 pc += 4;
297 }
298
299 fi->size = -next_addr;
300 fi->return_pc = read_register (13);
301
302 for (i=0; i<NUM_REGS; i++)
303 if (fsr->regs[i])
304 {
305 fsr->regs[i] = fp - (next_addr - fsr->regs[i]);
306 /* printf("register %d = *(%x) = %x\n",i,fsr->regs[i],read_memory_integer((fsr->regs[i]) & 0xffff, 2)); */
307 }
7b3fa778
MH
308}
309
310void
311d10v_init_extra_frame_info (fromleaf, fi)
312 int fromleaf;
313 struct frame_info *fi;
314{
315 struct frame_saved_regs dummy;
e05bda9f
MH
316 /* printf("extra init %x next=%x pc=%x\n",fi->frame,fi->next,fi->pc); */
317
318 /* fi->pc = fi->next->return_pc; */
319 d10v_frame_find_saved_regs (fi, &dummy);
320 /* printf(" %x next=%x pc=%x\n",fi->frame,fi->next,fi->pc); */
7b3fa778
MH
321}
322
323static void
324show_regs (args, from_tty)
325 char *args;
326 int from_tty;
327{
328 long long num1, num2;
329 printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
330 read_register (PC_REGNUM), read_register (PC_REGNUM) << 2,
331 read_register (PSW_REGNUM),
332 read_register (24),
333 read_register (25),
334 read_register (23));
335 printf_filtered ("R0-R7 %04x %04x %04x %04x %04x %04x %04x %04x\n",
336 read_register (0),
337 read_register (1),
338 read_register (2),
339 read_register (3),
340 read_register (4),
341 read_register (5),
342 read_register (6),
343 read_register (7));
344 printf_filtered ("R8-R15 %04x %04x %04x %04x %04x %04x %04x %04x\n",
345 read_register (8),
346 read_register (9),
347 read_register (10),
348 read_register (11),
349 read_register (12),
350 read_register (13),
351 read_register (14),
352 read_register (15));
353 read_register_gen (A0_REGNUM, (char *)&num1);
354 read_register_gen (A0_REGNUM+1, (char *)&num2);
355 printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
356}
357
358void
359_initialize_d10v_tdep ()
360{
361 struct cmd_list_element *c;
362 tm_print_insn = print_insn_d10v;
363 add_com ("regs", class_vars, show_regs, "Print all registers");
364}
365
366CORE_ADDR
367d10v_read_register_pid (regno, pid)
368 int regno, pid;
369{
370 int save_pid;
371 CORE_ADDR retval;
372
373 if (pid == inferior_pid)
374 return (read_register(regno)) << 2;
375
376 save_pid = inferior_pid;
377 inferior_pid = pid;
378 retval = read_register (regno);
379 inferior_pid = save_pid;
380 return (retval << 2);
381}
382
383void
384d10v_write_register_pid (regno, val, pid)
385 int regno;
386 LONGEST val;
387 int pid;
388{
389 int save_pid;
390
391 val >>= 2;
392
393 if (pid == inferior_pid)
394 {
395 write_register (regno, val);
396 return;
397 }
398
399 save_pid = inferior_pid;
400 inferior_pid = pid;
401 write_register (regno, val);
402 inferior_pid = save_pid;
403}
This page took 0.045995 seconds and 4 git commands to generate.