* mi/mi-main.c (enum captured_mi_execute_command_actions)
[deliverable/binutils-gdb.git] / gdb / score-tdep.c
CommitLineData
27fd2f50
Q
1/* Target-dependent code for the S+core architecture, for GDB,
2 the GNU Debugger.
3
9b254dd1 4 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
27fd2f50
Q
5
6 Contributed by Qinwei (qinwei@sunnorth.com.cn)
7 Contributed by Ching-Peng Lin (cplin@sunplus.com)
8
9 This file is part of GDB.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
a9762ec7 13 the Free Software Foundation; either version 3 of the License, or
27fd2f50
Q
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
a9762ec7 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27fd2f50
Q
23
24#include "defs.h"
25#include "gdb_assert.h"
26#include "inferior.h"
27#include "symtab.h"
28#include "objfiles.h"
29#include "gdbcore.h"
30#include "target.h"
31#include "arch-utils.h"
32#include "regcache.h"
33#include "dis-asm.h"
34#include "frame-unwind.h"
35#include "frame-base.h"
36#include "trad-frame.h"
37#include "dwarf2-frame.h"
38#include "score-tdep.h"
39
40#define G_FLD(_i,_ms,_ls) (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
41#define RM_PBITS(_raw) ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0))
42
43typedef struct{
44 unsigned int v;
45 unsigned int raw;
46 char is15;
47}inst_t;
48
49struct score_frame_cache
50{
51 CORE_ADDR base;
5e29c264 52 CORE_ADDR fp;
27fd2f50
Q
53 struct trad_frame_saved_reg *saved_regs;
54};
55
56#if 0
57/* If S+core GCC will generate these instructions in the prologue:
58
59 lw rx, imm1
60 addi rx, -imm2
61 mv! r2, rx
62
63 then .pdr section is used. */
64
65#define P_SIZE 8
66#define PI_SYM 0
67#define PI_R_MSK 1
68#define PI_R_OFF 2
69#define PI_R_LEF 4
70#define PI_F_OFF 5
71#define PI_F_REG 6
72#define PI_RAREG 7
73
74typedef struct frame_extra_info
75{
76 CORE_ADDR p_frame;
77 unsigned int pdr[P_SIZE];
78} extra_info_t;
79
80struct obj_priv
81{
82 bfd_size_type size;
83 char *contents;
84};
85
86static bfd *the_bfd;
87
88static int
89score_compare_pdr_entries (const void *a, const void *b)
90{
91 CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a);
92 CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b);
93 if (lhs < rhs)
94 return -1;
95 else if (lhs == rhs)
96 return 0;
97 else
98 return 1;
99}
100
101static void
102score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc,
103 struct frame_info *next_frame,
104 struct score_frame_cache *this_cache)
105{
106 struct symbol *sym;
107 struct obj_section *sec;
108 extra_info_t *fci_ext;
109 CORE_ADDR leaf_ra_stack_addr = -1;
110
111 gdb_assert (startaddr <= pc);
112 gdb_assert (this_cache != NULL);
113
114 fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
115 if ((sec = find_pc_section (pc)) == NULL)
116 {
5e29c264
Q
117 error ("Error: Can't find section in file:%s, line:%d!",
118 __FILE__, __LINE__);
27fd2f50
Q
119 return;
120 }
121
122 /* Anylyze .pdr section and get coresponding fields. */
123 {
124 static struct obj_priv *priv = NULL;
125
126 if (priv == NULL)
127 {
128 asection *bfdsec;
129 priv = obstack_alloc (&sec->objfile->objfile_obstack,
130 sizeof (struct obj_priv));
131 if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr")))
132 {
133 priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
134 priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
135 priv->size);
136 bfd_get_section_contents (sec->objfile->obfd, bfdsec,
137 priv->contents, 0, priv->size);
138 the_bfd = sec->objfile->obfd;
139 qsort (priv->contents, priv->size / 32, 32,
140 score_compare_pdr_entries);
141 the_bfd = NULL;
142 }
143 else
144 priv->size = 0;
145 }
146 if (priv->size != 0)
147 {
148 int low = 0, mid, high = priv->size / 32;
149 char *ptr;
150 do
27fd2f50
Q
151 {
152 CORE_ADDR pdr_pc;
153 mid = (low + high) / 2;
154 ptr = priv->contents + mid * 32;
155 pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
156 pdr_pc += ANOFFSET (sec->objfile->section_offsets,
157 SECT_OFF_TEXT (sec->objfile));
158 if (pdr_pc == startaddr)
159 break;
160 if (pdr_pc > startaddr)
161 high = mid;
162 else
163 low = mid + 1;
164 }
165 while (low != high);
166
167 if (low != high)
168 {
169 gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr);
170#define EXT_PDR(_pi) bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2))
171 fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM);
172 fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK);
173 fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF);
174 fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF);
175 fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF);
176 fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG);
177 fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG);
178#undef EXT_PDR
179 }
180 }
181 }
182}
183#endif
184
5e29c264
Q
185#if 0
186/* Open these functions if build with simulator. */
187
188int
189score_target_can_use_watch (int type, int cnt, int othertype)
190{
191 if (strcmp (current_target.to_shortname, "sim") == 0)
192 {
193 return soc_gh_can_use_watch (type, cnt);
194 }
195 else
196 {
197 return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
198 }
199}
200
201int
202score_stopped_by_watch (void)
203{
204 if (strcmp (current_target.to_shortname, "sim") == 0)
205 {
206 return soc_gh_stopped_by_watch ();
207 }
208 else
209 {
210 return (*current_target.to_stopped_by_watchpoint) ();
211 }
212}
213
214int
215score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
216{
217 if (strcmp (current_target.to_shortname, "sim") == 0)
218 {
219 return soc_gh_add_watch (addr, len, type);
220 }
221 else
222 {
223 return (*current_target.to_insert_watchpoint) (addr, len, type);
224 }
225}
226
227int
228score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
229{
230 if (strcmp (current_target.to_shortname, "sim") == 0)
231 {
232 return soc_gh_del_watch (addr, len, type);
233 }
234 else
235 {
236 return (*current_target.to_remove_watchpoint) (addr, len, type);
237 }
238}
239
240int
241score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt)
242{
243 if (strcmp (current_target.to_shortname, "sim") == 0)
244 {
245 return soc_gh_add_hardbp (bp_tgt->placed_address);
246 }
247 else
248 {
249 return (*current_target.to_insert_hw_breakpoint) (bp_tgt);
250 }
251}
252
253int
254score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt)
255{
256 if (strcmp (current_target.to_shortname, "sim") == 0)
257 {
258 return soc_gh_del_hardbp (bp_tgt->placed_address);
259 }
260 else
261 {
262 return (*current_target.to_remove_hw_breakpoint) (bp_tgt);
263 }
264}
265#endif
266
27fd2f50
Q
267static struct type *
268score_register_type (struct gdbarch *gdbarch, int regnum)
269{
270 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
271 return builtin_type_uint32;
272}
273
27fd2f50 274static CORE_ADDR
30244cd8 275score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
27fd2f50 276{
30244cd8 277 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
27fd2f50
Q
278}
279
280static CORE_ADDR
30244cd8 281score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
27fd2f50 282{
30244cd8 283 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
27fd2f50
Q
284}
285
286static const char *
d93859e2 287score_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50
Q
288{
289 const char *score_register_names[] = {
290 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
291 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
292 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
293 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
294
295 "PSR", "COND", "ECR", "EXCPVEC",
296 "CCR", "EPC", "EMA", "TLBLOCK",
297 "TLBPT", "PEADDR", "TLBRPT", "PEVN",
298 "PECTX", "LIMPFN", "LDMPFN", "PREV",
299 "DREG", "PC", "DSAVE", "COUNTER",
300 "LDCR", "STCR", "CEH", "CEL",
301 };
302
303 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
304 return score_register_names[regnum];
305}
306
307static int
e7faf938 308score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
27fd2f50
Q
309{
310 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
311 return regnum;
312}
313
314static int
315score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
316{
f52cb1b8 317 if (info->endian == BFD_ENDIAN_BIG)
27fd2f50
Q
318 return print_insn_big_score (memaddr, info);
319 else
320 return print_insn_little_score (memaddr, info);
321}
322
323static const gdb_byte *
67d57894
MD
324score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
325 int *lenptr)
27fd2f50
Q
326{
327 gdb_byte buf[SCORE_INSTLEN] = { 0 };
328 int ret;
329 unsigned int raw;
330
331 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
332 {
5e29c264
Q
333 error ("Error: target_read_memory in file:%s, line:%d!",
334 __FILE__, __LINE__);
27fd2f50
Q
335 }
336 raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
337
67d57894 338 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
27fd2f50
Q
339 {
340 if (!(raw & 0x80008000))
341 {
342 /* 16bits instruction. */
343 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
344 *pcptr &= ~0x1;
345 *lenptr = sizeof (big_breakpoint16);
346 return big_breakpoint16;
347 }
348 else
349 {
350 /* 32bits instruction. */
351 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
352 *pcptr &= ~0x3;
353 *lenptr = sizeof (big_breakpoint32);
354 return big_breakpoint32;
355 }
356 }
357 else
358 {
359 if (!(raw & 0x80008000))
360 {
361 /* 16bits instruction. */
362 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
363 *pcptr &= ~0x1;
364 *lenptr = sizeof (little_breakpoint16);
365 return little_breakpoint16;
366 }
367 else
368 {
369 /* 32bits instruction. */
370 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
371 *pcptr &= ~0x3;
372 *lenptr = sizeof (little_breakpoint32);
373 return little_breakpoint32;
374 }
375 }
376}
377
378static CORE_ADDR
379score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
380{
381 return align_down (addr, 16);
382}
383
384static void
385score_xfer_register (struct regcache *regcache, int regnum, int length,
386 enum bfd_endian endian, gdb_byte *readbuf,
387 const gdb_byte *writebuf, int buf_offset)
388{
389 int reg_offset = 0;
390 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
391
392 switch (endian)
393 {
394 case BFD_ENDIAN_BIG:
395 reg_offset = SCORE_REGSIZE - length;
396 break;
397 case BFD_ENDIAN_LITTLE:
398 reg_offset = 0;
399 break;
400 case BFD_ENDIAN_UNKNOWN:
401 reg_offset = 0;
402 break;
403 default:
5e29c264
Q
404 error ("Error: score_xfer_register in file:%s, line:%d!",
405 __FILE__, __LINE__);
27fd2f50
Q
406 }
407
408 if (readbuf != NULL)
409 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
410 readbuf + buf_offset);
411 if (writebuf != NULL)
412 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
413 writebuf + buf_offset);
414}
415
416static enum return_value_convention
c055b101
CV
417score_return_value (struct gdbarch *gdbarch, struct type *func_type,
418 struct type *type, struct regcache *regcache,
27fd2f50
Q
419 gdb_byte * readbuf, const gdb_byte * writebuf)
420{
421 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
422 || TYPE_CODE (type) == TYPE_CODE_UNION
423 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
424 return RETURN_VALUE_STRUCT_CONVENTION;
425 else
426 {
427 int offset;
428 int regnum;
429 for (offset = 0, regnum = SCORE_A0_REGNUM;
430 offset < TYPE_LENGTH (type);
431 offset += SCORE_REGSIZE, regnum++)
432 {
433 int xfer = SCORE_REGSIZE;
434 if (offset + xfer > TYPE_LENGTH (type))
435 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 436 score_xfer_register (regcache, regnum, xfer,
d93859e2 437 gdbarch_byte_order (gdbarch),
27fd2f50
Q
438 readbuf, writebuf, offset);
439 }
440 return RETURN_VALUE_REGISTER_CONVENTION;
441 }
442}
443
444static struct frame_id
5e29c264
Q
445score_unwind_dummy_id (struct gdbarch *gdbarch,
446 struct frame_info *next_frame)
27fd2f50
Q
447{
448 return frame_id_build (
449 frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
450 frame_pc_unwind (next_frame));
451}
452
453static int
454score_type_needs_double_align (struct type *type)
455{
456 enum type_code typecode = TYPE_CODE (type);
457
5e29c264
Q
458 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
459 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
27fd2f50
Q
460 return 1;
461 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
462 {
463 int i, n;
464
465 n = TYPE_NFIELDS (type);
466 for (i = 0; i < n; i++)
467 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
468 return 1;
469 return 0;
470 }
471 return 0;
472}
473
474static CORE_ADDR
475score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
476 struct regcache *regcache, CORE_ADDR bp_addr,
477 int nargs, struct value **args, CORE_ADDR sp,
478 int struct_return, CORE_ADDR struct_addr)
479{
480 int argnum;
481 int argreg;
482 int arglen = 0;
483 CORE_ADDR stack_offset = 0;
484 CORE_ADDR addr = 0;
485
486 /* Step 1, Save RA. */
487 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
488
489 /* Step 2, Make space on the stack for the args. */
490 struct_addr = align_down (struct_addr, 16);
491 sp = align_down (sp, 16);
492 for (argnum = 0; argnum < nargs; argnum++)
493 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
494 SCORE_REGSIZE);
495 sp -= align_up (arglen, 16);
496
497 argreg = SCORE_BEGIN_ARG_REGNUM;
498
5e29c264
Q
499 /* Step 3, Check if struct return then save the struct address to
500 r4 and increase the stack_offset by 4. */
27fd2f50
Q
501 if (struct_return)
502 {
503 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
504 stack_offset += SCORE_REGSIZE;
505 }
506
507 /* Step 4, Load arguments:
5e29c264
Q
508 If arg length is too long (> 4 bytes), then split the arg and
509 save every parts. */
27fd2f50
Q
510 for (argnum = 0; argnum < nargs; argnum++)
511 {
512 struct value *arg = args[argnum];
513 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
514 enum type_code typecode = TYPE_CODE (arg_type);
515 const gdb_byte *val = value_contents (arg);
516 int downward_offset = 0;
1cfd2c3e
JB
517 int odd_sized_struct_p;
518 int arg_last_part_p = 0;
27fd2f50 519
1cfd2c3e
JB
520 arglen = TYPE_LENGTH (arg_type);
521 odd_sized_struct_p = (arglen > SCORE_REGSIZE
5e29c264 522 && arglen % SCORE_REGSIZE != 0);
27fd2f50
Q
523
524 /* If a arg should be aligned to 8 bytes (long long or double),
525 the value should be put to even register numbers. */
526 if (score_type_needs_double_align (arg_type))
527 {
528 if (argreg & 1)
529 argreg++;
530 }
531
532 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
533 the default "downward"/"upward" method:
534
535 Example:
536
537 struct struc
538 {
539 char a; char b; char c;
540 } s = {'a', 'b', 'c'};
541
542 Big endian: s = {X, 'a', 'b', 'c'}
543 Little endian: s = {'a', 'b', 'c', X}
544
545 Where X is a hole. */
546
d93859e2 547 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
548 && (typecode == TYPE_CODE_STRUCT
549 || typecode == TYPE_CODE_UNION)
550 && argreg > SCORE_LAST_ARG_REGNUM
551 && arglen < SCORE_REGSIZE)
552 downward_offset += (SCORE_REGSIZE - arglen);
553
554 while (arglen > 0)
555 {
556 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
557 ULONGEST regval = extract_unsigned_integer (val, partial_len);
558
559 /* The last part of a arg should shift left when
4c6b5505 560 gdbarch_byte_order is BFD_ENDIAN_BIG. */
d93859e2 561 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
562 && arg_last_part_p == 1
563 && (typecode == TYPE_CODE_STRUCT
564 || typecode == TYPE_CODE_UNION))
565 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
566
567 /* Always increase the stack_offset and save args to stack. */
568 addr = sp + stack_offset + downward_offset;
569 write_memory (addr, val, partial_len);
570
571 if (argreg <= SCORE_LAST_ARG_REGNUM)
572 {
573 regcache_cooked_write_unsigned (regcache, argreg++, regval);
574 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
575 arg_last_part_p = 1;
576 }
577
578 val += partial_len;
579 arglen -= partial_len;
580 stack_offset += align_up (partial_len, SCORE_REGSIZE);
581 }
582 }
583
584 /* Step 5, Save SP. */
585 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
586
587 return sp;
588}
589
5e29c264
Q
590static char *
591score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
592{
593 int ret;
594 char *memblock = NULL;
595
596 if (size < 0)
597 {
598 error ("Error: malloc size < 0 in file:%s, line:%d!",
599 __FILE__, __LINE__);
600 return NULL;
601 }
602 else if (size == 0)
603 return NULL;
604
605 memblock = (char *) xmalloc (size);
606 memset (memblock, 0, size);
607 ret = target_read_memory (addr & ~0x3, memblock, size);
608 if (ret)
609 {
610 error ("Error: target_read_memory in file:%s, line:%d!",
611 __FILE__, __LINE__);
612 return NULL;
613 }
614 return memblock;
615}
616
617static void
618score_free_memblock (char *memblock)
619{
620 xfree (memblock);
621}
622
623static void
624score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
625 CORE_ADDR cur_pc)
626{
627 if (prev_pc == -1)
628 {
629 /* First time call this function, do nothing. */
630 }
631 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
632 {
633 /* First 16-bit instruction, then 32-bit instruction. */
634 *memblock += SCORE_INSTLEN;
635 }
636 else if (cur_pc - prev_pc == 4)
637 {
638 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
639 *memblock += SCORE_INSTLEN;
640 }
641}
642
27fd2f50 643static inst_t *
be8626e0 644score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
27fd2f50
Q
645{
646 static inst_t inst = { 0, 0 };
5e29c264 647 char buf[SCORE_INSTLEN] = { 0 };
27fd2f50 648 int big;
5e29c264 649 int ret;
27fd2f50 650
5e29c264 651 if (target_has_execution && memblock != NULL)
27fd2f50 652 {
5e29c264
Q
653 /* Fetch instruction from local MEMBLOCK. */
654 memcpy (buf, memblock, SCORE_INSTLEN);
655 }
656 else
657 {
658 /* Fetch instruction from target. */
659 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
660 if (ret)
661 {
662 error ("Error: target_read_memory in file:%s, line:%d!",
663 __FILE__, __LINE__);
664 return 0;
665 }
27fd2f50 666 }
5e29c264 667
27fd2f50
Q
668 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
669 inst.is15 = !(inst.raw & 0x80008000);
670 inst.v = RM_PBITS (inst.raw);
be8626e0 671 big = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG);
27fd2f50
Q
672 if (inst.is15)
673 {
674 if (big ^ ((addr & 0x2) == 2))
675 inst.v = G_FLD (inst.v, 29, 15);
676 else
677 inst.v = G_FLD (inst.v, 14, 0);
678 }
679 return &inst;
680}
681
682static CORE_ADDR
6093d2eb 683score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
684{
685 CORE_ADDR cpc = pc;
686 int iscan = 32, stack_sub = 0;
687 while (iscan-- > 0)
688 {
be8626e0 689 inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
690 if (!inst)
691 break;
692 if (!inst->is15 && !stack_sub
693 && (G_FLD (inst->v, 29, 25) == 0x1
694 && G_FLD (inst->v, 24, 20) == 0x0))
695 {
696 /* addi r0, offset */
697 pc = stack_sub = cpc + SCORE_INSTLEN;
698 }
699 else if (!inst->is15
700 && inst->v == RM_PBITS (0x8040bc56))
701 {
702 /* mv r2, r0 */
703 pc = cpc + SCORE_INSTLEN;
704 break;
705 }
706 else if (inst->is15
707 && inst->v == RM_PBITS (0x0203))
708 {
709 /* mv! r2, r0 */
710 pc = cpc + SCORE16_INSTLEN;
711 break;
712 }
713 else if (inst->is15
714 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
715 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
716 || (G_FLD (inst->v, 14, 12) == 0x0
717 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
718 break;
719 else if (!inst->is15
720 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
721 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
722 || (G_FLD (inst->v, 29, 25) == 0x0
723 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
724 break;
725
726 cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
727 }
728 return pc;
729}
730
731static int
732score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
733{
be8626e0 734 inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL);
27fd2f50
Q
735
736 if (inst->v == 0x23)
737 return 1; /* mv! r0, r2 */
738 else if (G_FLD (inst->v, 14, 12) == 0x2
739 && G_FLD (inst->v, 3, 0) == 0xa)
740 return 1; /* pop! */
741 else if (G_FLD (inst->v, 14, 12) == 0x0
742 && G_FLD (inst->v, 7, 0) == 0x34)
743 return 1; /* br! r3 */
744 else if (G_FLD (inst->v, 29, 15) == 0x2
745 && G_FLD (inst->v, 6, 1) == 0x2b)
746 return 1; /* mv r0, r2 */
747 else if (G_FLD (inst->v, 29, 25) == 0x0
748 && G_FLD (inst->v, 6, 1) == 0x4
749 && G_FLD (inst->v, 19, 15) == 0x3)
750 return 1; /* br r3 */
751 else
752 return 0;
753}
754
755static void
756score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
757 struct frame_info *next_frame,
758 struct score_frame_cache *this_cache)
759{
be8626e0 760 struct gdbarch *gdbarch = get_frame_arch (next_frame);
27fd2f50 761 CORE_ADDR sp;
5e29c264 762 CORE_ADDR fp;
27fd2f50
Q
763 CORE_ADDR cur_pc = startaddr;
764
765 int sp_offset = 0;
766 int ra_offset = 0;
767 int fp_offset = 0;
768 int ra_offset_p = 0;
769 int fp_offset_p = 0;
770 int inst_len = 0;
771
5e29c264
Q
772 char *memblock = NULL;
773 char *memblock_ptr = NULL;
774 CORE_ADDR prev_pc = -1;
775
776 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
777 memblock_ptr = memblock =
778 score_malloc_and_get_memblock (startaddr, pc - startaddr);
779
27fd2f50 780 sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
5e29c264 781 fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
27fd2f50 782
5e29c264 783 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
27fd2f50 784 {
5e29c264
Q
785 inst_t *inst = NULL;
786 if (memblock != NULL)
787 {
788 /* Reading memory block from target succefully and got all
789 the instructions(from STARTADDR to PC) needed. */
790 score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
be8626e0 791 inst = score_fetch_inst (gdbarch, cur_pc, memblock);
5e29c264
Q
792 }
793 else
794 {
795 /* Otherwise, we fetch 4 bytes from target, and GDB also
796 work correctly. */
be8626e0 797 inst = score_fetch_inst (gdbarch, cur_pc, NULL);
5e29c264
Q
798 }
799
27fd2f50
Q
800 if (inst->is15 == 1)
801 {
802 inst_len = SCORE16_INSTLEN;
803
804 if (G_FLD (inst->v, 14, 12) == 0x2
805 && G_FLD (inst->v, 3, 0) == 0xe)
806 {
807 /* push! */
808 sp_offset += 4;
809
810 if (G_FLD (inst->v, 11, 7) == 0x6
811 && ra_offset_p == 0)
812 {
813 /* push! r3, [r0] */
814 ra_offset = sp_offset;
815 ra_offset_p = 1;
816 }
817 else if (G_FLD (inst->v, 11, 7) == 0x4
818 && fp_offset_p == 0)
819 {
820 /* push! r2, [r0] */
821 fp_offset = sp_offset;
822 fp_offset_p = 1;
823 }
824 }
825 else if (G_FLD (inst->v, 14, 12) == 0x2
826 && G_FLD (inst->v, 3, 0) == 0xa)
827 {
828 /* pop! */
829 sp_offset -= 4;
830 }
831 else if (G_FLD (inst->v, 14, 7) == 0xc1
832 && G_FLD (inst->v, 2, 0) == 0x0)
833 {
834 /* subei! r0, n */
835 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
836 }
837 else if (G_FLD (inst->v, 14, 7) == 0xc0
838 && G_FLD (inst->v, 2, 0) == 0x0)
839 {
840 /* addei! r0, n */
841 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
842 }
843 }
844 else
845 {
846 inst_len = SCORE_INSTLEN;
847
848 if (G_FLD (inst->v, 29, 15) == 0xc60
849 && G_FLD (inst->v, 2, 0) == 0x4)
850 {
851 /* sw r3, [r0, offset]+ */
852 sp_offset += SCORE_INSTLEN;
853 if (ra_offset_p == 0)
854 {
855 ra_offset = sp_offset;
856 ra_offset_p = 1;
857 }
858 }
859 if (G_FLD (inst->v, 29, 15) == 0xc40
860 && G_FLD (inst->v, 2, 0) == 0x4)
861 {
862 /* sw r2, [r0, offset]+ */
863 sp_offset += SCORE_INSTLEN;
864 if (fp_offset_p == 0)
865 {
866 fp_offset = sp_offset;
867 fp_offset_p = 1;
868 }
869 }
870 else if (G_FLD (inst->v, 29, 15) == 0x1c60
871 && G_FLD (inst->v, 2, 0) == 0x0)
872 {
873 /* lw r3, [r0]+, 4 */
874 sp_offset -= SCORE_INSTLEN;
875 ra_offset_p = 1;
876 }
877 else if (G_FLD (inst->v, 29, 15) == 0x1c40
878 && G_FLD (inst->v, 2, 0) == 0x0)
879 {
880 /* lw r2, [r0]+, 4 */
881 sp_offset -= SCORE_INSTLEN;
882 fp_offset_p = 1;
883 }
884
885 else if (G_FLD (inst->v, 29, 17) == 0x100
886 && G_FLD (inst->v, 0, 0) == 0x0)
887 {
888 /* addi r0, -offset */
889 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
890 }
891 else if (G_FLD (inst->v, 29, 17) == 0x110
892 && G_FLD (inst->v, 0, 0) == 0x0)
893 {
894 /* addi r2, offset */
895 if (pc - cur_pc > 4)
896 {
897 unsigned int save_v = inst->v;
898 inst_t *inst2 =
be8626e0 899 score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
27fd2f50 900 if (inst2->v == 0x23)
5e29c264
Q
901 {
902 /* mv! r0, r2 */
903 sp_offset -= G_FLD (save_v, 16, 1);
904 }
27fd2f50
Q
905 }
906 }
907 }
908 }
909
910 /* Save RA. */
911 if (ra_offset_p == 1)
912 {
913 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
914 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
915 sp + sp_offset - ra_offset;
916 }
917 else
918 {
919 this_cache->saved_regs[SCORE_PC_REGNUM] =
920 this_cache->saved_regs[SCORE_RA_REGNUM];
921 }
922
923 /* Save FP. */
924 if (fp_offset_p == 1)
925 {
926 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
927 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
928 sp + sp_offset - fp_offset;
929 }
930
5e29c264
Q
931 /* Save SP and FP. */
932 this_cache->base = sp + sp_offset;
933 this_cache->fp = fp;
934
935 /* Don't forget to free MEMBLOCK if we allocated it. */
936 if (memblock_ptr != NULL)
937 score_free_memblock (memblock_ptr);
27fd2f50
Q
938}
939
940static struct score_frame_cache *
941score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
942{
943 struct score_frame_cache *cache;
944
945 if ((*this_cache) != NULL)
946 return (*this_cache);
947
948 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
949 (*this_cache) = cache;
950 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
951
952 /* Analyze the prologue. */
953 {
954 const CORE_ADDR pc = frame_pc_unwind (next_frame);
955 CORE_ADDR start_addr;
956
957 find_pc_partial_function (pc, NULL, &start_addr, NULL);
958 if (start_addr == 0)
959 return cache;
960 score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
961 }
962
963 /* Save SP. */
964 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
965
966 return (*this_cache);
967}
968
969static void
970score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
971 struct frame_id *this_id)
972{
973 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
974 this_cache);
93d42b30 975 (*this_id) = frame_id_build (info->base,
5e29c264 976 frame_func_unwind (next_frame, NORMAL_FRAME));
27fd2f50
Q
977}
978
979static void
980score_prologue_prev_register (struct frame_info *next_frame,
981 void **this_cache,
982 int regnum, int *optimizedp,
983 enum lval_type *lvalp, CORE_ADDR * addrp,
984 int *realnump, gdb_byte * valuep)
985{
986 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
987 this_cache);
988 trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
989 optimizedp, lvalp, addrp, realnump, valuep);
990}
991
992static const struct frame_unwind score_prologue_unwind =
993{
994 NORMAL_FRAME,
995 score_prologue_this_id,
996 score_prologue_prev_register
997};
998
999static const struct frame_unwind *
1000score_prologue_sniffer (struct frame_info *next_frame)
1001{
1002 return &score_prologue_unwind;
1003}
1004
1005static CORE_ADDR
1006score_prologue_frame_base_address (struct frame_info *next_frame,
1007 void **this_cache)
1008{
1009 struct score_frame_cache *info =
1010 score_make_prologue_cache (next_frame, this_cache);
5e29c264 1011 return info->fp;
27fd2f50
Q
1012}
1013
1014static const struct frame_base score_prologue_frame_base =
1015{
1016 &score_prologue_unwind,
1017 score_prologue_frame_base_address,
1018 score_prologue_frame_base_address,
1019 score_prologue_frame_base_address,
1020};
1021
1022static const struct frame_base *
1023score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1024{
1025 return &score_prologue_frame_base;
1026}
1027
1028static struct gdbarch *
1029score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1030{
1031 struct gdbarch *gdbarch;
1032
1033 arches = gdbarch_list_lookup_by_info (arches, &info);
1034 if (arches != NULL)
1035 {
1036 return (arches->gdbarch);
1037 }
1038 gdbarch = gdbarch_alloc (&info, 0);
1039
1040 set_gdbarch_short_bit (gdbarch, 16);
1041 set_gdbarch_int_bit (gdbarch, 32);
1042 set_gdbarch_float_bit (gdbarch, 32);
1043 set_gdbarch_double_bit (gdbarch, 64);
1044 set_gdbarch_long_double_bit (gdbarch, 64);
1045 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1046 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1047 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1048 set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1049 set_gdbarch_register_name (gdbarch, score_register_name);
1050 set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1051 set_gdbarch_register_type (gdbarch, score_register_type);
1052 set_gdbarch_frame_align (gdbarch, score_frame_align);
1053 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
27fd2f50 1054 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
30244cd8 1055 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
27fd2f50
Q
1056 set_gdbarch_print_insn (gdbarch, score_print_insn);
1057 set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1058 set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
5e29c264
Q
1059
1060 /* Watchpoint hooks. */
1061 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1062
1063 /* Dummy frame hooks. */
27fd2f50 1064 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1065 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
27fd2f50
Q
1066 set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
1067 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1068
5e29c264 1069 /* Normal frame hooks. */
27fd2f50
Q
1070 frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1071 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1072 frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
1073 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1074
1075 return gdbarch;
1076}
1077
1078extern initialize_file_ftype _initialize_score_tdep;
1079
1080void
1081_initialize_score_tdep (void)
1082{
1083 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1084}
This page took 0.200213 seconds and 4 git commands to generate.