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