1 /* Target-dependent code for the S+core architecture, for GDB,
4 Copyright (C) 2006-2019 Free Software Foundation, Inc.
6 Contributed by Qinwei (qinwei@sunnorth.com.cn)
7 Contributed by Ching-Peng Lin (cplin@sunplus.com)
9 This file is part of GDB.
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.
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.
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/>. */
30 #include "arch-utils.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"
40 #define G_FLD(_i,_ms,_ls) \
41 ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
45 unsigned long long raw;
49 struct score_frame_cache
53 struct trad_frame_saved_reg *saved_regs;
56 static int target_mach = bfd_mach_score7;
59 score_register_type (struct gdbarch *gdbarch, int regnum)
61 gdb_assert (regnum >= 0
62 && regnum < ((target_mach == bfd_mach_score7)
63 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
64 return builtin_type (gdbarch)->builtin_uint32;
68 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
70 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
74 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
76 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
80 score7_register_name (struct gdbarch *gdbarch, int regnum)
82 const char *score_register_names[] = {
83 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
84 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
85 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
86 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
88 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
89 "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR",
90 "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN",
91 "PREV", "DREG", "PC", "DSAVE", "COUNTER",
92 "LDCR", "STCR", "CEH", "CEL",
95 gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
96 return score_register_names[regnum];
100 score3_register_name (struct gdbarch *gdbarch, int regnum)
102 const char *score_register_names[] = {
103 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
104 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
105 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
106 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
108 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
109 "EPC", "EMA", "PREV", "DREG", "DSAVE",
110 "COUNTER", "LDCR", "STCR", "CEH", "CEL",
114 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
115 return score_register_names[regnum];
120 score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
122 gdb_assert (regnum >= 0
123 && regnum < ((target_mach == bfd_mach_score7)
124 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
130 score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock)
132 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
133 static inst_t inst = { 0, 0, 0 };
134 gdb_byte buf[SCORE_INSTLEN] = { 0 };
138 if (target_has_execution && memblock != NULL)
140 /* Fetch instruction from local MEMBLOCK. */
141 memcpy (buf, memblock, SCORE_INSTLEN);
145 /* Fetch instruction from target. */
146 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
149 error (_("Error: target_read_memory in file:%s, line:%d!"),
155 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
156 inst.len = (inst.raw & 0x80008000) ? 4 : 2;
157 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
158 big = (byte_order == BFD_ENDIAN_BIG);
161 if (big ^ ((addr & 0x2) == 2))
162 inst.v = G_FLD (inst.v, 29, 15);
164 inst.v = G_FLD (inst.v, 14, 0);
170 score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
171 enum bfd_endian byte_order)
173 static inst_t inst = { 0, 0, 0 };
180 /* raw table 1 (column 2, 3, 4)
184 table 2 (column 1, 2, 3)
190 static const struct breakplace bk_table[16] =
212 #define EXTRACT_LEN 2
213 CORE_ADDR adjust_pc = *pcptr & ~0x1;
214 gdb_byte buf[5][EXTRACT_LEN] =
224 unsigned int cbits = 0;
233 for (i = 0; i < 5; i++)
235 ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
241 error (_("Error: target_read_memory in file:%s, line:%d!"),
245 raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
246 cbits = (cbits << 1) | (raw >> 15);
253 cbits = (cbits >> 1) & 0x7;
259 cbits = (cbits >> 2) & 0x7;
260 bk_index = cbits + 8;
263 gdb_assert (!((bk_table[bk_index].break_offset == 0)
264 && (bk_table[bk_index].inst_len == 0)));
266 inst.len = bk_table[bk_index].inst_len;
268 i = (bk_table[bk_index].break_offset + 4) / 2;
269 count = inst.len / 2;
270 for (; count > 0; i++, count--)
272 inst.raw = (inst.raw << 16)
273 | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
279 inst.v = inst.raw & 0x7FFF;
282 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
285 inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
286 | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
291 *pcptr = adjust_pc + bk_table[bk_index].break_offset;
293 *lenptr = bk_table[bk_index].inst_len;
300 /* Implement the breakpoint_kind_from_pc gdbarch method. */
303 score7_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
307 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
308 gdb_byte buf[SCORE_INSTLEN] = { 0 };
310 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
312 error (_("Error: target_read_memory in file:%s, line:%d!"),
315 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
317 if (!(raw & 0x80008000))
319 /* 16bits instruction. */
325 /* 32bits instruction. */
331 /* Implement the sw_breakpoint_from_kind gdbarch method. */
333 static const gdb_byte *
334 score7_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
336 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
342 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
343 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
345 if (byte_order == BFD_ENDIAN_BIG)
346 return big_breakpoint32;
348 return little_breakpoint32;
352 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
353 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
355 if (byte_order == BFD_ENDIAN_BIG)
356 return big_breakpoint16;
358 return little_breakpoint16;
362 /* Implement the breakpoint_kind_from_pc gdbarch method. */
365 score3_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
367 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
370 score3_adjust_pc_and_fetch_inst (pcptr, &len, byte_order);
375 /* Implement the sw_breakpoint_from_kind gdbarch method. */
377 static const gdb_byte *
378 score3_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
381 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
382 static gdb_byte score_break_insns[6][6] = {
383 /* The following three instructions are big endian. */
385 { 0x80, 0x00, 0x00, 0x06 },
386 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
387 /* The following three instructions are little endian. */
389 { 0x00, 0x80, 0x06, 0x00 },
390 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
394 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (kind / 2 - 1);
395 return score_break_insns[index];
399 score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
401 CORE_ADDR adjust_pc = bpaddr;
403 if (target_mach == bfd_mach_score3)
404 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
405 gdbarch_byte_order (gdbarch));
407 adjust_pc = align_down (adjust_pc, 2);
413 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
415 return align_down (addr, 16);
419 score_xfer_register (struct regcache *regcache, int regnum, int length,
420 enum bfd_endian endian, gdb_byte *readbuf,
421 const gdb_byte *writebuf, int buf_offset)
424 gdb_assert (regnum >= 0
425 && regnum < ((target_mach == bfd_mach_score7)
426 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
431 reg_offset = SCORE_REGSIZE - length;
433 case BFD_ENDIAN_LITTLE:
436 case BFD_ENDIAN_UNKNOWN:
440 error (_("Error: score_xfer_register in file:%s, line:%d!"),
445 regcache->cooked_read_part (regnum, reg_offset, length,
446 readbuf + buf_offset);
447 if (writebuf != NULL)
448 regcache->cooked_write_part (regnum, reg_offset, length,
449 writebuf + buf_offset);
452 static enum return_value_convention
453 score_return_value (struct gdbarch *gdbarch, struct value *function,
454 struct type *type, struct regcache *regcache,
455 gdb_byte * readbuf, const gdb_byte * writebuf)
457 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
458 || TYPE_CODE (type) == TYPE_CODE_UNION
459 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
460 return RETURN_VALUE_STRUCT_CONVENTION;
465 for (offset = 0, regnum = SCORE_A0_REGNUM;
466 offset < TYPE_LENGTH (type);
467 offset += SCORE_REGSIZE, regnum++)
469 int xfer = SCORE_REGSIZE;
471 if (offset + xfer > TYPE_LENGTH (type))
472 xfer = TYPE_LENGTH (type) - offset;
473 score_xfer_register (regcache, regnum, xfer,
474 gdbarch_byte_order(gdbarch),
475 readbuf, writebuf, offset);
477 return RETURN_VALUE_REGISTER_CONVENTION;
481 static struct frame_id
482 score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
484 return frame_id_build (get_frame_register_unsigned (this_frame,
486 get_frame_pc (this_frame));
490 score_type_needs_double_align (struct type *type)
492 enum type_code typecode = TYPE_CODE (type);
494 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
495 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
497 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
501 n = TYPE_NFIELDS (type);
502 for (i = 0; i < n; i++)
503 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
511 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
512 struct regcache *regcache, CORE_ADDR bp_addr,
513 int nargs, struct value **args, CORE_ADDR sp,
514 function_call_return_method return_method,
515 CORE_ADDR struct_addr)
517 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
521 CORE_ADDR stack_offset = 0;
524 /* Step 1, Save RA. */
525 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
527 /* Step 2, Make space on the stack for the args. */
528 struct_addr = align_down (struct_addr, 16);
529 sp = align_down (sp, 16);
530 for (argnum = 0; argnum < nargs; argnum++)
531 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
533 sp -= align_up (arglen, 16);
535 argreg = SCORE_BEGIN_ARG_REGNUM;
537 /* Step 3, Check if struct return then save the struct address to
538 r4 and increase the stack_offset by 4. */
539 if (return_method == return_method_struct)
541 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
542 stack_offset += SCORE_REGSIZE;
545 /* Step 4, Load arguments:
546 If arg length is too long (> 4 bytes), then split the arg and
548 for (argnum = 0; argnum < nargs; argnum++)
550 struct value *arg = args[argnum];
551 struct type *arg_type = check_typedef (value_type (arg));
552 enum type_code typecode = TYPE_CODE (arg_type);
553 const gdb_byte *val = value_contents (arg);
554 int downward_offset = 0;
555 int arg_last_part_p = 0;
557 arglen = TYPE_LENGTH (arg_type);
559 /* If a arg should be aligned to 8 bytes (long long or double),
560 the value should be put to even register numbers. */
561 if (score_type_needs_double_align (arg_type))
567 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
568 the default "downward"/"upward" method:
574 char a; char b; char c;
575 } s = {'a', 'b', 'c'};
577 Big endian: s = {X, 'a', 'b', 'c'}
578 Little endian: s = {'a', 'b', 'c', X}
580 Where X is a hole. */
582 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
583 && (typecode == TYPE_CODE_STRUCT
584 || typecode == TYPE_CODE_UNION)
585 && argreg > SCORE_LAST_ARG_REGNUM
586 && arglen < SCORE_REGSIZE)
587 downward_offset += (SCORE_REGSIZE - arglen);
591 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
592 ULONGEST regval = extract_unsigned_integer (val, partial_len,
595 /* The last part of a arg should shift left when
596 gdbarch_byte_order is BFD_ENDIAN_BIG. */
597 if (byte_order == BFD_ENDIAN_BIG
598 && arg_last_part_p == 1
599 && (typecode == TYPE_CODE_STRUCT
600 || typecode == TYPE_CODE_UNION))
601 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
603 /* Always increase the stack_offset and save args to stack. */
604 addr = sp + stack_offset + downward_offset;
605 write_memory (addr, val, partial_len);
607 if (argreg <= SCORE_LAST_ARG_REGNUM)
609 regcache_cooked_write_unsigned (regcache, argreg++, regval);
610 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
615 arglen -= partial_len;
616 stack_offset += align_up (partial_len, SCORE_REGSIZE);
620 /* Step 5, Save SP. */
621 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
627 score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
630 int iscan = 32, stack_sub = 0;
633 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
636 if ((inst->len == 4) && !stack_sub
637 && (G_FLD (inst->v, 29, 25) == 0x1
638 && G_FLD (inst->v, 24, 20) == 0x0))
640 /* addi r0, offset */
641 stack_sub = cpc + SCORE_INSTLEN;
642 pc = cpc + SCORE_INSTLEN;
644 else if ((inst->len == 4)
645 && (G_FLD (inst->v, 29, 25) == 0x0)
646 && (G_FLD (inst->v, 24, 20) == 0x2)
647 && (G_FLD (inst->v, 19, 15) == 0x0)
648 && (G_FLD (inst->v, 14, 10) == 0xF)
649 && (G_FLD (inst->v, 9, 0) == 0x56))
652 pc = cpc + SCORE_INSTLEN;
655 else if ((inst->len == 2)
656 && (G_FLD (inst->v, 14, 12) == 0x0)
657 && (G_FLD (inst->v, 11, 8) == 0x2)
658 && (G_FLD (inst->v, 7, 4) == 0x0)
659 && (G_FLD (inst->v, 3, 0) == 0x3))
662 pc = cpc + SCORE16_INSTLEN;
665 else if ((inst->len == 2)
666 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
667 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
668 || (G_FLD (inst->v, 14, 12) == 0x0
669 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
671 else if ((inst->len == 4)
672 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
673 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
674 || (G_FLD (inst->v, 29, 25) == 0x0
675 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
678 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
684 score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
687 int iscan = 32, stack_sub = 0;
691 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
692 gdbarch_byte_order (gdbarch));
696 if (inst->len == 4 && !stack_sub
697 && (G_FLD (inst->v, 29, 25) == 0x1)
698 && (G_FLD (inst->v, 19, 17) == 0x0)
699 && (G_FLD (inst->v, 24, 20) == 0x0))
701 /* addi r0, offset */
702 stack_sub = cpc + inst->len;
703 pc = cpc + inst->len;
705 else if (inst->len == 4
706 && (G_FLD (inst->v, 29, 25) == 0x0)
707 && (G_FLD (inst->v, 24, 20) == 0x2)
708 && (G_FLD (inst->v, 19, 15) == 0x0)
709 && (G_FLD (inst->v, 14, 10) == 0xF)
710 && (G_FLD (inst->v, 9, 0) == 0x56))
713 pc = cpc + inst->len;
716 else if ((inst->len == 2)
717 && (G_FLD (inst->v, 14, 10) == 0x10)
718 && (G_FLD (inst->v, 9, 5) == 0x2)
719 && (G_FLD (inst->v, 4, 0) == 0x0))
722 pc = cpc + inst->len;
725 else if (inst->len == 2
726 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
727 || (G_FLD (inst->v, 14, 12) == 0x0
728 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
730 else if (inst->len == 4
731 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
732 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
740 /* Implement the stack_frame_destroyed_p gdbarch method. */
743 score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
745 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
748 return 1; /* mv! r0, r2 */
749 else if (G_FLD (inst->v, 14, 12) == 0x2
750 && G_FLD (inst->v, 3, 0) == 0xa)
752 else if (G_FLD (inst->v, 14, 12) == 0x0
753 && G_FLD (inst->v, 7, 0) == 0x34)
754 return 1; /* br! r3 */
755 else if (G_FLD (inst->v, 29, 15) == 0x2
756 && G_FLD (inst->v, 6, 1) == 0x2b)
757 return 1; /* mv r0, r2 */
758 else if (G_FLD (inst->v, 29, 25) == 0x0
759 && G_FLD (inst->v, 6, 1) == 0x4
760 && G_FLD (inst->v, 19, 15) == 0x3)
761 return 1; /* br r3 */
766 /* Implement the stack_frame_destroyed_p gdbarch method. */
769 score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
771 CORE_ADDR pc = cur_pc;
773 = score3_adjust_pc_and_fetch_inst (&pc, NULL,
774 gdbarch_byte_order (gdbarch));
777 && (G_FLD (inst->v, 14, 10) == 0x10)
778 && (G_FLD (inst->v, 9, 5) == 0x0)
779 && (G_FLD (inst->v, 4, 0) == 0x2))
780 return 1; /* mv! r0, r2 */
781 else if (inst->len == 4
782 && (G_FLD (inst->v, 29, 25) == 0x0)
783 && (G_FLD (inst->v, 24, 20) == 0x2)
784 && (G_FLD (inst->v, 19, 15) == 0x0)
785 && (G_FLD (inst->v, 14, 10) == 0xF)
786 && (G_FLD (inst->v, 9, 0) == 0x56))
787 return 1; /* mv r0, r2 */
788 else if (inst->len == 2
789 && (G_FLD (inst->v, 14, 12) == 0x0)
790 && (G_FLD (inst->v, 11, 5) == 0x2))
792 else if (inst->len == 2
793 && (G_FLD (inst->v, 14, 12) == 0x0)
794 && (G_FLD (inst->v, 11, 7) == 0x0)
795 && (G_FLD (inst->v, 6, 5) == 0x2))
796 return 1; /* rpop! */
797 else if (inst->len == 2
798 && (G_FLD (inst->v, 14, 12) == 0x0)
799 && (G_FLD (inst->v, 11, 5) == 0x4)
800 && (G_FLD (inst->v, 4, 0) == 0x3))
801 return 1; /* br! r3 */
802 else if (inst->len == 4
803 && (G_FLD (inst->v, 29, 25) == 0x0)
804 && (G_FLD (inst->v, 24, 20) == 0x0)
805 && (G_FLD (inst->v, 19, 15) == 0x3)
806 && (G_FLD (inst->v, 14, 10) == 0xF)
807 && (G_FLD (inst->v, 9, 0) == 0x8))
808 return 1; /* br r3 */
814 score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
817 gdb_byte *memblock = NULL;
822 memblock = (gdb_byte *) xmalloc (size);
823 memset (memblock, 0, size);
824 ret = target_read_memory (addr & ~0x3, memblock, size);
827 error (_("Error: target_read_memory in file:%s, line:%d!"),
835 score7_free_memblock (gdb_byte *memblock)
841 score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
846 /* First time call this function, do nothing. */
848 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
850 /* First 16-bit instruction, then 32-bit instruction. */
851 *memblock += SCORE_INSTLEN;
853 else if (cur_pc - prev_pc == 4)
855 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
856 *memblock += SCORE_INSTLEN;
861 score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
862 struct frame_info *this_frame,
863 struct score_frame_cache *this_cache)
865 struct gdbarch *gdbarch = get_frame_arch (this_frame);
868 CORE_ADDR cur_pc = startaddr;
877 gdb_byte *memblock = NULL;
878 gdb_byte *memblock_ptr = NULL;
879 CORE_ADDR prev_pc = -1;
881 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
882 memblock_ptr = memblock =
883 score7_malloc_and_get_memblock (startaddr, pc - startaddr);
885 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
886 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
888 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
891 if (memblock != NULL)
893 /* Reading memory block from target succefully and got all
894 the instructions(from STARTADDR to PC) needed. */
895 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
896 inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
900 /* Otherwise, we fetch 4 bytes from target, and GDB also
902 inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
905 /* FIXME: make a full-power prologue analyzer. */
908 inst_len = SCORE16_INSTLEN;
910 if (G_FLD (inst->v, 14, 12) == 0x2
911 && G_FLD (inst->v, 3, 0) == 0xe)
916 if (G_FLD (inst->v, 11, 7) == 0x6
920 ra_offset = sp_offset;
923 else if (G_FLD (inst->v, 11, 7) == 0x4
927 fp_offset = sp_offset;
931 else if (G_FLD (inst->v, 14, 12) == 0x2
932 && G_FLD (inst->v, 3, 0) == 0xa)
937 else if (G_FLD (inst->v, 14, 7) == 0xc1
938 && G_FLD (inst->v, 2, 0) == 0x0)
941 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
943 else if (G_FLD (inst->v, 14, 7) == 0xc0
944 && G_FLD (inst->v, 2, 0) == 0x0)
947 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
952 inst_len = SCORE_INSTLEN;
954 if (G_FLD(inst->v, 29, 25) == 0x3
955 && G_FLD(inst->v, 2, 0) == 0x4
956 && G_FLD(inst->v, 19, 15) == 0)
958 /* sw rD, [r0, offset]+ */
959 sp_offset += SCORE_INSTLEN;
961 if (G_FLD(inst->v, 24, 20) == 0x3)
964 if (ra_offset_p == 0)
966 ra_offset = sp_offset;
970 else if (G_FLD(inst->v, 24, 20) == 0x2)
973 if (fp_offset_p == 0)
975 fp_offset = sp_offset;
980 else if (G_FLD(inst->v, 29, 25) == 0x14
981 && G_FLD(inst->v, 19,15) == 0)
983 /* sw rD, [r0, offset] */
984 if (G_FLD(inst->v, 24, 20) == 0x3)
987 ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
990 else if (G_FLD(inst->v, 24, 20) == 0x2)
993 fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
997 else if (G_FLD (inst->v, 29, 15) == 0x1c60
998 && G_FLD (inst->v, 2, 0) == 0x0)
1000 /* lw r3, [r0]+, 4 */
1001 sp_offset -= SCORE_INSTLEN;
1004 else if (G_FLD (inst->v, 29, 15) == 0x1c40
1005 && G_FLD (inst->v, 2, 0) == 0x0)
1007 /* lw r2, [r0]+, 4 */
1008 sp_offset -= SCORE_INSTLEN;
1012 else if (G_FLD (inst->v, 29, 17) == 0x100
1013 && G_FLD (inst->v, 0, 0) == 0x0)
1015 /* addi r0, -offset */
1016 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1018 else if (G_FLD (inst->v, 29, 17) == 0x110
1019 && G_FLD (inst->v, 0, 0) == 0x0)
1021 /* addi r2, offset */
1022 if (pc - cur_pc > 4)
1024 unsigned int save_v = inst->v;
1026 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
1027 if (inst2->v == 0x23)
1030 sp_offset -= G_FLD (save_v, 16, 1);
1038 if (ra_offset_p == 1)
1040 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1041 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1042 sp + sp_offset - ra_offset;
1046 this_cache->saved_regs[SCORE_PC_REGNUM] =
1047 this_cache->saved_regs[SCORE_RA_REGNUM];
1051 if (fp_offset_p == 1)
1053 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1054 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1055 sp + sp_offset - fp_offset;
1058 /* Save SP and FP. */
1059 this_cache->base = sp + sp_offset;
1060 this_cache->fp = fp;
1062 /* Don't forget to free MEMBLOCK if we allocated it. */
1063 if (memblock_ptr != NULL)
1064 score7_free_memblock (memblock_ptr);
1068 score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1069 struct frame_info *this_frame,
1070 struct score_frame_cache *this_cache)
1074 CORE_ADDR cur_pc = startaddr;
1075 enum bfd_endian byte_order
1076 = gdbarch_byte_order (get_frame_arch (this_frame));
1081 int ra_offset_p = 0;
1082 int fp_offset_p = 0;
1085 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1086 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1088 for (; cur_pc < pc; cur_pc += inst_len)
1090 inst_t *inst = NULL;
1092 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1094 /* FIXME: make a full-power prologue analyzer. */
1097 if (G_FLD (inst->v, 14, 12) == 0x0
1098 && G_FLD (inst->v, 11, 7) == 0x0
1099 && G_FLD (inst->v, 6, 5) == 0x3)
1104 if (G_FLD (inst->v, 4, 0) == 0x3
1105 && ra_offset_p == 0)
1107 /* push! r3, [r0] */
1108 ra_offset = sp_offset;
1111 else if (G_FLD (inst->v, 4, 0) == 0x2
1112 && fp_offset_p == 0)
1114 /* push! r2, [r0] */
1115 fp_offset = sp_offset;
1119 else if (G_FLD (inst->v, 14, 12) == 0x6
1120 && G_FLD (inst->v, 11, 10) == 0x3)
1123 int start_r = G_FLD (inst->v, 9, 5);
1124 int cnt = G_FLD (inst->v, 4, 0);
1126 if ((ra_offset_p == 0)
1127 && (start_r <= SCORE_RA_REGNUM)
1128 && (SCORE_RA_REGNUM < start_r + cnt))
1130 /* rpush! contains r3 */
1132 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1135 if ((fp_offset_p == 0)
1136 && (start_r <= SCORE_FP_REGNUM)
1137 && (SCORE_FP_REGNUM < start_r + cnt))
1139 /* rpush! contains r2 */
1141 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1144 sp_offset += 4 * cnt;
1146 else if (G_FLD (inst->v, 14, 12) == 0x0
1147 && G_FLD (inst->v, 11, 7) == 0x0
1148 && G_FLD (inst->v, 6, 5) == 0x2)
1153 else if (G_FLD (inst->v, 14, 12) == 0x6
1154 && G_FLD (inst->v, 11, 10) == 0x2)
1157 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1159 else if (G_FLD (inst->v, 14, 12) == 0x5
1160 && G_FLD (inst->v, 11, 10) == 0x3
1161 && G_FLD (inst->v, 9, 6) == 0x0)
1163 /* addi! r0, -offset */
1164 int imm = G_FLD (inst->v, 5, 0);
1166 imm = -(0x3F - imm + 1);
1169 else if (G_FLD (inst->v, 14, 12) == 0x5
1170 && G_FLD (inst->v, 11, 10) == 0x3
1171 && G_FLD (inst->v, 9, 6) == 0x2)
1173 /* addi! r2, offset */
1174 if (pc - cur_pc >= 2)
1178 cur_pc += inst->len;
1179 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1183 && G_FLD (inst2->v, 14, 10) == 0x10
1184 && G_FLD (inst2->v, 9, 5) == 0x0
1185 && G_FLD (inst2->v, 4, 0) == 0x2)
1188 int imm = G_FLD (inst->v, 5, 0);
1190 imm = -(0x3F - imm + 1);
1196 else if (inst->len == 4)
1198 if (G_FLD (inst->v, 29, 25) == 0x3
1199 && G_FLD (inst->v, 2, 0) == 0x4
1200 && G_FLD (inst->v, 24, 20) == 0x3
1201 && G_FLD (inst->v, 19, 15) == 0x0)
1203 /* sw r3, [r0, offset]+ */
1204 sp_offset += inst->len;
1205 if (ra_offset_p == 0)
1207 ra_offset = sp_offset;
1211 else if (G_FLD (inst->v, 29, 25) == 0x3
1212 && G_FLD (inst->v, 2, 0) == 0x4
1213 && G_FLD (inst->v, 24, 20) == 0x2
1214 && G_FLD (inst->v, 19, 15) == 0x0)
1216 /* sw r2, [r0, offset]+ */
1217 sp_offset += inst->len;
1218 if (fp_offset_p == 0)
1220 fp_offset = sp_offset;
1224 else if (G_FLD (inst->v, 29, 25) == 0x7
1225 && G_FLD (inst->v, 2, 0) == 0x0
1226 && G_FLD (inst->v, 24, 20) == 0x3
1227 && G_FLD (inst->v, 19, 15) == 0x0)
1229 /* lw r3, [r0]+, 4 */
1230 sp_offset -= inst->len;
1233 else if (G_FLD (inst->v, 29, 25) == 0x7
1234 && G_FLD (inst->v, 2, 0) == 0x0
1235 && G_FLD (inst->v, 24, 20) == 0x2
1236 && G_FLD (inst->v, 19, 15) == 0x0)
1238 /* lw r2, [r0]+, 4 */
1239 sp_offset -= inst->len;
1242 else if (G_FLD (inst->v, 29, 25) == 0x1
1243 && G_FLD (inst->v, 19, 17) == 0x0
1244 && G_FLD (inst->v, 24, 20) == 0x0
1245 && G_FLD (inst->v, 0, 0) == 0x0)
1247 /* addi r0, -offset */
1248 int imm = G_FLD (inst->v, 16, 1);
1250 imm = -(0xFFFF - imm + 1);
1253 else if (G_FLD (inst->v, 29, 25) == 0x1
1254 && G_FLD (inst->v, 19, 17) == 0x0
1255 && G_FLD (inst->v, 24, 20) == 0x2
1256 && G_FLD (inst->v, 0, 0) == 0x0)
1258 /* addi r2, offset */
1259 if (pc - cur_pc >= 2)
1263 cur_pc += inst->len;
1264 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1268 && G_FLD (inst2->v, 14, 10) == 0x10
1269 && G_FLD (inst2->v, 9, 5) == 0x0
1270 && G_FLD (inst2->v, 4, 0) == 0x2)
1273 int imm = G_FLD (inst->v, 16, 1);
1275 imm = -(0xFFFF - imm + 1);
1284 if (ra_offset_p == 1)
1286 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1287 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1288 sp + sp_offset - ra_offset;
1292 this_cache->saved_regs[SCORE_PC_REGNUM] =
1293 this_cache->saved_regs[SCORE_RA_REGNUM];
1297 if (fp_offset_p == 1)
1299 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1300 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1301 sp + sp_offset - fp_offset;
1304 /* Save SP and FP. */
1305 this_cache->base = sp + sp_offset;
1306 this_cache->fp = fp;
1309 static struct score_frame_cache *
1310 score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
1312 struct score_frame_cache *cache;
1314 if ((*this_cache) != NULL)
1315 return (struct score_frame_cache *) (*this_cache);
1317 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1318 (*this_cache) = cache;
1319 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
1321 /* Analyze the prologue. */
1323 const CORE_ADDR pc = get_frame_pc (this_frame);
1324 CORE_ADDR start_addr;
1326 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1327 if (start_addr == 0)
1330 if (target_mach == bfd_mach_score3)
1331 score3_analyze_prologue (start_addr, pc, this_frame,
1332 (struct score_frame_cache *) *this_cache);
1334 score7_analyze_prologue (start_addr, pc, this_frame,
1335 (struct score_frame_cache *) *this_cache);
1339 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1341 return (struct score_frame_cache *) (*this_cache);
1345 score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
1346 struct frame_id *this_id)
1348 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1350 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
1353 static struct value *
1354 score_prologue_prev_register (struct frame_info *this_frame,
1355 void **this_cache, int regnum)
1357 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1359 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
1362 static const struct frame_unwind score_prologue_unwind =
1365 default_frame_unwind_stop_reason,
1366 score_prologue_this_id,
1367 score_prologue_prev_register,
1369 default_frame_sniffer,
1374 score_prologue_frame_base_address (struct frame_info *this_frame,
1377 struct score_frame_cache *info =
1378 score_make_prologue_cache (this_frame, this_cache);
1382 static const struct frame_base score_prologue_frame_base =
1384 &score_prologue_unwind,
1385 score_prologue_frame_base_address,
1386 score_prologue_frame_base_address,
1387 score_prologue_frame_base_address,
1390 static const struct frame_base *
1391 score_prologue_frame_base_sniffer (struct frame_info *this_frame)
1393 return &score_prologue_frame_base;
1396 /* Core file support. */
1398 static const struct regcache_map_entry score7_linux_gregmap[] =
1400 /* FIXME: According to the current Linux kernel, r0 is preceded by
1401 9 rather than 7 words. */
1402 { 7, REGCACHE_MAP_SKIP, 4 },
1403 { 32, 0, 4 }, /* r0 ... r31 */
1404 { 1, 55, 4 }, /* CEL */
1405 { 1, 54, 4 }, /* CEH */
1406 { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */
1407 { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */
1408 { 1, 51, 4 }, /* sr2, i.e. scr or STCR */
1409 { 1, 49, 4 }, /* PC (same slot as EPC) */
1410 { 1, 38, 4 }, /* EMA */
1411 { 1, 32, 4 }, /* PSR */
1412 { 1, 34, 4 }, /* ECR */
1413 { 1, 33, 4 }, /* COND */
1417 #define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1418 #define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
1421 score7_linux_supply_gregset(const struct regset *regset,
1422 struct regcache *regcache,
1423 int regnum, const void *buf,
1426 regcache_supply_regset (regset, regcache, regnum, buf, size);
1428 /* Supply the EPC from the same slot as the PC. Note that the
1429 collect function will store the PC in that slot. */
1430 if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1431 && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1432 regcache->raw_supply
1433 (SCORE_EPC_REGNUM, (const gdb_byte *) buf + SCORE7_LINUX_EPC_OFFSET);
1436 static const struct regset score7_linux_gregset =
1438 score7_linux_gregmap,
1439 score7_linux_supply_gregset,
1440 regcache_collect_regset
1443 /* Iterate over core file register note sections. */
1446 score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1447 iterate_over_regset_sections_cb *cb,
1449 const struct regcache *regcache)
1451 cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, SCORE7_LINUX_SIZEOF_GREGSET,
1452 &score7_linux_gregset, NULL, cb_data);
1455 static struct gdbarch *
1456 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1458 struct gdbarch *gdbarch;
1459 target_mach = info.bfd_arch_info->mach;
1461 arches = gdbarch_list_lookup_by_info (arches, &info);
1464 return (arches->gdbarch);
1466 gdbarch = gdbarch_alloc (&info, NULL);
1468 set_gdbarch_short_bit (gdbarch, 16);
1469 set_gdbarch_int_bit (gdbarch, 32);
1470 set_gdbarch_float_bit (gdbarch, 32);
1471 set_gdbarch_double_bit (gdbarch, 64);
1472 set_gdbarch_long_double_bit (gdbarch, 64);
1474 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1476 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1477 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1478 set_gdbarch_adjust_breakpoint_address (gdbarch,
1479 score_adjust_breakpoint_address);
1480 set_gdbarch_register_type (gdbarch, score_register_type);
1481 set_gdbarch_frame_align (gdbarch, score_frame_align);
1482 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1483 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1484 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1486 switch (target_mach)
1488 case bfd_mach_score7:
1489 set_gdbarch_breakpoint_kind_from_pc (gdbarch,
1490 score7_breakpoint_kind_from_pc);
1491 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1492 score7_sw_breakpoint_from_kind);
1493 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
1494 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1495 score7_stack_frame_destroyed_p);
1496 set_gdbarch_register_name (gdbarch, score7_register_name);
1497 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
1498 /* Core file support. */
1499 set_gdbarch_iterate_over_regset_sections
1500 (gdbarch, score7_linux_iterate_over_regset_sections);
1503 case bfd_mach_score3:
1504 set_gdbarch_breakpoint_kind_from_pc (gdbarch,
1505 score3_breakpoint_kind_from_pc);
1506 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1507 score3_sw_breakpoint_from_kind);
1508 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
1509 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1510 score3_stack_frame_destroyed_p);
1511 set_gdbarch_register_name (gdbarch, score3_register_name);
1512 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1516 /* Watchpoint hooks. */
1517 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1519 /* Dummy frame hooks. */
1520 set_gdbarch_return_value (gdbarch, score_return_value);
1521 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1522 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
1523 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1525 /* Normal frame hooks. */
1526 dwarf2_append_unwinders (gdbarch);
1527 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1528 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
1529 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1535 _initialize_score_tdep (void)
1537 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);