]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/score-tdep.c
Switch the license of all .c files to GPLv3.
[thirdparty/binutils-gdb.git] / gdb / score-tdep.c
1 /* Target-dependent code for the S+core architecture, for GDB,
2 the GNU Debugger.
3
4 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
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
13 the Free Software Foundation; either version 3 of the License, or
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
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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
43 typedef struct{
44 unsigned int v;
45 unsigned int raw;
46 char is15;
47 }inst_t;
48
49 struct score_frame_cache
50 {
51 CORE_ADDR base;
52 CORE_ADDR fp;
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
74 typedef struct frame_extra_info
75 {
76 CORE_ADDR p_frame;
77 unsigned int pdr[P_SIZE];
78 } extra_info_t;
79
80 struct obj_priv
81 {
82 bfd_size_type size;
83 char *contents;
84 };
85
86 static bfd *the_bfd;
87
88 static int
89 score_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
101 static void
102 score_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 {
117 error ("Error: Can't find section in file:%s, line:%d!",
118 __FILE__, __LINE__);
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
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
185 #if 0
186 /* Open these functions if build with simulator. */
187
188 int
189 score_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
201 int
202 score_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
214 int
215 score_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
227 int
228 score_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
240 int
241 score_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
253 int
254 score_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
267 static struct type *
268 score_register_type (struct gdbarch *gdbarch, int regnum)
269 {
270 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
271 return builtin_type_uint32;
272 }
273
274 static CORE_ADDR
275 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
276 {
277 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
278 }
279
280 static CORE_ADDR
281 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
282 {
283 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
284 }
285
286 static const char *
287 score_register_name (int regnum)
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
307 static int
308 score_register_sim_regno (int regnum)
309 {
310 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
311 return regnum;
312 }
313
314 static int
315 score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
316 {
317 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
318 return print_insn_big_score (memaddr, info);
319 else
320 return print_insn_little_score (memaddr, info);
321 }
322
323 static const gdb_byte *
324 score_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
325 {
326 gdb_byte buf[SCORE_INSTLEN] = { 0 };
327 int ret;
328 unsigned int raw;
329
330 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
331 {
332 error ("Error: target_read_memory in file:%s, line:%d!",
333 __FILE__, __LINE__);
334 }
335 raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
336
337 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
338 {
339 if (!(raw & 0x80008000))
340 {
341 /* 16bits instruction. */
342 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
343 *pcptr &= ~0x1;
344 *lenptr = sizeof (big_breakpoint16);
345 return big_breakpoint16;
346 }
347 else
348 {
349 /* 32bits instruction. */
350 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
351 *pcptr &= ~0x3;
352 *lenptr = sizeof (big_breakpoint32);
353 return big_breakpoint32;
354 }
355 }
356 else
357 {
358 if (!(raw & 0x80008000))
359 {
360 /* 16bits instruction. */
361 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
362 *pcptr &= ~0x1;
363 *lenptr = sizeof (little_breakpoint16);
364 return little_breakpoint16;
365 }
366 else
367 {
368 /* 32bits instruction. */
369 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
370 *pcptr &= ~0x3;
371 *lenptr = sizeof (little_breakpoint32);
372 return little_breakpoint32;
373 }
374 }
375 }
376
377 static CORE_ADDR
378 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
379 {
380 return align_down (addr, 16);
381 }
382
383 static void
384 score_xfer_register (struct regcache *regcache, int regnum, int length,
385 enum bfd_endian endian, gdb_byte *readbuf,
386 const gdb_byte *writebuf, int buf_offset)
387 {
388 int reg_offset = 0;
389 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
390
391 switch (endian)
392 {
393 case BFD_ENDIAN_BIG:
394 reg_offset = SCORE_REGSIZE - length;
395 break;
396 case BFD_ENDIAN_LITTLE:
397 reg_offset = 0;
398 break;
399 case BFD_ENDIAN_UNKNOWN:
400 reg_offset = 0;
401 break;
402 default:
403 error ("Error: score_xfer_register in file:%s, line:%d!",
404 __FILE__, __LINE__);
405 }
406
407 if (readbuf != NULL)
408 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
409 readbuf + buf_offset);
410 if (writebuf != NULL)
411 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
412 writebuf + buf_offset);
413 }
414
415 static enum return_value_convention
416 score_return_value (struct gdbarch *gdbarch, struct type *type,
417 struct regcache *regcache,
418 gdb_byte * readbuf, const gdb_byte * writebuf)
419 {
420 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
421 || TYPE_CODE (type) == TYPE_CODE_UNION
422 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
423 return RETURN_VALUE_STRUCT_CONVENTION;
424 else
425 {
426 int offset;
427 int regnum;
428 for (offset = 0, regnum = SCORE_A0_REGNUM;
429 offset < TYPE_LENGTH (type);
430 offset += SCORE_REGSIZE, regnum++)
431 {
432 int xfer = SCORE_REGSIZE;
433 if (offset + xfer > TYPE_LENGTH (type))
434 xfer = TYPE_LENGTH (type) - offset;
435 score_xfer_register (regcache, regnum, xfer,
436 gdbarch_byte_order (current_gdbarch),
437 readbuf, writebuf, offset);
438 }
439 return RETURN_VALUE_REGISTER_CONVENTION;
440 }
441 }
442
443 static struct frame_id
444 score_unwind_dummy_id (struct gdbarch *gdbarch,
445 struct frame_info *next_frame)
446 {
447 return frame_id_build (
448 frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
449 frame_pc_unwind (next_frame));
450 }
451
452 static int
453 score_type_needs_double_align (struct type *type)
454 {
455 enum type_code typecode = TYPE_CODE (type);
456
457 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
458 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
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
473 static CORE_ADDR
474 score_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
498 /* Step 3, Check if struct return then save the struct address to
499 r4 and increase the stack_offset by 4. */
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:
507 If arg length is too long (> 4 bytes), then split the arg and
508 save every parts. */
509 for (argnum = 0; argnum < nargs; argnum++)
510 {
511 struct value *arg = args[argnum];
512 struct type *arg_type = check_typedef (value_type (arg));
513 enum type_code typecode = TYPE_CODE (arg_type);
514 const gdb_byte *val = value_contents (arg);
515 int downward_offset = 0;
516 int odd_sized_struct_p;
517 int arg_last_part_p = 0;
518
519 arglen = TYPE_LENGTH (arg_type);
520 odd_sized_struct_p = (arglen > SCORE_REGSIZE
521 && arglen % SCORE_REGSIZE != 0);
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
546 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
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
559 gdbarch_byte_order is BFD_ENDIAN_BIG. */
560 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
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
589 static char *
590 score_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
616 static void
617 score_free_memblock (char *memblock)
618 {
619 xfree (memblock);
620 }
621
622 static void
623 score_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
642 static inst_t *
643 score_fetch_inst (CORE_ADDR addr, char *memblock)
644 {
645 static inst_t inst = { 0, 0 };
646 char buf[SCORE_INSTLEN] = { 0 };
647 int big;
648 int ret;
649
650 if (target_has_execution && memblock != NULL)
651 {
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 }
665 }
666
667 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
668 inst.is15 = !(inst.raw & 0x80008000);
669 inst.v = RM_PBITS (inst.raw);
670 big = (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG);
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
681 static CORE_ADDR
682 score_skip_prologue (CORE_ADDR pc)
683 {
684 CORE_ADDR cpc = pc;
685 int iscan = 32, stack_sub = 0;
686 while (iscan-- > 0)
687 {
688 inst_t *inst = score_fetch_inst (cpc, NULL);
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
730 static int
731 score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
732 {
733 inst_t *inst = score_fetch_inst (cur_pc, NULL);
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
754 static void
755 score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
756 struct frame_info *next_frame,
757 struct score_frame_cache *this_cache)
758 {
759 CORE_ADDR sp;
760 CORE_ADDR fp;
761 CORE_ADDR cur_pc = startaddr;
762
763 int sp_offset = 0;
764 int ra_offset = 0;
765 int fp_offset = 0;
766 int ra_offset_p = 0;
767 int fp_offset_p = 0;
768 int inst_len = 0;
769
770 char *memblock = NULL;
771 char *memblock_ptr = NULL;
772 CORE_ADDR prev_pc = -1;
773
774 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
775 memblock_ptr = memblock =
776 score_malloc_and_get_memblock (startaddr, pc - startaddr);
777
778 sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
779 fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
780
781 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
782 {
783 inst_t *inst = NULL;
784 if (memblock != NULL)
785 {
786 /* Reading memory block from target succefully and got all
787 the instructions(from STARTADDR to PC) needed. */
788 score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
789 inst = score_fetch_inst (cur_pc, memblock);
790 }
791 else
792 {
793 /* Otherwise, we fetch 4 bytes from target, and GDB also
794 work correctly. */
795 inst = score_fetch_inst (cur_pc, NULL);
796 }
797
798 if (inst->is15 == 1)
799 {
800 inst_len = SCORE16_INSTLEN;
801
802 if (G_FLD (inst->v, 14, 12) == 0x2
803 && G_FLD (inst->v, 3, 0) == 0xe)
804 {
805 /* push! */
806 sp_offset += 4;
807
808 if (G_FLD (inst->v, 11, 7) == 0x6
809 && ra_offset_p == 0)
810 {
811 /* push! r3, [r0] */
812 ra_offset = sp_offset;
813 ra_offset_p = 1;
814 }
815 else if (G_FLD (inst->v, 11, 7) == 0x4
816 && fp_offset_p == 0)
817 {
818 /* push! r2, [r0] */
819 fp_offset = sp_offset;
820 fp_offset_p = 1;
821 }
822 }
823 else if (G_FLD (inst->v, 14, 12) == 0x2
824 && G_FLD (inst->v, 3, 0) == 0xa)
825 {
826 /* pop! */
827 sp_offset -= 4;
828 }
829 else if (G_FLD (inst->v, 14, 7) == 0xc1
830 && G_FLD (inst->v, 2, 0) == 0x0)
831 {
832 /* subei! r0, n */
833 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
834 }
835 else if (G_FLD (inst->v, 14, 7) == 0xc0
836 && G_FLD (inst->v, 2, 0) == 0x0)
837 {
838 /* addei! r0, n */
839 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
840 }
841 }
842 else
843 {
844 inst_len = SCORE_INSTLEN;
845
846 if (G_FLD (inst->v, 29, 15) == 0xc60
847 && G_FLD (inst->v, 2, 0) == 0x4)
848 {
849 /* sw r3, [r0, offset]+ */
850 sp_offset += SCORE_INSTLEN;
851 if (ra_offset_p == 0)
852 {
853 ra_offset = sp_offset;
854 ra_offset_p = 1;
855 }
856 }
857 if (G_FLD (inst->v, 29, 15) == 0xc40
858 && G_FLD (inst->v, 2, 0) == 0x4)
859 {
860 /* sw r2, [r0, offset]+ */
861 sp_offset += SCORE_INSTLEN;
862 if (fp_offset_p == 0)
863 {
864 fp_offset = sp_offset;
865 fp_offset_p = 1;
866 }
867 }
868 else if (G_FLD (inst->v, 29, 15) == 0x1c60
869 && G_FLD (inst->v, 2, 0) == 0x0)
870 {
871 /* lw r3, [r0]+, 4 */
872 sp_offset -= SCORE_INSTLEN;
873 ra_offset_p = 1;
874 }
875 else if (G_FLD (inst->v, 29, 15) == 0x1c40
876 && G_FLD (inst->v, 2, 0) == 0x0)
877 {
878 /* lw r2, [r0]+, 4 */
879 sp_offset -= SCORE_INSTLEN;
880 fp_offset_p = 1;
881 }
882
883 else if (G_FLD (inst->v, 29, 17) == 0x100
884 && G_FLD (inst->v, 0, 0) == 0x0)
885 {
886 /* addi r0, -offset */
887 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
888 }
889 else if (G_FLD (inst->v, 29, 17) == 0x110
890 && G_FLD (inst->v, 0, 0) == 0x0)
891 {
892 /* addi r2, offset */
893 if (pc - cur_pc > 4)
894 {
895 unsigned int save_v = inst->v;
896 inst_t *inst2 =
897 score_fetch_inst (cur_pc + SCORE_INSTLEN, NULL);
898 if (inst2->v == 0x23)
899 {
900 /* mv! r0, r2 */
901 sp_offset -= G_FLD (save_v, 16, 1);
902 }
903 }
904 }
905 }
906 }
907
908 /* Save RA. */
909 if (ra_offset_p == 1)
910 {
911 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
912 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
913 sp + sp_offset - ra_offset;
914 }
915 else
916 {
917 this_cache->saved_regs[SCORE_PC_REGNUM] =
918 this_cache->saved_regs[SCORE_RA_REGNUM];
919 }
920
921 /* Save FP. */
922 if (fp_offset_p == 1)
923 {
924 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
925 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
926 sp + sp_offset - fp_offset;
927 }
928
929 /* Save SP and FP. */
930 this_cache->base = sp + sp_offset;
931 this_cache->fp = fp;
932
933 /* Don't forget to free MEMBLOCK if we allocated it. */
934 if (memblock_ptr != NULL)
935 score_free_memblock (memblock_ptr);
936 }
937
938 static struct score_frame_cache *
939 score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
940 {
941 struct score_frame_cache *cache;
942
943 if ((*this_cache) != NULL)
944 return (*this_cache);
945
946 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
947 (*this_cache) = cache;
948 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
949
950 /* Analyze the prologue. */
951 {
952 const CORE_ADDR pc = frame_pc_unwind (next_frame);
953 CORE_ADDR start_addr;
954
955 find_pc_partial_function (pc, NULL, &start_addr, NULL);
956 if (start_addr == 0)
957 return cache;
958 score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
959 }
960
961 /* Save SP. */
962 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
963
964 return (*this_cache);
965 }
966
967 static void
968 score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
969 struct frame_id *this_id)
970 {
971 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
972 this_cache);
973 (*this_id) = frame_id_build (info->base,
974 frame_func_unwind (next_frame, NORMAL_FRAME));
975 }
976
977 static void
978 score_prologue_prev_register (struct frame_info *next_frame,
979 void **this_cache,
980 int regnum, int *optimizedp,
981 enum lval_type *lvalp, CORE_ADDR * addrp,
982 int *realnump, gdb_byte * valuep)
983 {
984 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
985 this_cache);
986 trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
987 optimizedp, lvalp, addrp, realnump, valuep);
988 }
989
990 static const struct frame_unwind score_prologue_unwind =
991 {
992 NORMAL_FRAME,
993 score_prologue_this_id,
994 score_prologue_prev_register
995 };
996
997 static const struct frame_unwind *
998 score_prologue_sniffer (struct frame_info *next_frame)
999 {
1000 return &score_prologue_unwind;
1001 }
1002
1003 static CORE_ADDR
1004 score_prologue_frame_base_address (struct frame_info *next_frame,
1005 void **this_cache)
1006 {
1007 struct score_frame_cache *info =
1008 score_make_prologue_cache (next_frame, this_cache);
1009 return info->fp;
1010 }
1011
1012 static const struct frame_base score_prologue_frame_base =
1013 {
1014 &score_prologue_unwind,
1015 score_prologue_frame_base_address,
1016 score_prologue_frame_base_address,
1017 score_prologue_frame_base_address,
1018 };
1019
1020 static const struct frame_base *
1021 score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1022 {
1023 return &score_prologue_frame_base;
1024 }
1025
1026 static struct gdbarch *
1027 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1028 {
1029 struct gdbarch *gdbarch;
1030
1031 arches = gdbarch_list_lookup_by_info (arches, &info);
1032 if (arches != NULL)
1033 {
1034 return (arches->gdbarch);
1035 }
1036 gdbarch = gdbarch_alloc (&info, 0);
1037
1038 set_gdbarch_short_bit (gdbarch, 16);
1039 set_gdbarch_int_bit (gdbarch, 32);
1040 set_gdbarch_float_bit (gdbarch, 32);
1041 set_gdbarch_double_bit (gdbarch, 64);
1042 set_gdbarch_long_double_bit (gdbarch, 64);
1043 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1044 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1045 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1046 set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1047 set_gdbarch_register_name (gdbarch, score_register_name);
1048 set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1049 set_gdbarch_register_type (gdbarch, score_register_type);
1050 set_gdbarch_frame_align (gdbarch, score_frame_align);
1051 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1052 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1053 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1054 set_gdbarch_print_insn (gdbarch, score_print_insn);
1055 set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1056 set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
1057
1058 /* Watchpoint hooks. */
1059 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1060
1061 /* Dummy frame hooks. */
1062 set_gdbarch_return_value (gdbarch, score_return_value);
1063 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1064 set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
1065 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1066
1067 /* Normal frame hooks. */
1068 frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1069 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1070 frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
1071 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1072
1073 return gdbarch;
1074 }
1075
1076 extern initialize_file_ftype _initialize_score_tdep;
1077
1078 void
1079 _initialize_score_tdep (void)
1080 {
1081 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1082 }