testsuite/ChangeLog
[deliverable/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, 2008, 2009 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 "regset.h"
34 #include "dis-asm.h"
35 #include "frame-unwind.h"
36 #include "frame-base.h"
37 #include "trad-frame.h"
38 #include "dwarf2-frame.h"
39 #include "score-tdep.h"
40
41 #define G_FLD(_i,_ms,_ls) \
42 ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
43
44 typedef struct{
45 unsigned long long v;
46 unsigned long long raw;
47 unsigned int len;
48 }inst_t;
49
50 struct score_frame_cache
51 {
52 CORE_ADDR base;
53 CORE_ADDR fp;
54 struct trad_frame_saved_reg *saved_regs;
55 };
56
57 static int target_mach = bfd_mach_score7;
58
59 #if WITH_SIM
60 int
61 score_target_can_use_watch (int type, int cnt, int othertype)
62 {
63 if (strcmp (current_target.to_shortname, "sim") == 0)
64 return soc_gh_can_use_watch (type, cnt);
65 return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
66 }
67
68 int
69 score_stopped_by_watch (void)
70 {
71 if (strcmp (current_target.to_shortname, "sim") == 0)
72 return soc_gh_stopped_by_watch ();
73 return (*current_target.to_stopped_by_watchpoint) ();
74 }
75
76 int
77 score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
78 {
79 if (strcmp (current_target.to_shortname, "sim") == 0)
80 return soc_gh_add_watch (addr, len, type);
81 return (*current_target.to_insert_watchpoint) (addr, len, type);
82 }
83
84 int
85 score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
86 {
87 if (strcmp (current_target.to_shortname, "sim") == 0)
88 return soc_gh_del_watch (addr, len, type);
89 return (*current_target.to_remove_watchpoint) (addr, len, type);
90 }
91
92 int
93 score_target_insert_hw_breakpoint (struct gdbarch *gdbarch,
94 struct bp_target_info * bp_tgt)
95 {
96 if (strcmp (current_target.to_shortname, "sim") == 0)
97 return soc_gh_add_hardbp (bp_tgt->placed_address);
98 return (*current_target.to_insert_hw_breakpoint) (gdbarch, bp_tgt);
99 }
100
101 int
102 score_target_remove_hw_breakpoint (struct gdbarch *gdbarch,
103 struct bp_target_info * bp_tgt)
104 {
105 if (strcmp (current_target.to_shortname, "sim") == 0)
106 return soc_gh_del_hardbp (bp_tgt->placed_address);
107 return (*current_target.to_remove_hw_breakpoint) (gdbarch, bp_tgt);
108 }
109 #endif
110
111 static struct type *
112 score_register_type (struct gdbarch *gdbarch, int regnum)
113 {
114 gdb_assert (regnum >= 0
115 && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
116 return builtin_type (gdbarch)->builtin_uint32;
117 }
118
119 static CORE_ADDR
120 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
121 {
122 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
123 }
124
125 static CORE_ADDR
126 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
127 {
128 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
129 }
130
131 static const char *
132 score7_register_name (struct gdbarch *gdbarch, int regnum)
133 {
134 const char *score_register_names[] = {
135 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
136 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
137 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
138 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
139
140 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
141 "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR",
142 "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN",
143 "PREV", "DREG", "PC", "DSAVE", "COUNTER",
144 "LDCR", "STCR", "CEH", "CEL",
145 };
146
147 gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
148 return score_register_names[regnum];
149 }
150
151 static const char *
152 score3_register_name (struct gdbarch *gdbarch, int regnum)
153 {
154 const char *score_register_names[] = {
155 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
156 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
157 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
158 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
159
160 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
161 "EPC", "EMA", "PREV", "DREG", "DSAVE",
162 "COUNTER", "LDCR", "STCR", "CEH", "CEL",
163 "", "", "PC",
164 };
165
166 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
167 return score_register_names[regnum];
168 }
169
170 #if WITH_SIM
171 static int
172 score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
173 {
174 gdb_assert (regnum >= 0
175 && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
176 return regnum;
177 }
178 #endif
179
180 static int
181 score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
182 {
183 if (info->endian == BFD_ENDIAN_BIG)
184 return print_insn_big_score (memaddr, info);
185 else
186 return print_insn_little_score (memaddr, info);
187 }
188
189 static inst_t *
190 score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
191 {
192 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
193 static inst_t inst = { 0, 0, 0 };
194 char buf[SCORE_INSTLEN] = { 0 };
195 int big;
196 int ret;
197
198 if (target_has_execution && memblock != NULL)
199 {
200 /* Fetch instruction from local MEMBLOCK. */
201 memcpy (buf, memblock, SCORE_INSTLEN);
202 }
203 else
204 {
205 /* Fetch instruction from target. */
206 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
207 if (ret)
208 {
209 error ("Error: target_read_memory in file:%s, line:%d!",
210 __FILE__, __LINE__);
211 return 0;
212 }
213 }
214
215 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
216 inst.len = (inst.raw & 0x80008000) ? 4 : 2;
217 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
218 big = (byte_order == BFD_ENDIAN_BIG);
219 if (inst.len == 2)
220 {
221 if (big ^ ((addr & 0x2) == 2))
222 inst.v = G_FLD (inst.v, 29, 15);
223 else
224 inst.v = G_FLD (inst.v, 14, 0);
225 }
226 return &inst;
227 }
228
229 static inst_t *
230 score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
231 enum bfd_endian byte_order)
232 {
233 static inst_t inst = { 0, 0, 0 };
234
235 struct breakplace
236 {
237 int break_offset;
238 int inst_len;
239 };
240 /* raw table 1 (column 2, 3, 4)
241 * 0 1 0 * # 2
242 * 0 1 1 0 # 3
243 0 1 1 0 * # 6
244 table 2 (column 1, 2, 3)
245 * 0 0 * * # 0, 4
246 0 1 0 * * # 2
247 1 1 0 * * # 6
248 */
249
250 static const struct breakplace bk_table[16] =
251 {
252 /* table 1 */
253 {0, 0},
254 {0, 0},
255 {0, 4},
256 {0, 6},
257 {0, 0},
258 {0, 0},
259 {-2, 6},
260 {0, 0},
261 /* table 2 */
262 {0, 2},
263 {0, 0},
264 {-2, 4},
265 {0, 0},
266 {0, 2},
267 {0, 0},
268 {-4, 6},
269 {0, 0}
270 };
271
272 #define EXTRACT_LEN 2
273 CORE_ADDR adjust_pc = *pcptr & ~0x1;
274 int inst_len;
275 gdb_byte buf[5][EXTRACT_LEN] =
276 {
277 {'\0', '\0'},
278 {'\0', '\0'},
279 {'\0', '\0'},
280 {'\0', '\0'},
281 {'\0', '\0'}
282 };
283 int ret;
284 unsigned int raw;
285 unsigned int cbits = 0;
286 int bk_index;
287 int i, count;
288
289 inst.v = 0;
290 inst.raw = 0;
291 inst.len = 0;
292
293 adjust_pc -= 4;
294 for (i = 0; i < 5; i++)
295 {
296 ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
297 if (ret != 0)
298 {
299 buf[i][0] = '\0';
300 buf[i][1] = '\0';
301 if (i == 2)
302 error ("Error: target_read_memory in file:%s, line:%d!",
303 __FILE__, __LINE__);
304 }
305
306 raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
307 cbits = (cbits << 1) | (raw >> 15);
308 }
309 adjust_pc += 4;
310
311 if (cbits & 0x4)
312 {
313 /* table 1 */
314 cbits = (cbits >> 1) & 0x7;
315 bk_index = cbits;
316 }
317 else
318 {
319 /* table 2 */
320 cbits = (cbits >> 2) & 0x7;
321 bk_index = cbits + 8;
322 }
323
324 gdb_assert (!((bk_table[bk_index].break_offset == 0)
325 && (bk_table[bk_index].inst_len == 0)));
326
327 inst.len = bk_table[bk_index].inst_len;
328
329 i = (bk_table[bk_index].break_offset + 4) / 2;
330 count = inst.len / 2;
331 for (; count > 0; i++, count--)
332 {
333 inst.raw = (inst.raw << 16)
334 | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
335 }
336
337 switch (inst.len)
338 {
339 case 2:
340 inst.v = inst.raw & 0x7FFF;
341 break;
342 case 4:
343 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
344 break;
345 case 6:
346 inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
347 | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
348 break;
349 }
350
351 if (pcptr)
352 *pcptr = adjust_pc + bk_table[bk_index].break_offset;
353 if (lenptr)
354 *lenptr = bk_table[bk_index].inst_len;
355
356 #undef EXTRACT_LEN
357
358 return &inst;
359 }
360
361 static const gdb_byte *
362 score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
363 int *lenptr)
364 {
365 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
366 gdb_byte buf[SCORE_INSTLEN] = { 0 };
367 int ret;
368 unsigned int raw;
369
370 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
371 {
372 error ("Error: target_read_memory in file:%s, line:%d!",
373 __FILE__, __LINE__);
374 }
375 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
376
377 if (byte_order == BFD_ENDIAN_BIG)
378 {
379 if (!(raw & 0x80008000))
380 {
381 /* 16bits instruction. */
382 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
383 *pcptr &= ~0x1;
384 *lenptr = sizeof (big_breakpoint16);
385 return big_breakpoint16;
386 }
387 else
388 {
389 /* 32bits instruction. */
390 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
391 *pcptr &= ~0x3;
392 *lenptr = sizeof (big_breakpoint32);
393 return big_breakpoint32;
394 }
395 }
396 else
397 {
398 if (!(raw & 0x80008000))
399 {
400 /* 16bits instruction. */
401 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
402 *pcptr &= ~0x1;
403 *lenptr = sizeof (little_breakpoint16);
404 return little_breakpoint16;
405 }
406 else
407 {
408 /* 32bits instruction. */
409 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
410 *pcptr &= ~0x3;
411 *lenptr = sizeof (little_breakpoint32);
412 return little_breakpoint32;
413 }
414 }
415 }
416
417 static const gdb_byte *
418 score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
419 int *lenptr)
420 {
421 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
422 CORE_ADDR adjust_pc = *pcptr;
423 int len;
424 static gdb_byte score_break_insns[6][6] = {
425 /* The following three instructions are big endian. */
426 { 0x00, 0x20 },
427 { 0x80, 0x00, 0x00, 0x06 },
428 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
429 /* The following three instructions are little endian. */
430 { 0x20, 0x00 },
431 { 0x00, 0x80, 0x06, 0x00 },
432 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
433
434 gdb_byte *p = NULL;
435 int index = 0;
436
437 score3_adjust_pc_and_fetch_inst (&adjust_pc, &len, byte_order);
438
439 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1);
440 p = score_break_insns[index];
441
442 *pcptr = adjust_pc;
443 *lenptr = len;
444
445 return p;
446 }
447
448 static CORE_ADDR
449 score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
450 {
451 CORE_ADDR adjust_pc = bpaddr;
452
453 if (target_mach == bfd_mach_score3)
454 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
455 gdbarch_byte_order (gdbarch));
456 else
457 adjust_pc = align_down (adjust_pc, 2);
458
459 return adjust_pc;
460 }
461
462 static CORE_ADDR
463 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
464 {
465 return align_down (addr, 16);
466 }
467
468 static void
469 score_xfer_register (struct regcache *regcache, int regnum, int length,
470 enum bfd_endian endian, gdb_byte *readbuf,
471 const gdb_byte *writebuf, int buf_offset)
472 {
473 int reg_offset = 0;
474 gdb_assert (regnum >= 0
475 && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
476
477 switch (endian)
478 {
479 case BFD_ENDIAN_BIG:
480 reg_offset = SCORE_REGSIZE - length;
481 break;
482 case BFD_ENDIAN_LITTLE:
483 reg_offset = 0;
484 break;
485 case BFD_ENDIAN_UNKNOWN:
486 reg_offset = 0;
487 break;
488 default:
489 error ("Error: score_xfer_register in file:%s, line:%d!",
490 __FILE__, __LINE__);
491 }
492
493 if (readbuf != NULL)
494 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
495 readbuf + buf_offset);
496 if (writebuf != NULL)
497 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
498 writebuf + buf_offset);
499 }
500
501 static enum return_value_convention
502 score_return_value (struct gdbarch *gdbarch, struct type *func_type,
503 struct type *type, struct regcache *regcache,
504 gdb_byte * readbuf, const gdb_byte * writebuf)
505 {
506 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
507 || TYPE_CODE (type) == TYPE_CODE_UNION
508 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
509 return RETURN_VALUE_STRUCT_CONVENTION;
510 else
511 {
512 int offset;
513 int regnum;
514 for (offset = 0, regnum = SCORE_A0_REGNUM;
515 offset < TYPE_LENGTH (type);
516 offset += SCORE_REGSIZE, regnum++)
517 {
518 int xfer = SCORE_REGSIZE;
519 if (offset + xfer > TYPE_LENGTH (type))
520 xfer = TYPE_LENGTH (type) - offset;
521 score_xfer_register (regcache, regnum, xfer,
522 gdbarch_byte_order(gdbarch),
523 readbuf, writebuf, offset);
524 }
525 return RETURN_VALUE_REGISTER_CONVENTION;
526 }
527 }
528
529 static struct frame_id
530 score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
531 {
532 return frame_id_build (
533 get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM),
534 get_frame_pc (this_frame));
535 }
536
537 static int
538 score_type_needs_double_align (struct type *type)
539 {
540 enum type_code typecode = TYPE_CODE (type);
541
542 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
543 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
544 return 1;
545 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
546 {
547 int i, n;
548
549 n = TYPE_NFIELDS (type);
550 for (i = 0; i < n; i++)
551 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
552 return 1;
553 return 0;
554 }
555 return 0;
556 }
557
558 static CORE_ADDR
559 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
560 struct regcache *regcache, CORE_ADDR bp_addr,
561 int nargs, struct value **args, CORE_ADDR sp,
562 int struct_return, CORE_ADDR struct_addr)
563 {
564 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
565 int argnum;
566 int argreg;
567 int arglen = 0;
568 CORE_ADDR stack_offset = 0;
569 CORE_ADDR addr = 0;
570
571 /* Step 1, Save RA. */
572 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
573
574 /* Step 2, Make space on the stack for the args. */
575 struct_addr = align_down (struct_addr, 16);
576 sp = align_down (sp, 16);
577 for (argnum = 0; argnum < nargs; argnum++)
578 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
579 SCORE_REGSIZE);
580 sp -= align_up (arglen, 16);
581
582 argreg = SCORE_BEGIN_ARG_REGNUM;
583
584 /* Step 3, Check if struct return then save the struct address to
585 r4 and increase the stack_offset by 4. */
586 if (struct_return)
587 {
588 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
589 stack_offset += SCORE_REGSIZE;
590 }
591
592 /* Step 4, Load arguments:
593 If arg length is too long (> 4 bytes), then split the arg and
594 save every parts. */
595 for (argnum = 0; argnum < nargs; argnum++)
596 {
597 struct value *arg = args[argnum];
598 struct type *arg_type = check_typedef (value_type (arg));
599 enum type_code typecode = TYPE_CODE (arg_type);
600 const gdb_byte *val = value_contents (arg);
601 int downward_offset = 0;
602 int odd_sized_struct_p;
603 int arg_last_part_p = 0;
604
605 arglen = TYPE_LENGTH (arg_type);
606 odd_sized_struct_p = (arglen > SCORE_REGSIZE
607 && arglen % SCORE_REGSIZE != 0);
608
609 /* If a arg should be aligned to 8 bytes (long long or double),
610 the value should be put to even register numbers. */
611 if (score_type_needs_double_align (arg_type))
612 {
613 if (argreg & 1)
614 argreg++;
615 }
616
617 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
618 the default "downward"/"upward" method:
619
620 Example:
621
622 struct struc
623 {
624 char a; char b; char c;
625 } s = {'a', 'b', 'c'};
626
627 Big endian: s = {X, 'a', 'b', 'c'}
628 Little endian: s = {'a', 'b', 'c', X}
629
630 Where X is a hole. */
631
632 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
633 && (typecode == TYPE_CODE_STRUCT
634 || typecode == TYPE_CODE_UNION)
635 && argreg > SCORE_LAST_ARG_REGNUM
636 && arglen < SCORE_REGSIZE)
637 downward_offset += (SCORE_REGSIZE - arglen);
638
639 while (arglen > 0)
640 {
641 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
642 ULONGEST regval = extract_unsigned_integer (val, partial_len,
643 byte_order);
644
645 /* The last part of a arg should shift left when
646 gdbarch_byte_order is BFD_ENDIAN_BIG. */
647 if (byte_order == BFD_ENDIAN_BIG
648 && arg_last_part_p == 1
649 && (typecode == TYPE_CODE_STRUCT
650 || typecode == TYPE_CODE_UNION))
651 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
652
653 /* Always increase the stack_offset and save args to stack. */
654 addr = sp + stack_offset + downward_offset;
655 write_memory (addr, val, partial_len);
656
657 if (argreg <= SCORE_LAST_ARG_REGNUM)
658 {
659 regcache_cooked_write_unsigned (regcache, argreg++, regval);
660 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
661 arg_last_part_p = 1;
662 }
663
664 val += partial_len;
665 arglen -= partial_len;
666 stack_offset += align_up (partial_len, SCORE_REGSIZE);
667 }
668 }
669
670 /* Step 5, Save SP. */
671 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
672
673 return sp;
674 }
675
676 static CORE_ADDR
677 score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
678 {
679 CORE_ADDR cpc = pc;
680 int iscan = 32, stack_sub = 0;
681 while (iscan-- > 0)
682 {
683 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
684 if (!inst)
685 break;
686 if ((inst->len == 4) && !stack_sub
687 && (G_FLD (inst->v, 29, 25) == 0x1
688 && G_FLD (inst->v, 24, 20) == 0x0))
689 {
690 /* addi r0, offset */
691 stack_sub = cpc + SCORE_INSTLEN;
692 pc = cpc + SCORE_INSTLEN;
693 }
694 else if ((inst->len == 4)
695 && (G_FLD (inst->v, 29, 25) == 0x0)
696 && (G_FLD (inst->v, 24, 20) == 0x2)
697 && (G_FLD (inst->v, 19, 15) == 0x0)
698 && (G_FLD (inst->v, 14, 10) == 0xF)
699 && (G_FLD (inst->v, 9, 0) == 0x56))
700 {
701 /* mv r2, r0 */
702 pc = cpc + SCORE_INSTLEN;
703 break;
704 }
705 else if ((inst->len == 2)
706 && (G_FLD (inst->v, 14, 12) == 0x0)
707 && (G_FLD (inst->v, 11, 8) == 0x2)
708 && (G_FLD (inst->v, 7, 4) == 0x0)
709 && (G_FLD (inst->v, 3, 0) == 0x3))
710 {
711 /* mv! r2, r0 */
712 pc = cpc + SCORE16_INSTLEN;
713 break;
714 }
715 else if ((inst->len == 2)
716 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
717 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
718 || (G_FLD (inst->v, 14, 12) == 0x0
719 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
720 break;
721 else if ((inst->len == 4)
722 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
723 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
724 || (G_FLD (inst->v, 29, 25) == 0x0
725 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
726 break;
727
728 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
729 }
730 return pc;
731 }
732
733 static CORE_ADDR
734 score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
735 {
736 CORE_ADDR cpc = pc;
737 int iscan = 32, stack_sub = 0;
738 while (iscan-- > 0)
739 {
740 inst_t *inst
741 = score3_adjust_pc_and_fetch_inst (&cpc, NULL, gdbarch_byte_order (gdbarch));
742
743 if (!inst)
744 break;
745 if (inst->len == 4 && !stack_sub
746 && (G_FLD (inst->v, 29, 25) == 0x1)
747 && (G_FLD (inst->v, 19, 17) == 0x0)
748 && (G_FLD (inst->v, 24, 20) == 0x0))
749 {
750 /* addi r0, offset */
751 stack_sub = cpc + inst->len;
752 pc = cpc + inst->len;
753 }
754 else if (inst->len == 4
755 && (G_FLD (inst->v, 29, 25) == 0x0)
756 && (G_FLD (inst->v, 24, 20) == 0x2)
757 && (G_FLD (inst->v, 19, 15) == 0x0)
758 && (G_FLD (inst->v, 14, 10) == 0xF)
759 && (G_FLD (inst->v, 9, 0) == 0x56))
760 {
761 /* mv r2, r0 */
762 pc = cpc + inst->len;
763 break;
764 }
765 else if ((inst->len == 2)
766 && (G_FLD (inst->v, 14, 10) == 0x10)
767 && (G_FLD (inst->v, 9, 5) == 0x2)
768 && (G_FLD (inst->v, 4, 0) == 0x0))
769 {
770 /* mv! r2, r0 */
771 pc = cpc + inst->len;
772 break;
773 }
774 else if (inst->len == 2
775 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
776 || (G_FLD (inst->v, 14, 12) == 0x0
777 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
778 break;
779 else if (inst->len == 4
780 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
781 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
782 break;
783
784 cpc += inst->len;
785 }
786 return pc;
787 }
788
789 static int
790 score7_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
791 {
792 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
793
794 if (inst->v == 0x23)
795 return 1; /* mv! r0, r2 */
796 else if (G_FLD (inst->v, 14, 12) == 0x2
797 && G_FLD (inst->v, 3, 0) == 0xa)
798 return 1; /* pop! */
799 else if (G_FLD (inst->v, 14, 12) == 0x0
800 && G_FLD (inst->v, 7, 0) == 0x34)
801 return 1; /* br! r3 */
802 else if (G_FLD (inst->v, 29, 15) == 0x2
803 && G_FLD (inst->v, 6, 1) == 0x2b)
804 return 1; /* mv r0, r2 */
805 else if (G_FLD (inst->v, 29, 25) == 0x0
806 && G_FLD (inst->v, 6, 1) == 0x4
807 && G_FLD (inst->v, 19, 15) == 0x3)
808 return 1; /* br r3 */
809 else
810 return 0;
811 }
812
813 static int
814 score3_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
815 {
816 CORE_ADDR pc = cur_pc;
817 inst_t *inst
818 = score3_adjust_pc_and_fetch_inst (&pc, NULL, gdbarch_byte_order (gdbarch));
819
820 if (inst->len == 2
821 && (G_FLD (inst->v, 14, 10) == 0x10)
822 && (G_FLD (inst->v, 9, 5) == 0x0)
823 && (G_FLD (inst->v, 4, 0) == 0x2))
824 return 1; /* mv! r0, r2 */
825 else if (inst->len == 4
826 && (G_FLD (inst->v, 29, 25) == 0x0)
827 && (G_FLD (inst->v, 24, 20) == 0x2)
828 && (G_FLD (inst->v, 19, 15) == 0x0)
829 && (G_FLD (inst->v, 14, 10) == 0xF)
830 && (G_FLD (inst->v, 9, 0) == 0x56))
831 return 1; /* mv r0, r2 */
832 else if (inst->len == 2
833 && (G_FLD (inst->v, 14, 12) == 0x0)
834 && (G_FLD (inst->v, 11, 5) == 0x2))
835 return 1; /* pop! */
836 else if (inst->len == 2
837 && (G_FLD (inst->v, 14, 12) == 0x0)
838 && (G_FLD (inst->v, 11, 7) == 0x0)
839 && (G_FLD (inst->v, 6, 5) == 0x2))
840 return 1; /* rpop! */
841 else if (inst->len == 2
842 && (G_FLD (inst->v, 14, 12) == 0x0)
843 && (G_FLD (inst->v, 11, 5) == 0x4)
844 && (G_FLD (inst->v, 4, 0) == 0x3))
845 return 1; /* br! r3 */
846 else if (inst->len == 4
847 && (G_FLD (inst->v, 29, 25) == 0x0)
848 && (G_FLD (inst->v, 24, 20) == 0x0)
849 && (G_FLD (inst->v, 19, 15) == 0x3)
850 && (G_FLD (inst->v, 14, 10) == 0xF)
851 && (G_FLD (inst->v, 9, 0) == 0x8))
852 return 1; /* br r3 */
853 else
854 return 0;
855 }
856
857 static char *
858 score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
859 {
860 int ret;
861 char *memblock = NULL;
862
863 if (size < 0)
864 {
865 error ("Error: malloc size < 0 in file:%s, line:%d!",
866 __FILE__, __LINE__);
867 return NULL;
868 }
869 else if (size == 0)
870 return NULL;
871
872 memblock = (char *) xmalloc (size);
873 memset (memblock, 0, size);
874 ret = target_read_memory (addr & ~0x3, memblock, size);
875 if (ret)
876 {
877 error ("Error: target_read_memory in file:%s, line:%d!",
878 __FILE__, __LINE__);
879 return NULL;
880 }
881 return memblock;
882 }
883
884 static void
885 score7_free_memblock (char *memblock)
886 {
887 xfree (memblock);
888 }
889
890 static void
891 score7_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
892 CORE_ADDR cur_pc)
893 {
894 if (prev_pc == -1)
895 {
896 /* First time call this function, do nothing. */
897 }
898 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
899 {
900 /* First 16-bit instruction, then 32-bit instruction. */
901 *memblock += SCORE_INSTLEN;
902 }
903 else if (cur_pc - prev_pc == 4)
904 {
905 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
906 *memblock += SCORE_INSTLEN;
907 }
908 }
909
910 static void
911 score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
912 struct frame_info *this_frame,
913 struct score_frame_cache *this_cache)
914 {
915 struct gdbarch *gdbarch = get_frame_arch (this_frame);
916 CORE_ADDR sp;
917 CORE_ADDR fp;
918 CORE_ADDR cur_pc = startaddr;
919
920 int sp_offset = 0;
921 int ra_offset = 0;
922 int fp_offset = 0;
923 int ra_offset_p = 0;
924 int fp_offset_p = 0;
925 int inst_len = 0;
926
927 char *memblock = NULL;
928 char *memblock_ptr = NULL;
929 CORE_ADDR prev_pc = -1;
930
931 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
932 memblock_ptr = memblock =
933 score7_malloc_and_get_memblock (startaddr, pc - startaddr);
934
935 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
936 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
937
938 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
939 {
940 inst_t *inst = NULL;
941 if (memblock != NULL)
942 {
943 /* Reading memory block from target succefully and got all
944 the instructions(from STARTADDR to PC) needed. */
945 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
946 inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
947 }
948 else
949 {
950 /* Otherwise, we fetch 4 bytes from target, and GDB also
951 work correctly. */
952 inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
953 }
954
955 /* FIXME: make a full-power prologue analyzer */
956 if (inst->len == 2)
957 {
958 inst_len = SCORE16_INSTLEN;
959
960 if (G_FLD (inst->v, 14, 12) == 0x2
961 && G_FLD (inst->v, 3, 0) == 0xe)
962 {
963 /* push! */
964 sp_offset += 4;
965
966 if (G_FLD (inst->v, 11, 7) == 0x6
967 && ra_offset_p == 0)
968 {
969 /* push! r3, [r0] */
970 ra_offset = sp_offset;
971 ra_offset_p = 1;
972 }
973 else if (G_FLD (inst->v, 11, 7) == 0x4
974 && fp_offset_p == 0)
975 {
976 /* push! r2, [r0] */
977 fp_offset = sp_offset;
978 fp_offset_p = 1;
979 }
980 }
981 else if (G_FLD (inst->v, 14, 12) == 0x2
982 && G_FLD (inst->v, 3, 0) == 0xa)
983 {
984 /* pop! */
985 sp_offset -= 4;
986 }
987 else if (G_FLD (inst->v, 14, 7) == 0xc1
988 && G_FLD (inst->v, 2, 0) == 0x0)
989 {
990 /* subei! r0, n */
991 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
992 }
993 else if (G_FLD (inst->v, 14, 7) == 0xc0
994 && G_FLD (inst->v, 2, 0) == 0x0)
995 {
996 /* addei! r0, n */
997 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
998 }
999 }
1000 else
1001 {
1002 inst_len = SCORE_INSTLEN;
1003
1004 if (G_FLD(inst->v, 29, 25) == 0x3
1005 && G_FLD(inst->v, 2, 0) == 0x4
1006 && G_FLD(inst->v, 19, 15) == 0)
1007 {
1008 /* sw rD, [r0, offset]+ */
1009 sp_offset += SCORE_INSTLEN;
1010
1011 if (G_FLD(inst->v, 24, 20) == 0x3)
1012 {
1013 /* rD = r3 */
1014 if (ra_offset_p == 0)
1015 {
1016 ra_offset = sp_offset;
1017 ra_offset_p = 1;
1018 }
1019 }
1020 else if (G_FLD(inst->v, 24, 20) == 0x2)
1021 {
1022 /* rD = r2 */
1023 if (fp_offset_p == 0)
1024 {
1025 fp_offset = sp_offset;
1026 fp_offset_p = 1;
1027 }
1028 }
1029 }
1030 else if (G_FLD(inst->v, 29, 25) == 0x14
1031 && G_FLD(inst->v, 19,15) == 0)
1032 {
1033 /* sw rD, [r0, offset] */
1034 if (G_FLD(inst->v, 24, 20) == 0x3)
1035 {
1036 /* rD = r3 */
1037 ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
1038 ra_offset_p = 1;
1039 }
1040 else if (G_FLD(inst->v, 24, 20) == 0x2)
1041 {
1042 /* rD = r2 */
1043 fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
1044 fp_offset_p = 1;
1045 }
1046 }
1047 else if (G_FLD (inst->v, 29, 15) == 0x1c60
1048 && G_FLD (inst->v, 2, 0) == 0x0)
1049 {
1050 /* lw r3, [r0]+, 4 */
1051 sp_offset -= SCORE_INSTLEN;
1052 ra_offset_p = 1;
1053 }
1054 else if (G_FLD (inst->v, 29, 15) == 0x1c40
1055 && G_FLD (inst->v, 2, 0) == 0x0)
1056 {
1057 /* lw r2, [r0]+, 4 */
1058 sp_offset -= SCORE_INSTLEN;
1059 fp_offset_p = 1;
1060 }
1061
1062 else if (G_FLD (inst->v, 29, 17) == 0x100
1063 && G_FLD (inst->v, 0, 0) == 0x0)
1064 {
1065 /* addi r0, -offset */
1066 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1067 }
1068 else if (G_FLD (inst->v, 29, 17) == 0x110
1069 && G_FLD (inst->v, 0, 0) == 0x0)
1070 {
1071 /* addi r2, offset */
1072 if (pc - cur_pc > 4)
1073 {
1074 unsigned int save_v = inst->v;
1075 inst_t *inst2 =
1076 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
1077 if (inst2->v == 0x23)
1078 {
1079 /* mv! r0, r2 */
1080 sp_offset -= G_FLD (save_v, 16, 1);
1081 }
1082 }
1083 }
1084 }
1085 }
1086
1087 /* Save RA. */
1088 if (ra_offset_p == 1)
1089 {
1090 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1091 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1092 sp + sp_offset - ra_offset;
1093 }
1094 else
1095 {
1096 this_cache->saved_regs[SCORE_PC_REGNUM] =
1097 this_cache->saved_regs[SCORE_RA_REGNUM];
1098 }
1099
1100 /* Save FP. */
1101 if (fp_offset_p == 1)
1102 {
1103 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1104 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1105 sp + sp_offset - fp_offset;
1106 }
1107
1108 /* Save SP and FP. */
1109 this_cache->base = sp + sp_offset;
1110 this_cache->fp = fp;
1111
1112 /* Don't forget to free MEMBLOCK if we allocated it. */
1113 if (memblock_ptr != NULL)
1114 score7_free_memblock (memblock_ptr);
1115 }
1116
1117 static void
1118 score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1119 struct frame_info *this_frame,
1120 struct score_frame_cache *this_cache)
1121 {
1122 CORE_ADDR sp;
1123 CORE_ADDR fp;
1124 CORE_ADDR cur_pc = startaddr;
1125 enum bfd_endian byte_order = gdbarch_byte_order (get_frame_arch (this_frame));
1126
1127 int sp_offset = 0;
1128 int ra_offset = 0;
1129 int fp_offset = 0;
1130 int ra_offset_p = 0;
1131 int fp_offset_p = 0;
1132 int inst_len = 0;
1133
1134 CORE_ADDR prev_pc = -1;
1135
1136 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1137 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1138
1139 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
1140 {
1141 inst_t *inst = NULL;
1142
1143 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1144
1145 /* FIXME: make a full-power prologue analyzer */
1146 if (inst->len == 2)
1147 {
1148 if (G_FLD (inst->v, 14, 12) == 0x0
1149 && G_FLD (inst->v, 11, 7) == 0x0
1150 && G_FLD (inst->v, 6, 5) == 0x3)
1151 {
1152 /* push! */
1153 sp_offset += 4;
1154
1155 if (G_FLD (inst->v, 4, 0) == 0x3
1156 && ra_offset_p == 0)
1157 {
1158 /* push! r3, [r0] */
1159 ra_offset = sp_offset;
1160 ra_offset_p = 1;
1161 }
1162 else if (G_FLD (inst->v, 4, 0) == 0x2
1163 && fp_offset_p == 0)
1164 {
1165 /* push! r2, [r0] */
1166 fp_offset = sp_offset;
1167 fp_offset_p = 1;
1168 }
1169 }
1170 else if (G_FLD (inst->v, 14, 12) == 0x6
1171 && G_FLD (inst->v, 11, 10) == 0x3)
1172 {
1173 /* rpush! */
1174 int start_r = G_FLD (inst->v, 9, 5);
1175 int cnt = G_FLD (inst->v, 4, 0);
1176
1177 if ((ra_offset_p == 0)
1178 && (start_r <= SCORE_RA_REGNUM)
1179 && (SCORE_RA_REGNUM < start_r + cnt))
1180 {
1181 /* rpush! contains r3 */
1182 ra_offset_p = 1;
1183 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1184 }
1185
1186 if ((fp_offset_p == 0)
1187 && (start_r <= SCORE_FP_REGNUM)
1188 && (SCORE_FP_REGNUM < start_r + cnt))
1189 {
1190 /* rpush! contains r2 */
1191 fp_offset_p = 1;
1192 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1193 }
1194
1195 sp_offset += 4 * cnt;
1196 }
1197 else if (G_FLD (inst->v, 14, 12) == 0x0
1198 && G_FLD (inst->v, 11, 7) == 0x0
1199 && G_FLD (inst->v, 6, 5) == 0x2)
1200 {
1201 /* pop! */
1202 sp_offset -= 4;
1203 }
1204 else if (G_FLD (inst->v, 14, 12) == 0x6
1205 && G_FLD (inst->v, 11, 10) == 0x2)
1206 {
1207 /* rpop! */
1208 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1209 }
1210 else if (G_FLD (inst->v, 14, 12) == 0x5
1211 && G_FLD (inst->v, 11, 10) == 0x3
1212 && G_FLD (inst->v, 9, 6) == 0x0)
1213 {
1214 /* addi! r0, -offset */
1215 int imm = G_FLD (inst->v, 5, 0);
1216 if (imm >> 5)
1217 imm = -(0x3F - imm + 1);
1218 sp_offset -= imm;
1219 }
1220 else if (G_FLD (inst->v, 14, 12) == 0x5
1221 && G_FLD (inst->v, 11, 10) == 0x3
1222 && G_FLD (inst->v, 9, 6) == 0x2)
1223 {
1224 /* addi! r2, offset */
1225 if (pc - cur_pc >= 2)
1226 {
1227 unsigned int save_v = inst->v;
1228 inst_t *inst2;
1229
1230 cur_pc += inst->len;
1231 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL, byte_order);
1232
1233 if (inst2->len == 2
1234 && G_FLD (inst2->v, 14, 10) == 0x10
1235 && G_FLD (inst2->v, 9, 5) == 0x0
1236 && G_FLD (inst2->v, 4, 0) == 0x2)
1237 {
1238 /* mv! r0, r2 */
1239 int imm = G_FLD (inst->v, 5, 0);
1240 if (imm >> 5)
1241 imm = -(0x3F - imm + 1);
1242 sp_offset -= imm;
1243 }
1244 }
1245 }
1246 }
1247 else if (inst->len == 4)
1248 {
1249 if (G_FLD (inst->v, 29, 25) == 0x3
1250 && G_FLD (inst->v, 2, 0) == 0x4
1251 && G_FLD (inst->v, 24, 20) == 0x3
1252 && G_FLD (inst->v, 19, 15) == 0x0)
1253 {
1254 /* sw r3, [r0, offset]+ */
1255 sp_offset += inst->len;
1256 if (ra_offset_p == 0)
1257 {
1258 ra_offset = sp_offset;
1259 ra_offset_p = 1;
1260 }
1261 }
1262 else if (G_FLD (inst->v, 29, 25) == 0x3
1263 && G_FLD (inst->v, 2, 0) == 0x4
1264 && G_FLD (inst->v, 24, 20) == 0x2
1265 && G_FLD (inst->v, 19, 15) == 0x0)
1266 {
1267 /* sw r2, [r0, offset]+ */
1268 sp_offset += inst->len;
1269 if (fp_offset_p == 0)
1270 {
1271 fp_offset = sp_offset;
1272 fp_offset_p = 1;
1273 }
1274 }
1275 else if (G_FLD (inst->v, 29, 25) == 0x7
1276 && G_FLD (inst->v, 2, 0) == 0x0
1277 && G_FLD (inst->v, 24, 20) == 0x3
1278 && G_FLD (inst->v, 19, 15) == 0x0)
1279 {
1280 /* lw r3, [r0]+, 4 */
1281 sp_offset -= inst->len;
1282 ra_offset_p = 1;
1283 }
1284 else if (G_FLD (inst->v, 29, 25) == 0x7
1285 && G_FLD (inst->v, 2, 0) == 0x0
1286 && G_FLD (inst->v, 24, 20) == 0x2
1287 && G_FLD (inst->v, 19, 15) == 0x0)
1288 {
1289 /* lw r2, [r0]+, 4 */
1290 sp_offset -= inst->len;
1291 fp_offset_p = 1;
1292 }
1293 else if (G_FLD (inst->v, 29, 25) == 0x1
1294 && G_FLD (inst->v, 19, 17) == 0x0
1295 && G_FLD (inst->v, 24, 20) == 0x0
1296 && G_FLD (inst->v, 0, 0) == 0x0)
1297 {
1298 /* addi r0, -offset */
1299 int imm = G_FLD (inst->v, 16, 1);
1300 if (imm >> 15)
1301 imm = -(0xFFFF - imm + 1);
1302 sp_offset -= imm;
1303 }
1304 else if (G_FLD (inst->v, 29, 25) == 0x1
1305 && G_FLD (inst->v, 19, 17) == 0x0
1306 && G_FLD (inst->v, 24, 20) == 0x2
1307 && G_FLD (inst->v, 0, 0) == 0x0)
1308 {
1309 /* addi r2, offset */
1310 if (pc - cur_pc >= 2)
1311 {
1312 unsigned int save_v = inst->v;
1313 inst_t *inst2;
1314
1315 cur_pc += inst->len;
1316 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL, byte_order);
1317
1318 if (inst2->len == 2
1319 && G_FLD (inst2->v, 14, 10) == 0x10
1320 && G_FLD (inst2->v, 9, 5) == 0x0
1321 && G_FLD (inst2->v, 4, 0) == 0x2)
1322 {
1323 /* mv! r0, r2 */
1324 int imm = G_FLD (inst->v, 16, 1);
1325 if (imm >> 15)
1326 imm = -(0xFFFF - imm + 1);
1327 sp_offset -= imm;
1328 }
1329 }
1330 }
1331 }
1332 }
1333
1334 /* Save RA. */
1335 if (ra_offset_p == 1)
1336 {
1337 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1338 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1339 sp + sp_offset - ra_offset;
1340 }
1341 else
1342 {
1343 this_cache->saved_regs[SCORE_PC_REGNUM] =
1344 this_cache->saved_regs[SCORE_RA_REGNUM];
1345 }
1346
1347 /* Save FP. */
1348 if (fp_offset_p == 1)
1349 {
1350 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1351 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1352 sp + sp_offset - fp_offset;
1353 }
1354
1355 /* Save SP and FP. */
1356 this_cache->base = sp + sp_offset;
1357 this_cache->fp = fp;
1358 }
1359
1360 static struct score_frame_cache *
1361 score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
1362 {
1363 struct score_frame_cache *cache;
1364
1365 if ((*this_cache) != NULL)
1366 return (*this_cache);
1367
1368 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1369 (*this_cache) = cache;
1370 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
1371
1372 /* Analyze the prologue. */
1373 {
1374 const CORE_ADDR pc = get_frame_pc (this_frame);
1375 CORE_ADDR start_addr;
1376
1377 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1378 if (start_addr == 0)
1379 return cache;
1380
1381 if (target_mach == bfd_mach_score3)
1382 score3_analyze_prologue (start_addr, pc, this_frame, *this_cache);
1383 else
1384 score7_analyze_prologue (start_addr, pc, this_frame, *this_cache);
1385 }
1386
1387 /* Save SP. */
1388 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1389
1390 return (*this_cache);
1391 }
1392
1393 static void
1394 score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
1395 struct frame_id *this_id)
1396 {
1397 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1398 this_cache);
1399 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
1400 }
1401
1402 static struct value *
1403 score_prologue_prev_register (struct frame_info *this_frame,
1404 void **this_cache, int regnum)
1405 {
1406 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1407 this_cache);
1408 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
1409 }
1410
1411 static const struct frame_unwind score_prologue_unwind =
1412 {
1413 NORMAL_FRAME,
1414 score_prologue_this_id,
1415 score_prologue_prev_register,
1416 NULL,
1417 default_frame_sniffer,
1418 NULL
1419 };
1420
1421 static CORE_ADDR
1422 score_prologue_frame_base_address (struct frame_info *this_frame,
1423 void **this_cache)
1424 {
1425 struct score_frame_cache *info =
1426 score_make_prologue_cache (this_frame, this_cache);
1427 return info->fp;
1428 }
1429
1430 static const struct frame_base score_prologue_frame_base =
1431 {
1432 &score_prologue_unwind,
1433 score_prologue_frame_base_address,
1434 score_prologue_frame_base_address,
1435 score_prologue_frame_base_address,
1436 };
1437
1438 static const struct frame_base *
1439 score_prologue_frame_base_sniffer (struct frame_info *this_frame)
1440 {
1441 return &score_prologue_frame_base;
1442 }
1443
1444 /* Core file support (dirty hack)
1445
1446 The core file MUST be generated by GNU/Linux on S+core */
1447
1448 static void
1449 score7_linux_supply_gregset(const struct regset *regset,
1450 struct regcache *regcache,
1451 int regnum, const void *gregs_buf, size_t len)
1452 {
1453 int regno;
1454 elf_gregset_t *gregs;
1455
1456 gdb_assert (regset != NULL);
1457 gdb_assert ((regcache != NULL) && (gregs_buf != NULL));
1458
1459 gregs = (elf_gregset_t *) gregs_buf;
1460
1461 for (regno = 0; regno < 32; regno++)
1462 if (regnum == -1 || regnum == regno)
1463 regcache_raw_supply (regcache, regno, gregs->regs + regno);
1464
1465 {
1466 struct sreg {
1467 int regnum;
1468 void *buf;
1469 } sregs [] = {
1470 { 55, &(gregs->cel) }, /* CEL */
1471 { 54, &(gregs->ceh) }, /* CEH */
1472 { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */
1473 { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */
1474 { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */
1475
1476 /* Exception occured at this address, exactly the PC we want */
1477 { 49, &(gregs->cp0_epc) }, /* PC */
1478
1479 { 38, &(gregs->cp0_ema) }, /* EMA */
1480 { 37, &(gregs->cp0_epc) }, /* EPC */
1481 { 34, &(gregs->cp0_ecr) }, /* ECR */
1482 { 33, &(gregs->cp0_condition) }, /* COND */
1483 { 32, &(gregs->cp0_psr) }, /* PSR */
1484 };
1485
1486 for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++)
1487 if (regnum == -1 || regnum == sregs[regno].regnum)
1488 regcache_raw_supply (regcache, sregs[regno].regnum, sregs[regno].buf);
1489 }
1490 }
1491
1492 /* Return the appropriate register set from the core section identified
1493 by SECT_NAME and SECT_SIZE. */
1494
1495 static const struct regset *
1496 score7_linux_regset_from_core_section(struct gdbarch *gdbarch,
1497 const char *sect_name, size_t sect_size)
1498 {
1499 struct gdbarch_tdep *tdep;
1500
1501 gdb_assert (gdbarch != NULL);
1502 gdb_assert (sect_name != NULL);
1503
1504 tdep = gdbarch_tdep (gdbarch);
1505
1506 if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t))
1507 {
1508 if (tdep->gregset == NULL)
1509 tdep->gregset = regset_alloc (gdbarch, score7_linux_supply_gregset, NULL);
1510 return tdep->gregset;
1511 }
1512
1513 return NULL;
1514 }
1515
1516 static struct gdbarch *
1517 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1518 {
1519 struct gdbarch *gdbarch;
1520 struct gdbarch_tdep *tdep;
1521 target_mach = info.bfd_arch_info->mach;
1522
1523 arches = gdbarch_list_lookup_by_info (arches, &info);
1524 if (arches != NULL)
1525 {
1526 return (arches->gdbarch);
1527 }
1528 tdep = xcalloc(1, sizeof(struct gdbarch_tdep));
1529 gdbarch = gdbarch_alloc (&info, tdep);
1530
1531 set_gdbarch_short_bit (gdbarch, 16);
1532 set_gdbarch_int_bit (gdbarch, 32);
1533 set_gdbarch_float_bit (gdbarch, 32);
1534 set_gdbarch_double_bit (gdbarch, 64);
1535 set_gdbarch_long_double_bit (gdbarch, 64);
1536 #if WITH_SIM
1537 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1538 #endif
1539 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1540 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1541 set_gdbarch_adjust_breakpoint_address (gdbarch, score_adjust_breakpoint_address);
1542 set_gdbarch_register_type (gdbarch, score_register_type);
1543 set_gdbarch_frame_align (gdbarch, score_frame_align);
1544 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1545 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1546 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1547 set_gdbarch_print_insn (gdbarch, score_print_insn);
1548
1549 switch (target_mach)
1550 {
1551 case bfd_mach_score7:
1552 set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
1553 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
1554 set_gdbarch_in_function_epilogue_p (gdbarch, score7_in_function_epilogue_p);
1555 set_gdbarch_register_name (gdbarch, score7_register_name);
1556 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
1557 /* Core file support. */
1558 set_gdbarch_regset_from_core_section (gdbarch, score7_linux_regset_from_core_section);
1559 break;
1560
1561 case bfd_mach_score3:
1562 set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
1563 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
1564 set_gdbarch_in_function_epilogue_p (gdbarch, score3_in_function_epilogue_p);
1565 set_gdbarch_register_name (gdbarch, score3_register_name);
1566 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1567 break;
1568 }
1569
1570 /* Watchpoint hooks. */
1571 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1572
1573 /* Dummy frame hooks. */
1574 set_gdbarch_return_value (gdbarch, score_return_value);
1575 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1576 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
1577 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1578
1579 /* Normal frame hooks. */
1580 dwarf2_append_unwinders (gdbarch);
1581 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1582 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
1583 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1584
1585 return gdbarch;
1586 }
1587
1588 extern initialize_file_ftype _initialize_score_tdep;
1589
1590 void
1591 _initialize_score_tdep (void)
1592 {
1593 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1594 }
This page took 0.068398 seconds and 4 git commands to generate.