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