* binutils.texi: Add section on reporting bugs.
[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"
3b1af95c
MH
29#include "symfile.h"
30#include "objfiles.h"
7b3fa778 31
e05bda9f 32void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi, struct frame_saved_regs *fsr));
19414cdf 33static void d10v_pop_dummy_frame PARAMS ((struct frame_info *fi));
e05bda9f
MH
34
35/* Discard from the stack the innermost frame,
36 restoring all saved registers. */
37
7b3fa778
MH
38void
39d10v_pop_frame ()
40{
e05bda9f 41 struct frame_info *frame = get_current_frame ();
b70b03b0 42 CORE_ADDR fp;
e05bda9f
MH
43 int regnum;
44 struct frame_saved_regs fsr;
45 char raw_buffer[8];
46
b70b03b0 47 fp = FRAME_FP (frame);
19414cdf
MH
48 printf("pop_frame %x\n",(int)fp);
49 if (frame->dummy)
50 {
51 d10v_pop_dummy_frame(frame);
52 return;
53 }
54
e05bda9f
MH
55 /* fill out fsr with the address of where each */
56 /* register was stored in the frame */
57 get_frame_saved_regs (frame, &fsr);
58
e05bda9f
MH
59 /* now update the current registers with the old values */
60 for (regnum = A0_REGNUM; regnum < A0_REGNUM+2 ; regnum++)
61 {
62 if (fsr.regs[regnum])
63 {
81dc176f 64 read_memory (fsr.regs[regnum], raw_buffer, 8);
e05bda9f
MH
65 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 8);
66 }
67 }
68 for (regnum = 0; regnum < SP_REGNUM; regnum++)
69 {
70 if (fsr.regs[regnum])
71 {
81dc176f 72 write_register (regnum, read_memory_unsigned_integer (fsr.regs[regnum], 2));
e05bda9f
MH
73 }
74 }
75 if (fsr.regs[PSW_REGNUM])
76 {
81dc176f 77 write_register (PSW_REGNUM, read_memory_unsigned_integer (fsr.regs[PSW_REGNUM], 2));
e05bda9f
MH
78 }
79
b70b03b0
MH
80 write_register (PC_REGNUM, read_register(13));
81 write_register (SP_REGNUM, fp + frame->size);
82 target_store_registers (-1);
e05bda9f
MH
83 flush_cached_frames ();
84}
85
86static int
87check_prologue (op)
88 unsigned short op;
89{
90 /* st rn, @-sp */
91 if ((op & 0x7E1F) == 0x6C1F)
92 return 1;
93
94 /* st2w rn, @-sp */
95 if ((op & 0x7E3F) == 0x6E1F)
96 return 1;
97
98 /* subi sp, n */
99 if ((op & 0x7FE1) == 0x01E1)
100 return 1;
101
102 /* mv r11, sp */
103 if (op == 0x417E)
104 return 1;
105
106 /* nop */
107 if (op == 0x5E00)
108 return 1;
109
110 /* st rn, @sp */
111 if ((op & 0x7E1F) == 0x681E)
112 return 1;
113
114 /* st2w rn, @sp */
115 if ((op & 0x7E3F) == 0x3A1E)
116 return 1;
117
e05bda9f 118 return 0;
7b3fa778
MH
119}
120
121CORE_ADDR
e05bda9f
MH
122d10v_skip_prologue (pc)
123 CORE_ADDR pc;
7b3fa778 124{
e05bda9f
MH
125 unsigned long op;
126 unsigned short op1, op2;
127
128 if (target_read_memory (pc, (char *)&op, 4))
129 return pc; /* Can't access it -- assume no prologue. */
130
131 while (1)
132 {
81dc176f 133 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
134 if ((op & 0xC0000000) == 0xC0000000)
135 {
136 /* long instruction */
137 if ( ((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */
138 ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */
139 ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */
140 break;
141 }
142 else
143 {
144 /* short instructions */
145 op1 = (op & 0x3FFF8000) >> 15;
146 op2 = op & 0x7FFF;
147 if (!check_prologue(op1) || !check_prologue(op2))
148 break;
149 }
150 pc += 4;
151 }
152 return pc;
7b3fa778 153}
19414cdf 154
e05bda9f
MH
155/* Given a GDB frame, determine the address of the calling function's frame.
156 This will be used to create a new GDB frame struct, and then
157 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
81dc176f 158*/
e05bda9f 159
7b3fa778
MH
160CORE_ADDR
161d10v_frame_chain (frame)
162 struct frame_info *frame;
163{
e05bda9f 164 struct frame_saved_regs fsr;
3b1af95c
MH
165
166 if (inside_entry_file (frame->pc))
167 return 0;
168
e05bda9f 169 d10v_frame_find_saved_regs (frame, &fsr);
3b1af95c
MH
170
171 if (!fsr.regs[FP_REGNUM])
172 {
19414cdf 173 return (CORE_ADDR)fsr.regs[SP_REGNUM]+0x2000000;
3b1af95c 174 }
19414cdf 175 return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],2)+0x2000000;
7b3fa778
MH
176}
177
e05bda9f
MH
178static int next_addr;
179
180static int
181prologue_find_regs (op, fsr, addr)
182 unsigned short op;
183 struct frame_saved_regs *fsr;
184 CORE_ADDR addr;
185{
186 int n;
187
188 /* st rn, @-sp */
189 if ((op & 0x7E1F) == 0x6C1F)
190 {
191 n = (op & 0x1E0) >> 5;
192 next_addr -= 2;
193 fsr->regs[n] = next_addr;
194 return 1;
195 }
196
197 /* st2w rn, @-sp */
198 else if ((op & 0x7E3F) == 0x6E1F)
199 {
200 n = (op & 0x1E0) >> 5;
201 next_addr -= 4;
202 fsr->regs[n] = next_addr;
203 fsr->regs[n+1] = next_addr+2;
204 return 1;
205 }
206
207 /* subi sp, n */
208 if ((op & 0x7FE1) == 0x01E1)
209 {
210 n = (op & 0x1E) >> 1;
211 if (n == 0)
212 n = 16;
213 next_addr -= n;
214 return 1;
215 }
216
217 /* mv r11, sp */
218 if (op == 0x417E)
3b1af95c 219 return 1;
e05bda9f
MH
220
221 /* nop */
222 if (op == 0x5E00)
223 return 1;
224
225 /* st rn, @sp */
226 if ((op & 0x7E1F) == 0x681E)
227 {
228 n = (op & 0x1E0) >> 5;
229 fsr->regs[n] = next_addr;
230 return 1;
231 }
232
233 /* st2w rn, @sp */
234 if ((op & 0x7E3F) == 0x3A1E)
235 {
236 n = (op & 0x1E0) >> 5;
237 fsr->regs[n] = next_addr;
238 fsr->regs[n+1] = next_addr+2;
239 return 1;
240 }
241
242 return 0;
243}
244
7b3fa778
MH
245/* Put here the code to store, into a struct frame_saved_regs, the
246 addresses of the saved registers of frame described by FRAME_INFO.
247 This includes special registers such as pc and fp saved in special
248 ways in the stack frame. sp is even more special: the address we
249 return for it IS the sp for the next frame. */
250void
251d10v_frame_find_saved_regs (fi, fsr)
252 struct frame_info *fi;
253 struct frame_saved_regs *fsr;
e05bda9f
MH
254{
255 CORE_ADDR fp, pc;
256 unsigned long op;
257 unsigned short op1, op2;
258 int i;
259
260 fp = fi->frame;
261 memset (fsr, 0, sizeof (*fsr));
262 next_addr = 0;
263
264 pc = get_pc_function_start (fi->pc);
265
266 while (1)
267 {
81dc176f 268 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
269 if ((op & 0xC0000000) == 0xC0000000)
270 {
271 /* long instruction */
272 if ((op & 0x3FFF0000) == 0x01FF0000)
273 {
274 /* add3 sp,sp,n */
275 short n = op & 0xFFFF;
276 next_addr += n;
277 }
278 else if ((op & 0x3F0F0000) == 0x340F0000)
279 {
280 /* st rn, @(offset,sp) */
281 short offset = op & 0xFFFF;
282 short n = (op >> 20) & 0xF;
283 fsr->regs[n] = next_addr + offset;
284 }
285 else if ((op & 0x3F1F0000) == 0x350F0000)
286 {
287 /* st2w rn, @(offset,sp) */
288 short offset = op & 0xFFFF;
289 short n = (op >> 20) & 0xF;
290 fsr->regs[n] = next_addr + offset;
291 fsr->regs[n+1] = next_addr + offset + 2;
292 }
293 else
294 break;
295 }
296 else
297 {
298 /* short instructions */
299 op1 = (op & 0x3FFF8000) >> 15;
300 op2 = op & 0x7FFF;
301 if (!prologue_find_regs(op1,fsr,pc) || !prologue_find_regs(op2,fsr,pc))
302 break;
303 }
304 pc += 4;
305 }
306
307 fi->size = -next_addr;
e05bda9f 308
3b1af95c 309 for (i=0; i<NUM_REGS-1; i++)
e05bda9f
MH
310 if (fsr->regs[i])
311 {
312 fsr->regs[i] = fp - (next_addr - fsr->regs[i]);
e05bda9f 313 }
81dc176f
MH
314
315 if (fsr->regs[13])
19414cdf 316 fi->return_pc = ((read_memory_unsigned_integer(fsr->regs[13],2)-1) << 2) + 0x1000000;
81dc176f 317 else
19414cdf 318 fi->return_pc = ((read_register(13) - 1) << 2) + 0x1000000;
b70b03b0 319
3b1af95c 320 /* th SP is not normally (ever?) saved, but check anyway */
b70b03b0 321 if (!fsr->regs[SP_REGNUM])
3b1af95c
MH
322 {
323 /* if the FP was saved, that means the current FP is valid, */
324 /* otherwise, it isn't being used, so we use the SP instead */
325 if (fsr->regs[FP_REGNUM])
326 fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
327 else
328 fsr->regs[SP_REGNUM] = read_register(SP_REGNUM) + fi->size;
329 }
7b3fa778
MH
330}
331
332void
333d10v_init_extra_frame_info (fromleaf, fi)
334 int fromleaf;
335 struct frame_info *fi;
336{
337 struct frame_saved_regs dummy;
e05bda9f 338
3b1af95c 339 if (fi->next && (fi->pc == 0))
81dc176f
MH
340 fi->pc = fi->next->return_pc;
341
19414cdf
MH
342 /*
343 printf("init_extra_frame_info: fi->pc=%x frame=%x PC=%x SP=%x\n",
344 (int)fi->pc,(int)fi->frame,(int)read_register(PC_REGNUM)<<2,(int)read_register(SP_REGNUM));
345 */
346
e05bda9f 347 d10v_frame_find_saved_regs (fi, &dummy);
3b1af95c
MH
348 if (!dummy.regs[FP_REGNUM])
349 {
19414cdf
MH
350 /* printf("init_extra_frame_info: sp=%x size=%x\n",dummy.regs[SP_REGNUM],fi->size);; */
351 fi->frame = dummy.regs[SP_REGNUM] - fi->size + 0x2000000;
3b1af95c 352 d10v_frame_find_saved_regs (fi, &dummy);
19414cdf
MH
353 }
354 /* printf("init_extra_frame_info end: pc=%x frame=%x\n",(int)fi->pc,(int)fi->frame); */
7b3fa778
MH
355}
356
357static void
358show_regs (args, from_tty)
359 char *args;
360 int from_tty;
361{
362 long long num1, num2;
363 printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
364 read_register (PC_REGNUM), read_register (PC_REGNUM) << 2,
365 read_register (PSW_REGNUM),
366 read_register (24),
367 read_register (25),
368 read_register (23));
369 printf_filtered ("R0-R7 %04x %04x %04x %04x %04x %04x %04x %04x\n",
370 read_register (0),
371 read_register (1),
372 read_register (2),
373 read_register (3),
374 read_register (4),
375 read_register (5),
376 read_register (6),
377 read_register (7));
378 printf_filtered ("R8-R15 %04x %04x %04x %04x %04x %04x %04x %04x\n",
379 read_register (8),
380 read_register (9),
381 read_register (10),
382 read_register (11),
383 read_register (12),
384 read_register (13),
385 read_register (14),
386 read_register (15));
19414cdf
MH
387 printf_filtered ("IMAP0 %04x IMAP1 %04x DMAP %04x\n",
388 read_register (IMAP0_REGNUM),
389 read_register (IMAP1_REGNUM),
390 read_register (DMAP_REGNUM));
7b3fa778
MH
391 read_register_gen (A0_REGNUM, (char *)&num1);
392 read_register_gen (A0_REGNUM+1, (char *)&num2);
393 printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
81dc176f 394}
7b3fa778
MH
395
396void
397_initialize_d10v_tdep ()
398{
7b3fa778
MH
399 tm_print_insn = print_insn_d10v;
400 add_com ("regs", class_vars, show_regs, "Print all registers");
401}
402
19414cdf
MH
403static CORE_ADDR
404d10v_xlate_addr (addr)
405 int addr;
7b3fa778 406{
19414cdf
MH
407 int imap;
408
409 if (addr < 0x20000)
410 imap = (int)read_register(IMAP0_REGNUM);
411 else
412 imap = (int)read_register(IMAP1_REGNUM);
7b3fa778 413
19414cdf
MH
414 if (imap & 0x1000)
415 return (CORE_ADDR)(addr + 0x1000000);
416 return (CORE_ADDR)(addr + (imap & 0xff)*0x20000);
417}
418
419
420CORE_ADDR
421d10v_read_pc (pid)
422 int pid;
423{
424 int save_pid, retval;
7b3fa778
MH
425
426 save_pid = inferior_pid;
427 inferior_pid = pid;
19414cdf 428 retval = (int)read_register (PC_REGNUM);
7b3fa778 429 inferior_pid = save_pid;
19414cdf 430 return d10v_xlate_addr(retval << 2);
7b3fa778
MH
431}
432
433void
19414cdf 434d10v_write_pc (val, pid)
7b3fa778
MH
435 LONGEST val;
436 int pid;
437{
438 int save_pid;
439
7b3fa778
MH
440 save_pid = inferior_pid;
441 inferior_pid = pid;
19414cdf 442 write_register (PC_REGNUM, (val & 0x3ffff) >> 2);
7b3fa778
MH
443 inferior_pid = save_pid;
444}
3b1af95c 445
19414cdf
MH
446CORE_ADDR
447d10v_read_fp ()
448{
449 return (read_register(FP_REGNUM) + 0x2000000);
450}
451
452void
453d10v_write_fp (val)
454 LONGEST val;
455{
456 write_register (FP_REGNUM, val & 0xffff);
457}
3b1af95c
MH
458
459void
460d10v_fix_call_dummy (dummyname, start_sp, fun, nargs, args, type, gcc_p)
461 char *dummyname;
462 CORE_ADDR start_sp;
463 CORE_ADDR fun;
464 int nargs;
465 value_ptr *args;
466 struct type *type;
467 int gcc_p;
468{
469 int regnum, i;
470 CORE_ADDR sp;
471 char buffer[MAX_REGISTER_RAW_SIZE];
19414cdf
MH
472 struct frame_info *frame = get_current_frame ();
473 frame->dummy = 1;
474 printf("D10v_fix_call_dummy: %x %x %d frame=%x\n",(int)start_sp,(int)fun,nargs,(int)frame->frame);
3b1af95c
MH
475 sp = start_sp;
476 for (regnum = 0; regnum < NUM_REGS-1; regnum++)
477 {
478 store_address (buffer, REGISTER_RAW_SIZE(regnum), read_register(regnum));
479 write_memory (sp, buffer, REGISTER_RAW_SIZE(regnum));
480 sp -= REGISTER_RAW_SIZE(regnum);
481 }
482 write_register (SP_REGNUM, (LONGEST)sp);
19414cdf
MH
483 printf("writing %x to sp\n",(int)sp);
484 /* now we need to load LR with the return address */
3b1af95c 485 write_register (LR_REGNUM, (LONGEST)d10v_call_dummy_address()>>2);
3b1af95c
MH
486}
487
19414cdf
MH
488static void
489d10v_pop_dummy_frame (fi)
490 struct frame_info *fi;
491{
492 printf("pop_dummy_frame: start_sp=%x\n",(int)fi->frame);
493 /*
494 sp = start_sp;
495 for (regnum = 0; regnum < NUM_REGS-1; regnum++)
496 {
497 store_address (buffer, REGISTER_RAW_SIZE(regnum), read_register(regnum));
498 write_memory (sp, buffer, REGISTER_RAW_SIZE(regnum));
499 sp -= REGISTER_RAW_SIZE(regnum);
500 }
501 */
502}
503
504
3b1af95c
MH
505CORE_ADDR
506d10v_push_arguments (nargs, args, sp, struct_return, struct_addr)
507 int nargs;
508 value_ptr *args;
509 CORE_ADDR sp;
510 int struct_return;
511 CORE_ADDR struct_addr;
512{
513 int i, len, regnum=2;
514 char *contents;
19414cdf
MH
515 LONGEST val;
516
3b1af95c
MH
517 for (i = 0; i < nargs; i++)
518 {
519 value_ptr arg = args[i];
520 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
521 switch (TYPE_CODE (arg_type))
19414cdf 522 {
3b1af95c
MH
523 case TYPE_CODE_INT:
524 case TYPE_CODE_BOOL:
525 case TYPE_CODE_CHAR:
526 case TYPE_CODE_RANGE:
527 case TYPE_CODE_ENUM:
528 break;
529 default:
530 break;
531 }
532 len = TYPE_LENGTH (arg_type);
533 contents = VALUE_CONTENTS(arg);
19414cdf
MH
534 val = extract_signed_integer (contents, len);
535 printf("arg %d: len=%d contents=%x\n",i,len,(int)val);
536 if (len == 4)
537 write_register (regnum++, val>>16);
538 write_register (regnum++, val & 0xffff);
3b1af95c
MH
539 }
540}
541
19414cdf 542
3b1af95c
MH
543CORE_ADDR
544d10v_call_dummy_address ()
545{
19414cdf 546 CORE_ADDR entry;
3b1af95c
MH
547 struct minimal_symbol *sym;
548
549 entry = entry_point_address ();
550
551 if (entry != 0)
19414cdf 552 return entry;
3b1af95c
MH
553
554 sym = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
555
556 if (!sym || MSYMBOL_TYPE (sym) != mst_text)
19414cdf 557 return 0;
3b1af95c 558 else
19414cdf 559 return SYMBOL_VALUE_ADDRESS (sym);
3b1af95c
MH
560}
561
562/* Given a return value in `regbuf' with a type `valtype',
563 extract and copy its value into `valbuf'. */
564
565void
566d10v_extract_return_value (valtype, regbuf, valbuf)
567 struct type *valtype;
568 char regbuf[REGISTER_BYTES];
569 char *valbuf;
570{
19414cdf
MH
571 printf("EXTRACT: regbuf=%x, *regbuf=%x %x %x %x len=%d %d\n",(int)regbuf,*(int *)regbuf,
572 *(int *)(regbuf+4),*(int *)(regbuf+8),*(int *)(regbuf+12),TYPE_LENGTH (valtype),REGISTER_BYTE (2) );
3b1af95c
MH
573 memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
574}
This page took 0.053972 seconds and 4 git commands to generate.