* defs.h (extract_signed_integer, extract_unsigned_integer,
[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
0fb0cc75 4 Copyright (C) 2006, 2007, 2008, 2009 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,
94afd7a6 103 struct frame_info *this_frame,
27fd2f50
Q
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);
df4df182 271 return builtin_type (gdbarch)->builtin_uint32;
27fd2f50
Q
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 326{
e17a4113 327 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
328 gdb_byte buf[SCORE_INSTLEN] = { 0 };
329 int ret;
330 unsigned int raw;
331
332 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
333 {
5e29c264
Q
334 error ("Error: target_read_memory in file:%s, line:%d!",
335 __FILE__, __LINE__);
27fd2f50 336 }
e17a4113 337 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50 338
e17a4113 339 if (byte_order == BFD_ENDIAN_BIG)
27fd2f50
Q
340 {
341 if (!(raw & 0x80008000))
342 {
343 /* 16bits instruction. */
344 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
345 *pcptr &= ~0x1;
346 *lenptr = sizeof (big_breakpoint16);
347 return big_breakpoint16;
348 }
349 else
350 {
351 /* 32bits instruction. */
352 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
353 *pcptr &= ~0x3;
354 *lenptr = sizeof (big_breakpoint32);
355 return big_breakpoint32;
356 }
357 }
358 else
359 {
360 if (!(raw & 0x80008000))
361 {
362 /* 16bits instruction. */
363 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
364 *pcptr &= ~0x1;
365 *lenptr = sizeof (little_breakpoint16);
366 return little_breakpoint16;
367 }
368 else
369 {
370 /* 32bits instruction. */
371 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
372 *pcptr &= ~0x3;
373 *lenptr = sizeof (little_breakpoint32);
374 return little_breakpoint32;
375 }
376 }
377}
378
379static CORE_ADDR
380score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
381{
382 return align_down (addr, 16);
383}
384
385static void
386score_xfer_register (struct regcache *regcache, int regnum, int length,
387 enum bfd_endian endian, gdb_byte *readbuf,
388 const gdb_byte *writebuf, int buf_offset)
389{
390 int reg_offset = 0;
391 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
392
393 switch (endian)
394 {
395 case BFD_ENDIAN_BIG:
396 reg_offset = SCORE_REGSIZE - length;
397 break;
398 case BFD_ENDIAN_LITTLE:
399 reg_offset = 0;
400 break;
401 case BFD_ENDIAN_UNKNOWN:
402 reg_offset = 0;
403 break;
404 default:
5e29c264
Q
405 error ("Error: score_xfer_register in file:%s, line:%d!",
406 __FILE__, __LINE__);
27fd2f50
Q
407 }
408
409 if (readbuf != NULL)
410 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
411 readbuf + buf_offset);
412 if (writebuf != NULL)
413 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
414 writebuf + buf_offset);
415}
416
417static enum return_value_convention
c055b101
CV
418score_return_value (struct gdbarch *gdbarch, struct type *func_type,
419 struct type *type, struct regcache *regcache,
27fd2f50
Q
420 gdb_byte * readbuf, const gdb_byte * writebuf)
421{
422 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
423 || TYPE_CODE (type) == TYPE_CODE_UNION
424 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
425 return RETURN_VALUE_STRUCT_CONVENTION;
426 else
427 {
428 int offset;
429 int regnum;
430 for (offset = 0, regnum = SCORE_A0_REGNUM;
431 offset < TYPE_LENGTH (type);
432 offset += SCORE_REGSIZE, regnum++)
433 {
434 int xfer = SCORE_REGSIZE;
435 if (offset + xfer > TYPE_LENGTH (type))
436 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 437 score_xfer_register (regcache, regnum, xfer,
d93859e2 438 gdbarch_byte_order (gdbarch),
27fd2f50
Q
439 readbuf, writebuf, offset);
440 }
441 return RETURN_VALUE_REGISTER_CONVENTION;
442 }
443}
444
445static struct frame_id
94afd7a6 446score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27fd2f50
Q
447{
448 return frame_id_build (
94afd7a6
UW
449 get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM),
450 get_frame_pc (this_frame));
27fd2f50
Q
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{
e17a4113 480 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
481 int argnum;
482 int argreg;
483 int arglen = 0;
484 CORE_ADDR stack_offset = 0;
485 CORE_ADDR addr = 0;
486
487 /* Step 1, Save RA. */
488 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
489
490 /* Step 2, Make space on the stack for the args. */
491 struct_addr = align_down (struct_addr, 16);
492 sp = align_down (sp, 16);
493 for (argnum = 0; argnum < nargs; argnum++)
494 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
495 SCORE_REGSIZE);
496 sp -= align_up (arglen, 16);
497
498 argreg = SCORE_BEGIN_ARG_REGNUM;
499
5e29c264
Q
500 /* Step 3, Check if struct return then save the struct address to
501 r4 and increase the stack_offset by 4. */
27fd2f50
Q
502 if (struct_return)
503 {
504 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
505 stack_offset += SCORE_REGSIZE;
506 }
507
508 /* Step 4, Load arguments:
5e29c264
Q
509 If arg length is too long (> 4 bytes), then split the arg and
510 save every parts. */
27fd2f50
Q
511 for (argnum = 0; argnum < nargs; argnum++)
512 {
513 struct value *arg = args[argnum];
514 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
515 enum type_code typecode = TYPE_CODE (arg_type);
516 const gdb_byte *val = value_contents (arg);
517 int downward_offset = 0;
1cfd2c3e
JB
518 int odd_sized_struct_p;
519 int arg_last_part_p = 0;
27fd2f50 520
1cfd2c3e
JB
521 arglen = TYPE_LENGTH (arg_type);
522 odd_sized_struct_p = (arglen > SCORE_REGSIZE
5e29c264 523 && arglen % SCORE_REGSIZE != 0);
27fd2f50
Q
524
525 /* If a arg should be aligned to 8 bytes (long long or double),
526 the value should be put to even register numbers. */
527 if (score_type_needs_double_align (arg_type))
528 {
529 if (argreg & 1)
530 argreg++;
531 }
532
533 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
534 the default "downward"/"upward" method:
535
536 Example:
537
538 struct struc
539 {
540 char a; char b; char c;
541 } s = {'a', 'b', 'c'};
542
543 Big endian: s = {X, 'a', 'b', 'c'}
544 Little endian: s = {'a', 'b', 'c', X}
545
546 Where X is a hole. */
547
d93859e2 548 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
549 && (typecode == TYPE_CODE_STRUCT
550 || typecode == TYPE_CODE_UNION)
551 && argreg > SCORE_LAST_ARG_REGNUM
552 && arglen < SCORE_REGSIZE)
553 downward_offset += (SCORE_REGSIZE - arglen);
554
555 while (arglen > 0)
556 {
557 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
e17a4113
UW
558 ULONGEST regval = extract_unsigned_integer (val, partial_len,
559 byte_order);
27fd2f50
Q
560
561 /* The last part of a arg should shift left when
4c6b5505 562 gdbarch_byte_order is BFD_ENDIAN_BIG. */
d93859e2 563 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
564 && arg_last_part_p == 1
565 && (typecode == TYPE_CODE_STRUCT
566 || typecode == TYPE_CODE_UNION))
567 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
568
569 /* Always increase the stack_offset and save args to stack. */
570 addr = sp + stack_offset + downward_offset;
571 write_memory (addr, val, partial_len);
572
573 if (argreg <= SCORE_LAST_ARG_REGNUM)
574 {
575 regcache_cooked_write_unsigned (regcache, argreg++, regval);
576 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
577 arg_last_part_p = 1;
578 }
579
580 val += partial_len;
581 arglen -= partial_len;
582 stack_offset += align_up (partial_len, SCORE_REGSIZE);
583 }
584 }
585
586 /* Step 5, Save SP. */
587 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
588
589 return sp;
590}
591
5e29c264
Q
592static char *
593score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
594{
595 int ret;
596 char *memblock = NULL;
597
598 if (size < 0)
599 {
600 error ("Error: malloc size < 0 in file:%s, line:%d!",
601 __FILE__, __LINE__);
602 return NULL;
603 }
604 else if (size == 0)
605 return NULL;
606
607 memblock = (char *) xmalloc (size);
608 memset (memblock, 0, size);
609 ret = target_read_memory (addr & ~0x3, memblock, size);
610 if (ret)
611 {
612 error ("Error: target_read_memory in file:%s, line:%d!",
613 __FILE__, __LINE__);
614 return NULL;
615 }
616 return memblock;
617}
618
619static void
620score_free_memblock (char *memblock)
621{
622 xfree (memblock);
623}
624
625static void
626score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
627 CORE_ADDR cur_pc)
628{
629 if (prev_pc == -1)
630 {
631 /* First time call this function, do nothing. */
632 }
633 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
634 {
635 /* First 16-bit instruction, then 32-bit instruction. */
636 *memblock += SCORE_INSTLEN;
637 }
638 else if (cur_pc - prev_pc == 4)
639 {
640 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
641 *memblock += SCORE_INSTLEN;
642 }
643}
644
27fd2f50 645static inst_t *
be8626e0 646score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
27fd2f50 647{
e17a4113 648 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50 649 static inst_t inst = { 0, 0 };
5e29c264 650 char buf[SCORE_INSTLEN] = { 0 };
27fd2f50 651 int big;
5e29c264 652 int ret;
27fd2f50 653
5e29c264 654 if (target_has_execution && memblock != NULL)
27fd2f50 655 {
5e29c264
Q
656 /* Fetch instruction from local MEMBLOCK. */
657 memcpy (buf, memblock, SCORE_INSTLEN);
658 }
659 else
660 {
661 /* Fetch instruction from target. */
662 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
663 if (ret)
664 {
665 error ("Error: target_read_memory in file:%s, line:%d!",
666 __FILE__, __LINE__);
667 return 0;
668 }
27fd2f50 669 }
5e29c264 670
e17a4113 671 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50
Q
672 inst.is15 = !(inst.raw & 0x80008000);
673 inst.v = RM_PBITS (inst.raw);
e17a4113 674 big = (byte_order == BFD_ENDIAN_BIG);
27fd2f50
Q
675 if (inst.is15)
676 {
677 if (big ^ ((addr & 0x2) == 2))
678 inst.v = G_FLD (inst.v, 29, 15);
679 else
680 inst.v = G_FLD (inst.v, 14, 0);
681 }
682 return &inst;
683}
684
685static CORE_ADDR
6093d2eb 686score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
687{
688 CORE_ADDR cpc = pc;
689 int iscan = 32, stack_sub = 0;
690 while (iscan-- > 0)
691 {
be8626e0 692 inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
693 if (!inst)
694 break;
695 if (!inst->is15 && !stack_sub
696 && (G_FLD (inst->v, 29, 25) == 0x1
697 && G_FLD (inst->v, 24, 20) == 0x0))
698 {
699 /* addi r0, offset */
700 pc = stack_sub = cpc + SCORE_INSTLEN;
701 }
702 else if (!inst->is15
703 && inst->v == RM_PBITS (0x8040bc56))
704 {
705 /* mv r2, r0 */
706 pc = cpc + SCORE_INSTLEN;
707 break;
708 }
709 else if (inst->is15
710 && inst->v == RM_PBITS (0x0203))
711 {
712 /* mv! r2, r0 */
713 pc = cpc + SCORE16_INSTLEN;
714 break;
715 }
716 else if (inst->is15
717 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
718 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
719 || (G_FLD (inst->v, 14, 12) == 0x0
720 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
721 break;
722 else if (!inst->is15
723 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
724 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
725 || (G_FLD (inst->v, 29, 25) == 0x0
726 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
727 break;
728
729 cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
730 }
731 return pc;
732}
733
734static int
735score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
736{
be8626e0 737 inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL);
27fd2f50
Q
738
739 if (inst->v == 0x23)
740 return 1; /* mv! r0, r2 */
741 else if (G_FLD (inst->v, 14, 12) == 0x2
742 && G_FLD (inst->v, 3, 0) == 0xa)
743 return 1; /* pop! */
744 else if (G_FLD (inst->v, 14, 12) == 0x0
745 && G_FLD (inst->v, 7, 0) == 0x34)
746 return 1; /* br! r3 */
747 else if (G_FLD (inst->v, 29, 15) == 0x2
748 && G_FLD (inst->v, 6, 1) == 0x2b)
749 return 1; /* mv r0, r2 */
750 else if (G_FLD (inst->v, 29, 25) == 0x0
751 && G_FLD (inst->v, 6, 1) == 0x4
752 && G_FLD (inst->v, 19, 15) == 0x3)
753 return 1; /* br r3 */
754 else
755 return 0;
756}
757
758static void
759score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
94afd7a6 760 struct frame_info *this_frame,
27fd2f50
Q
761 struct score_frame_cache *this_cache)
762{
94afd7a6 763 struct gdbarch *gdbarch = get_frame_arch (this_frame);
27fd2f50 764 CORE_ADDR sp;
5e29c264 765 CORE_ADDR fp;
27fd2f50
Q
766 CORE_ADDR cur_pc = startaddr;
767
768 int sp_offset = 0;
769 int ra_offset = 0;
770 int fp_offset = 0;
771 int ra_offset_p = 0;
772 int fp_offset_p = 0;
773 int inst_len = 0;
774
5e29c264
Q
775 char *memblock = NULL;
776 char *memblock_ptr = NULL;
777 CORE_ADDR prev_pc = -1;
778
779 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
780 memblock_ptr = memblock =
781 score_malloc_and_get_memblock (startaddr, pc - startaddr);
782
94afd7a6
UW
783 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
784 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
27fd2f50 785
5e29c264 786 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
27fd2f50 787 {
5e29c264
Q
788 inst_t *inst = NULL;
789 if (memblock != NULL)
790 {
791 /* Reading memory block from target succefully and got all
792 the instructions(from STARTADDR to PC) needed. */
793 score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
be8626e0 794 inst = score_fetch_inst (gdbarch, cur_pc, memblock);
5e29c264
Q
795 }
796 else
797 {
798 /* Otherwise, we fetch 4 bytes from target, and GDB also
799 work correctly. */
be8626e0 800 inst = score_fetch_inst (gdbarch, cur_pc, NULL);
5e29c264
Q
801 }
802
27fd2f50
Q
803 if (inst->is15 == 1)
804 {
805 inst_len = SCORE16_INSTLEN;
806
807 if (G_FLD (inst->v, 14, 12) == 0x2
808 && G_FLD (inst->v, 3, 0) == 0xe)
809 {
810 /* push! */
811 sp_offset += 4;
812
813 if (G_FLD (inst->v, 11, 7) == 0x6
814 && ra_offset_p == 0)
815 {
816 /* push! r3, [r0] */
817 ra_offset = sp_offset;
818 ra_offset_p = 1;
819 }
820 else if (G_FLD (inst->v, 11, 7) == 0x4
821 && fp_offset_p == 0)
822 {
823 /* push! r2, [r0] */
824 fp_offset = sp_offset;
825 fp_offset_p = 1;
826 }
827 }
828 else if (G_FLD (inst->v, 14, 12) == 0x2
829 && G_FLD (inst->v, 3, 0) == 0xa)
830 {
831 /* pop! */
832 sp_offset -= 4;
833 }
834 else if (G_FLD (inst->v, 14, 7) == 0xc1
835 && G_FLD (inst->v, 2, 0) == 0x0)
836 {
837 /* subei! r0, n */
838 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
839 }
840 else if (G_FLD (inst->v, 14, 7) == 0xc0
841 && G_FLD (inst->v, 2, 0) == 0x0)
842 {
843 /* addei! r0, n */
844 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
845 }
846 }
847 else
848 {
849 inst_len = SCORE_INSTLEN;
850
851 if (G_FLD (inst->v, 29, 15) == 0xc60
852 && G_FLD (inst->v, 2, 0) == 0x4)
853 {
854 /* sw r3, [r0, offset]+ */
855 sp_offset += SCORE_INSTLEN;
856 if (ra_offset_p == 0)
857 {
858 ra_offset = sp_offset;
859 ra_offset_p = 1;
860 }
861 }
862 if (G_FLD (inst->v, 29, 15) == 0xc40
863 && G_FLD (inst->v, 2, 0) == 0x4)
864 {
865 /* sw r2, [r0, offset]+ */
866 sp_offset += SCORE_INSTLEN;
867 if (fp_offset_p == 0)
868 {
869 fp_offset = sp_offset;
870 fp_offset_p = 1;
871 }
872 }
873 else if (G_FLD (inst->v, 29, 15) == 0x1c60
874 && G_FLD (inst->v, 2, 0) == 0x0)
875 {
876 /* lw r3, [r0]+, 4 */
877 sp_offset -= SCORE_INSTLEN;
878 ra_offset_p = 1;
879 }
880 else if (G_FLD (inst->v, 29, 15) == 0x1c40
881 && G_FLD (inst->v, 2, 0) == 0x0)
882 {
883 /* lw r2, [r0]+, 4 */
884 sp_offset -= SCORE_INSTLEN;
885 fp_offset_p = 1;
886 }
887
888 else if (G_FLD (inst->v, 29, 17) == 0x100
889 && G_FLD (inst->v, 0, 0) == 0x0)
890 {
891 /* addi r0, -offset */
892 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
893 }
894 else if (G_FLD (inst->v, 29, 17) == 0x110
895 && G_FLD (inst->v, 0, 0) == 0x0)
896 {
897 /* addi r2, offset */
898 if (pc - cur_pc > 4)
899 {
900 unsigned int save_v = inst->v;
901 inst_t *inst2 =
be8626e0 902 score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
27fd2f50 903 if (inst2->v == 0x23)
5e29c264
Q
904 {
905 /* mv! r0, r2 */
906 sp_offset -= G_FLD (save_v, 16, 1);
907 }
27fd2f50
Q
908 }
909 }
910 }
911 }
912
913 /* Save RA. */
914 if (ra_offset_p == 1)
915 {
916 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
917 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
918 sp + sp_offset - ra_offset;
919 }
920 else
921 {
922 this_cache->saved_regs[SCORE_PC_REGNUM] =
923 this_cache->saved_regs[SCORE_RA_REGNUM];
924 }
925
926 /* Save FP. */
927 if (fp_offset_p == 1)
928 {
929 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
930 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
931 sp + sp_offset - fp_offset;
932 }
933
5e29c264
Q
934 /* Save SP and FP. */
935 this_cache->base = sp + sp_offset;
936 this_cache->fp = fp;
937
938 /* Don't forget to free MEMBLOCK if we allocated it. */
939 if (memblock_ptr != NULL)
940 score_free_memblock (memblock_ptr);
27fd2f50
Q
941}
942
943static struct score_frame_cache *
94afd7a6 944score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
27fd2f50
Q
945{
946 struct score_frame_cache *cache;
947
948 if ((*this_cache) != NULL)
949 return (*this_cache);
950
951 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
952 (*this_cache) = cache;
94afd7a6 953 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
27fd2f50
Q
954
955 /* Analyze the prologue. */
956 {
94afd7a6 957 const CORE_ADDR pc = get_frame_pc (this_frame);
27fd2f50
Q
958 CORE_ADDR start_addr;
959
960 find_pc_partial_function (pc, NULL, &start_addr, NULL);
961 if (start_addr == 0)
962 return cache;
94afd7a6 963 score_analyze_prologue (start_addr, pc, this_frame, *this_cache);
27fd2f50
Q
964 }
965
966 /* Save SP. */
967 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
968
969 return (*this_cache);
970}
971
972static void
94afd7a6 973score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
974 struct frame_id *this_id)
975{
94afd7a6 976 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 977 this_cache);
94afd7a6 978 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
979}
980
94afd7a6
UW
981static struct value *
982score_prologue_prev_register (struct frame_info *this_frame,
983 void **this_cache, int regnum)
27fd2f50 984{
94afd7a6 985 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 986 this_cache);
94afd7a6 987 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
988}
989
990static const struct frame_unwind score_prologue_unwind =
991{
992 NORMAL_FRAME,
993 score_prologue_this_id,
94afd7a6
UW
994 score_prologue_prev_register,
995 NULL,
996 default_frame_sniffer
27fd2f50
Q
997};
998
27fd2f50 999static CORE_ADDR
94afd7a6 1000score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1001 void **this_cache)
1002{
1003 struct score_frame_cache *info =
94afd7a6 1004 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1005 return info->fp;
27fd2f50
Q
1006}
1007
1008static const struct frame_base score_prologue_frame_base =
1009{
1010 &score_prologue_unwind,
1011 score_prologue_frame_base_address,
1012 score_prologue_frame_base_address,
1013 score_prologue_frame_base_address,
1014};
1015
1016static const struct frame_base *
94afd7a6 1017score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1018{
1019 return &score_prologue_frame_base;
1020}
1021
1022static struct gdbarch *
1023score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1024{
1025 struct gdbarch *gdbarch;
1026
1027 arches = gdbarch_list_lookup_by_info (arches, &info);
1028 if (arches != NULL)
1029 {
1030 return (arches->gdbarch);
1031 }
1032 gdbarch = gdbarch_alloc (&info, 0);
1033
1034 set_gdbarch_short_bit (gdbarch, 16);
1035 set_gdbarch_int_bit (gdbarch, 32);
1036 set_gdbarch_float_bit (gdbarch, 32);
1037 set_gdbarch_double_bit (gdbarch, 64);
1038 set_gdbarch_long_double_bit (gdbarch, 64);
1039 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1040 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1041 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1042 set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1043 set_gdbarch_register_name (gdbarch, score_register_name);
1044 set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1045 set_gdbarch_register_type (gdbarch, score_register_type);
1046 set_gdbarch_frame_align (gdbarch, score_frame_align);
1047 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
27fd2f50 1048 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
30244cd8 1049 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
27fd2f50
Q
1050 set_gdbarch_print_insn (gdbarch, score_print_insn);
1051 set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1052 set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
5e29c264
Q
1053
1054 /* Watchpoint hooks. */
1055 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1056
1057 /* Dummy frame hooks. */
27fd2f50 1058 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1059 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1060 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1061 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1062
5e29c264 1063 /* Normal frame hooks. */
94afd7a6 1064 dwarf2_append_unwinders (gdbarch);
27fd2f50 1065 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1066 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1067 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1068
1069 return gdbarch;
1070}
1071
1072extern initialize_file_ftype _initialize_score_tdep;
1073
1074void
1075_initialize_score_tdep (void)
1076{
1077 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1078}
This page took 0.304022 seconds and 4 git commands to generate.