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