Use 'ptid_t' instead of 'ptid' for fbsd_next_vfork_done's return type.
[deliverable/binutils-gdb.git] / gdb / score-tdep.c
CommitLineData
27fd2f50
Q
1/* Target-dependent code for the S+core architecture, for GDB,
2 the GNU Debugger.
3
618f726f 4 Copyright (C) 2006-2016 Free Software Foundation, Inc.
27fd2f50
Q
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
a9762ec7 13 the Free Software Foundation; either version 3 of the License, or
27fd2f50
Q
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
a9762ec7 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27fd2f50
Q
23
24#include "defs.h"
27fd2f50
Q
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"
5f814c3b 32#include "regset.h"
27fd2f50
Q
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
5f814c3b
DL
40#define G_FLD(_i,_ms,_ls) \
41 ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
27fd2f50
Q
42
43typedef struct{
c378eb4e
MS
44 unsigned long long v;
45 unsigned long long raw;
46 unsigned int len;
27fd2f50
Q
47}inst_t;
48
49struct score_frame_cache
50{
51 CORE_ADDR base;
5e29c264 52 CORE_ADDR fp;
27fd2f50
Q
53 struct trad_frame_saved_reg *saved_regs;
54};
55
5f814c3b 56static int target_mach = bfd_mach_score7;
5e29c264 57
27fd2f50
Q
58static struct type *
59score_register_type (struct gdbarch *gdbarch, int regnum)
60{
5f814c3b 61 gdb_assert (regnum >= 0
c378eb4e
MS
62 && regnum < ((target_mach == bfd_mach_score7)
63 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
df4df182 64 return builtin_type (gdbarch)->builtin_uint32;
27fd2f50
Q
65}
66
5f814c3b
DL
67static CORE_ADDR
68score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
69{
70 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
71}
72
27fd2f50 73static CORE_ADDR
30244cd8 74score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
27fd2f50 75{
30244cd8 76 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
27fd2f50
Q
77}
78
5f814c3b
DL
79static const char *
80score7_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50 81{
5f814c3b
DL
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];
27fd2f50
Q
97}
98
99static const char *
5f814c3b 100score3_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50
Q
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
5f814c3b
DL
108 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
109 "EPC", "EMA", "PREV", "DREG", "DSAVE",
110 "COUNTER", "LDCR", "STCR", "CEH", "CEL",
111 "", "", "PC",
27fd2f50
Q
112 };
113
5f814c3b 114 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
27fd2f50
Q
115 return score_register_names[regnum];
116}
117
5f814c3b 118#if WITH_SIM
27fd2f50 119static int
e7faf938 120score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
27fd2f50 121{
5f814c3b 122 gdb_assert (regnum >= 0
c378eb4e
MS
123 && regnum < ((target_mach == bfd_mach_score7)
124 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
125 return regnum;
126}
5f814c3b 127#endif
27fd2f50
Q
128
129static int
130score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
131{
f52cb1b8 132 if (info->endian == BFD_ENDIAN_BIG)
27fd2f50
Q
133 return print_insn_big_score (memaddr, info);
134 else
135 return print_insn_little_score (memaddr, info);
136}
137
5f814c3b 138static inst_t *
e362b510 139score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock)
5f814c3b
DL
140{
141 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
142 static inst_t inst = { 0, 0, 0 };
e362b510 143 gdb_byte buf[SCORE_INSTLEN] = { 0 };
5f814c3b
DL
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 {
a73c6dcd 158 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
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
178static inst_t *
179score3_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;
5f814c3b
DL
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)
a73c6dcd 250 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
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
27fd2f50 309static const gdb_byte *
5f814c3b
DL
310score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
311 int *lenptr)
27fd2f50 312{
e17a4113 313 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
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 {
a73c6dcd 320 error (_("Error: target_read_memory in file:%s, line:%d!"),
5e29c264 321 __FILE__, __LINE__);
27fd2f50 322 }
e17a4113 323 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50 324
e17a4113 325 if (byte_order == BFD_ENDIAN_BIG)
27fd2f50
Q
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
5f814c3b
DL
365static const gdb_byte *
366score3_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
396static CORE_ADDR
397score_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
27fd2f50
Q
410static CORE_ADDR
411score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
412{
413 return align_down (addr, 16);
414}
415
416static void
417score_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;
5f814c3b 422 gdb_assert (regnum >= 0
c378eb4e
MS
423 && regnum < ((target_mach == bfd_mach_score7)
424 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
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:
a73c6dcd 438 error (_("Error: score_xfer_register in file:%s, line:%d!"),
5e29c264 439 __FILE__, __LINE__);
27fd2f50
Q
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
450static enum return_value_convention
6a3a010b 451score_return_value (struct gdbarch *gdbarch, struct value *function,
5f814c3b 452 struct type *type, struct regcache *regcache,
27fd2f50
Q
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;
c378eb4e 468
27fd2f50
Q
469 if (offset + xfer > TYPE_LENGTH (type))
470 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 471 score_xfer_register (regcache, regnum, xfer,
5f814c3b 472 gdbarch_byte_order(gdbarch),
27fd2f50
Q
473 readbuf, writebuf, offset);
474 }
475 return RETURN_VALUE_REGISTER_CONVENTION;
476 }
477}
478
479static struct frame_id
94afd7a6 480score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27fd2f50 481{
c378eb4e
MS
482 return frame_id_build (get_frame_register_unsigned (this_frame,
483 SCORE_SP_REGNUM),
484 get_frame_pc (this_frame));
27fd2f50
Q
485}
486
487static int
488score_type_needs_double_align (struct type *type)
489{
490 enum type_code typecode = TYPE_CODE (type);
491
5e29c264
Q
492 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
493 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
27fd2f50
Q
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
508static CORE_ADDR
509score_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{
e17a4113 514 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
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
5e29c264
Q
534 /* Step 3, Check if struct return then save the struct address to
535 r4 and increase the stack_offset by 4. */
27fd2f50
Q
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:
5e29c264
Q
543 If arg length is too long (> 4 bytes), then split the arg and
544 save every parts. */
27fd2f50
Q
545 for (argnum = 0; argnum < nargs; argnum++)
546 {
547 struct value *arg = args[argnum];
548 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
549 enum type_code typecode = TYPE_CODE (arg_type);
550 const gdb_byte *val = value_contents (arg);
551 int downward_offset = 0;
1cfd2c3e 552 int arg_last_part_p = 0;
27fd2f50 553
1cfd2c3e 554 arglen = TYPE_LENGTH (arg_type);
27fd2f50
Q
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
5f814c3b 579 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
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;
e17a4113 589 ULONGEST regval = extract_unsigned_integer (val, partial_len,
5f814c3b 590 byte_order);
27fd2f50
Q
591
592 /* The last part of a arg should shift left when
4c6b5505 593 gdbarch_byte_order is BFD_ENDIAN_BIG. */
5f814c3b 594 if (byte_order == BFD_ENDIAN_BIG
27fd2f50
Q
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
27fd2f50 623static CORE_ADDR
5f814c3b 624score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
625{
626 CORE_ADDR cpc = pc;
627 int iscan = 32, stack_sub = 0;
628 while (iscan-- > 0)
629 {
5f814c3b 630 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
631 if (!inst)
632 break;
5f814c3b 633 if ((inst->len == 4) && !stack_sub
27fd2f50
Q
634 && (G_FLD (inst->v, 29, 25) == 0x1
635 && G_FLD (inst->v, 24, 20) == 0x0))
636 {
637 /* addi r0, offset */
5f814c3b
DL
638 stack_sub = cpc + SCORE_INSTLEN;
639 pc = cpc + SCORE_INSTLEN;
27fd2f50 640 }
5f814c3b
DL
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))
27fd2f50
Q
647 {
648 /* mv r2, r0 */
649 pc = cpc + SCORE_INSTLEN;
650 break;
651 }
5f814c3b
DL
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))
27fd2f50
Q
657 {
658 /* mv! r2, r0 */
659 pc = cpc + SCORE16_INSTLEN;
660 break;
661 }
5f814c3b 662 else if ((inst->len == 2)
27fd2f50
Q
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;
5f814c3b 668 else if ((inst->len == 4)
27fd2f50
Q
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
5f814c3b 675 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
27fd2f50
Q
676 }
677 return pc;
678}
679
5f814c3b
DL
680static CORE_ADDR
681score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50 682{
5f814c3b
DL
683 CORE_ADDR cpc = pc;
684 int iscan = 32, stack_sub = 0;
685 while (iscan-- > 0)
686 {
687 inst_t *inst
c378eb4e
MS
688 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
689 gdbarch_byte_order (gdbarch));
27fd2f50 690
5f814c3b
DL
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
c9cf6e20
MG
737/* Implement the stack_frame_destroyed_p gdbarch method. */
738
5f814c3b 739static int
c9cf6e20 740score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
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! */
27fd2f50
Q
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
c9cf6e20
MG
763/* Implement the stack_frame_destroyed_p gdbarch method. */
764
5f814c3b 765static int
c9cf6e20 766score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
767{
768 CORE_ADDR pc = cur_pc;
769 inst_t *inst
c378eb4e
MS
770 = score3_adjust_pc_and_fetch_inst (&pc, NULL,
771 gdbarch_byte_order (gdbarch));
5f814c3b
DL
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
e362b510 810static gdb_byte *
5f814c3b
DL
811score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
812{
813 int ret;
e362b510 814 gdb_byte *memblock = NULL;
5f814c3b
DL
815
816 if (size < 0)
817 {
a73c6dcd 818 error (_("Error: malloc size < 0 in file:%s, line:%d!"),
5f814c3b
DL
819 __FILE__, __LINE__);
820 return NULL;
821 }
822 else if (size == 0)
823 return NULL;
824
224c3ddb 825 memblock = (gdb_byte *) xmalloc (size);
5f814c3b
DL
826 memset (memblock, 0, size);
827 ret = target_read_memory (addr & ~0x3, memblock, size);
828 if (ret)
829 {
a73c6dcd 830 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
831 __FILE__, __LINE__);
832 return NULL;
833 }
834 return memblock;
835}
836
27fd2f50 837static void
948f8e3d 838score7_free_memblock (gdb_byte *memblock)
5f814c3b
DL
839{
840 xfree (memblock);
841}
842
843static void
e362b510 844score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
5f814c3b
DL
845 CORE_ADDR cur_pc)
846{
847 if (prev_pc == -1)
848 {
849 /* First time call this function, do nothing. */
850 }
851 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
852 {
853 /* First 16-bit instruction, then 32-bit instruction. */
854 *memblock += SCORE_INSTLEN;
855 }
856 else if (cur_pc - prev_pc == 4)
857 {
858 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
859 *memblock += SCORE_INSTLEN;
860 }
861}
862
863static void
864score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
94afd7a6 865 struct frame_info *this_frame,
27fd2f50
Q
866 struct score_frame_cache *this_cache)
867{
94afd7a6 868 struct gdbarch *gdbarch = get_frame_arch (this_frame);
27fd2f50 869 CORE_ADDR sp;
5e29c264 870 CORE_ADDR fp;
27fd2f50
Q
871 CORE_ADDR cur_pc = startaddr;
872
873 int sp_offset = 0;
874 int ra_offset = 0;
875 int fp_offset = 0;
876 int ra_offset_p = 0;
877 int fp_offset_p = 0;
878 int inst_len = 0;
879
e362b510
PA
880 gdb_byte *memblock = NULL;
881 gdb_byte *memblock_ptr = NULL;
5e29c264
Q
882 CORE_ADDR prev_pc = -1;
883
884 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
885 memblock_ptr = memblock =
5f814c3b 886 score7_malloc_and_get_memblock (startaddr, pc - startaddr);
5e29c264 887
94afd7a6
UW
888 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
889 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
27fd2f50 890
5e29c264 891 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
27fd2f50 892 {
5e29c264
Q
893 inst_t *inst = NULL;
894 if (memblock != NULL)
895 {
896 /* Reading memory block from target succefully and got all
897 the instructions(from STARTADDR to PC) needed. */
5f814c3b
DL
898 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
899 inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
5e29c264
Q
900 }
901 else
902 {
903 /* Otherwise, we fetch 4 bytes from target, and GDB also
904 work correctly. */
5f814c3b 905 inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
5e29c264
Q
906 }
907
c378eb4e 908 /* FIXME: make a full-power prologue analyzer. */
5f814c3b 909 if (inst->len == 2)
27fd2f50
Q
910 {
911 inst_len = SCORE16_INSTLEN;
912
913 if (G_FLD (inst->v, 14, 12) == 0x2
914 && G_FLD (inst->v, 3, 0) == 0xe)
915 {
916 /* push! */
917 sp_offset += 4;
918
919 if (G_FLD (inst->v, 11, 7) == 0x6
920 && ra_offset_p == 0)
921 {
922 /* push! r3, [r0] */
923 ra_offset = sp_offset;
924 ra_offset_p = 1;
925 }
926 else if (G_FLD (inst->v, 11, 7) == 0x4
927 && fp_offset_p == 0)
928 {
929 /* push! r2, [r0] */
930 fp_offset = sp_offset;
931 fp_offset_p = 1;
932 }
933 }
934 else if (G_FLD (inst->v, 14, 12) == 0x2
935 && G_FLD (inst->v, 3, 0) == 0xa)
936 {
937 /* pop! */
938 sp_offset -= 4;
939 }
940 else if (G_FLD (inst->v, 14, 7) == 0xc1
941 && G_FLD (inst->v, 2, 0) == 0x0)
942 {
943 /* subei! r0, n */
944 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
945 }
946 else if (G_FLD (inst->v, 14, 7) == 0xc0
947 && G_FLD (inst->v, 2, 0) == 0x0)
948 {
949 /* addei! r0, n */
950 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
951 }
952 }
953 else
954 {
955 inst_len = SCORE_INSTLEN;
956
5f814c3b
DL
957 if (G_FLD(inst->v, 29, 25) == 0x3
958 && G_FLD(inst->v, 2, 0) == 0x4
959 && G_FLD(inst->v, 19, 15) == 0)
27fd2f50 960 {
5f814c3b
DL
961 /* sw rD, [r0, offset]+ */
962 sp_offset += SCORE_INSTLEN;
963
964 if (G_FLD(inst->v, 24, 20) == 0x3)
965 {
966 /* rD = r3 */
967 if (ra_offset_p == 0)
968 {
969 ra_offset = sp_offset;
970 ra_offset_p = 1;
971 }
972 }
973 else if (G_FLD(inst->v, 24, 20) == 0x2)
974 {
975 /* rD = r2 */
976 if (fp_offset_p == 0)
977 {
978 fp_offset = sp_offset;
979 fp_offset_p = 1;
980 }
981 }
27fd2f50 982 }
5f814c3b
DL
983 else if (G_FLD(inst->v, 29, 25) == 0x14
984 && G_FLD(inst->v, 19,15) == 0)
27fd2f50 985 {
5f814c3b
DL
986 /* sw rD, [r0, offset] */
987 if (G_FLD(inst->v, 24, 20) == 0x3)
988 {
989 /* rD = r3 */
990 ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
991 ra_offset_p = 1;
992 }
993 else if (G_FLD(inst->v, 24, 20) == 0x2)
994 {
995 /* rD = r2 */
996 fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
997 fp_offset_p = 1;
998 }
27fd2f50
Q
999 }
1000 else if (G_FLD (inst->v, 29, 15) == 0x1c60
1001 && G_FLD (inst->v, 2, 0) == 0x0)
1002 {
1003 /* lw r3, [r0]+, 4 */
1004 sp_offset -= SCORE_INSTLEN;
1005 ra_offset_p = 1;
1006 }
1007 else if (G_FLD (inst->v, 29, 15) == 0x1c40
1008 && G_FLD (inst->v, 2, 0) == 0x0)
1009 {
1010 /* lw r2, [r0]+, 4 */
1011 sp_offset -= SCORE_INSTLEN;
1012 fp_offset_p = 1;
1013 }
1014
1015 else if (G_FLD (inst->v, 29, 17) == 0x100
1016 && G_FLD (inst->v, 0, 0) == 0x0)
1017 {
1018 /* addi r0, -offset */
1019 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1020 }
1021 else if (G_FLD (inst->v, 29, 17) == 0x110
1022 && G_FLD (inst->v, 0, 0) == 0x0)
1023 {
1024 /* addi r2, offset */
1025 if (pc - cur_pc > 4)
1026 {
1027 unsigned int save_v = inst->v;
1028 inst_t *inst2 =
5f814c3b 1029 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
27fd2f50 1030 if (inst2->v == 0x23)
5e29c264
Q
1031 {
1032 /* mv! r0, r2 */
1033 sp_offset -= G_FLD (save_v, 16, 1);
1034 }
27fd2f50
Q
1035 }
1036 }
1037 }
1038 }
1039
1040 /* Save RA. */
1041 if (ra_offset_p == 1)
1042 {
1043 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1044 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1045 sp + sp_offset - ra_offset;
1046 }
1047 else
1048 {
1049 this_cache->saved_regs[SCORE_PC_REGNUM] =
1050 this_cache->saved_regs[SCORE_RA_REGNUM];
1051 }
1052
1053 /* Save FP. */
1054 if (fp_offset_p == 1)
1055 {
1056 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1057 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1058 sp + sp_offset - fp_offset;
1059 }
1060
5e29c264
Q
1061 /* Save SP and FP. */
1062 this_cache->base = sp + sp_offset;
1063 this_cache->fp = fp;
1064
1065 /* Don't forget to free MEMBLOCK if we allocated it. */
1066 if (memblock_ptr != NULL)
5f814c3b
DL
1067 score7_free_memblock (memblock_ptr);
1068}
1069
1070static void
1071score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1072 struct frame_info *this_frame,
1073 struct score_frame_cache *this_cache)
1074{
1075 CORE_ADDR sp;
1076 CORE_ADDR fp;
1077 CORE_ADDR cur_pc = startaddr;
c378eb4e
MS
1078 enum bfd_endian byte_order
1079 = gdbarch_byte_order (get_frame_arch (this_frame));
5f814c3b
DL
1080
1081 int sp_offset = 0;
1082 int ra_offset = 0;
1083 int fp_offset = 0;
1084 int ra_offset_p = 0;
1085 int fp_offset_p = 0;
1086 int inst_len = 0;
1087
5f814c3b
DL
1088 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1089 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1090
870f88f7 1091 for (; cur_pc < pc; cur_pc += inst_len)
5f814c3b
DL
1092 {
1093 inst_t *inst = NULL;
1094
1095 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1096
c378eb4e 1097 /* FIXME: make a full-power prologue analyzer. */
5f814c3b
DL
1098 if (inst->len == 2)
1099 {
1100 if (G_FLD (inst->v, 14, 12) == 0x0
1101 && G_FLD (inst->v, 11, 7) == 0x0
1102 && G_FLD (inst->v, 6, 5) == 0x3)
1103 {
1104 /* push! */
1105 sp_offset += 4;
1106
1107 if (G_FLD (inst->v, 4, 0) == 0x3
1108 && ra_offset_p == 0)
1109 {
1110 /* push! r3, [r0] */
1111 ra_offset = sp_offset;
1112 ra_offset_p = 1;
1113 }
1114 else if (G_FLD (inst->v, 4, 0) == 0x2
1115 && fp_offset_p == 0)
1116 {
1117 /* push! r2, [r0] */
1118 fp_offset = sp_offset;
1119 fp_offset_p = 1;
1120 }
1121 }
1122 else if (G_FLD (inst->v, 14, 12) == 0x6
1123 && G_FLD (inst->v, 11, 10) == 0x3)
1124 {
1125 /* rpush! */
1126 int start_r = G_FLD (inst->v, 9, 5);
1127 int cnt = G_FLD (inst->v, 4, 0);
1128
1129 if ((ra_offset_p == 0)
1130 && (start_r <= SCORE_RA_REGNUM)
1131 && (SCORE_RA_REGNUM < start_r + cnt))
1132 {
1133 /* rpush! contains r3 */
1134 ra_offset_p = 1;
1135 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1136 }
1137
1138 if ((fp_offset_p == 0)
1139 && (start_r <= SCORE_FP_REGNUM)
1140 && (SCORE_FP_REGNUM < start_r + cnt))
1141 {
1142 /* rpush! contains r2 */
1143 fp_offset_p = 1;
1144 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1145 }
1146
1147 sp_offset += 4 * cnt;
1148 }
1149 else if (G_FLD (inst->v, 14, 12) == 0x0
1150 && G_FLD (inst->v, 11, 7) == 0x0
1151 && G_FLD (inst->v, 6, 5) == 0x2)
1152 {
1153 /* pop! */
1154 sp_offset -= 4;
1155 }
1156 else if (G_FLD (inst->v, 14, 12) == 0x6
1157 && G_FLD (inst->v, 11, 10) == 0x2)
1158 {
1159 /* rpop! */
1160 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1161 }
1162 else if (G_FLD (inst->v, 14, 12) == 0x5
1163 && G_FLD (inst->v, 11, 10) == 0x3
1164 && G_FLD (inst->v, 9, 6) == 0x0)
1165 {
1166 /* addi! r0, -offset */
1167 int imm = G_FLD (inst->v, 5, 0);
1168 if (imm >> 5)
1169 imm = -(0x3F - imm + 1);
1170 sp_offset -= imm;
1171 }
1172 else if (G_FLD (inst->v, 14, 12) == 0x5
1173 && G_FLD (inst->v, 11, 10) == 0x3
1174 && G_FLD (inst->v, 9, 6) == 0x2)
1175 {
1176 /* addi! r2, offset */
1177 if (pc - cur_pc >= 2)
1178 {
5f814c3b
DL
1179 inst_t *inst2;
1180
1181 cur_pc += inst->len;
c378eb4e
MS
1182 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1183 byte_order);
5f814c3b
DL
1184
1185 if (inst2->len == 2
1186 && G_FLD (inst2->v, 14, 10) == 0x10
1187 && G_FLD (inst2->v, 9, 5) == 0x0
1188 && G_FLD (inst2->v, 4, 0) == 0x2)
1189 {
1190 /* mv! r0, r2 */
1191 int imm = G_FLD (inst->v, 5, 0);
1192 if (imm >> 5)
1193 imm = -(0x3F - imm + 1);
1194 sp_offset -= imm;
1195 }
1196 }
1197 }
1198 }
1199 else if (inst->len == 4)
1200 {
1201 if (G_FLD (inst->v, 29, 25) == 0x3
1202 && G_FLD (inst->v, 2, 0) == 0x4
1203 && G_FLD (inst->v, 24, 20) == 0x3
1204 && G_FLD (inst->v, 19, 15) == 0x0)
1205 {
1206 /* sw r3, [r0, offset]+ */
1207 sp_offset += inst->len;
1208 if (ra_offset_p == 0)
1209 {
1210 ra_offset = sp_offset;
1211 ra_offset_p = 1;
1212 }
1213 }
1214 else if (G_FLD (inst->v, 29, 25) == 0x3
1215 && G_FLD (inst->v, 2, 0) == 0x4
1216 && G_FLD (inst->v, 24, 20) == 0x2
1217 && G_FLD (inst->v, 19, 15) == 0x0)
1218 {
1219 /* sw r2, [r0, offset]+ */
1220 sp_offset += inst->len;
1221 if (fp_offset_p == 0)
1222 {
1223 fp_offset = sp_offset;
1224 fp_offset_p = 1;
1225 }
1226 }
1227 else if (G_FLD (inst->v, 29, 25) == 0x7
1228 && G_FLD (inst->v, 2, 0) == 0x0
1229 && G_FLD (inst->v, 24, 20) == 0x3
1230 && G_FLD (inst->v, 19, 15) == 0x0)
1231 {
1232 /* lw r3, [r0]+, 4 */
1233 sp_offset -= inst->len;
1234 ra_offset_p = 1;
1235 }
1236 else if (G_FLD (inst->v, 29, 25) == 0x7
1237 && G_FLD (inst->v, 2, 0) == 0x0
1238 && G_FLD (inst->v, 24, 20) == 0x2
1239 && G_FLD (inst->v, 19, 15) == 0x0)
1240 {
1241 /* lw r2, [r0]+, 4 */
1242 sp_offset -= inst->len;
1243 fp_offset_p = 1;
1244 }
1245 else if (G_FLD (inst->v, 29, 25) == 0x1
1246 && G_FLD (inst->v, 19, 17) == 0x0
1247 && G_FLD (inst->v, 24, 20) == 0x0
1248 && G_FLD (inst->v, 0, 0) == 0x0)
1249 {
1250 /* addi r0, -offset */
1251 int imm = G_FLD (inst->v, 16, 1);
1252 if (imm >> 15)
1253 imm = -(0xFFFF - imm + 1);
1254 sp_offset -= imm;
1255 }
1256 else if (G_FLD (inst->v, 29, 25) == 0x1
1257 && G_FLD (inst->v, 19, 17) == 0x0
1258 && G_FLD (inst->v, 24, 20) == 0x2
1259 && G_FLD (inst->v, 0, 0) == 0x0)
1260 {
1261 /* addi r2, offset */
1262 if (pc - cur_pc >= 2)
1263 {
5f814c3b
DL
1264 inst_t *inst2;
1265
1266 cur_pc += inst->len;
c378eb4e
MS
1267 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1268 byte_order);
5f814c3b
DL
1269
1270 if (inst2->len == 2
1271 && G_FLD (inst2->v, 14, 10) == 0x10
1272 && G_FLD (inst2->v, 9, 5) == 0x0
1273 && G_FLD (inst2->v, 4, 0) == 0x2)
1274 {
1275 /* mv! r0, r2 */
1276 int imm = G_FLD (inst->v, 16, 1);
1277 if (imm >> 15)
1278 imm = -(0xFFFF - imm + 1);
1279 sp_offset -= imm;
1280 }
1281 }
1282 }
1283 }
1284 }
1285
1286 /* Save RA. */
1287 if (ra_offset_p == 1)
1288 {
1289 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1290 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1291 sp + sp_offset - ra_offset;
1292 }
1293 else
1294 {
1295 this_cache->saved_regs[SCORE_PC_REGNUM] =
1296 this_cache->saved_regs[SCORE_RA_REGNUM];
1297 }
1298
1299 /* Save FP. */
1300 if (fp_offset_p == 1)
1301 {
1302 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1303 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1304 sp + sp_offset - fp_offset;
1305 }
1306
1307 /* Save SP and FP. */
1308 this_cache->base = sp + sp_offset;
1309 this_cache->fp = fp;
27fd2f50
Q
1310}
1311
1312static struct score_frame_cache *
94afd7a6 1313score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
27fd2f50
Q
1314{
1315 struct score_frame_cache *cache;
1316
1317 if ((*this_cache) != NULL)
19ba03f4 1318 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
1319
1320 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1321 (*this_cache) = cache;
94afd7a6 1322 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
27fd2f50
Q
1323
1324 /* Analyze the prologue. */
1325 {
94afd7a6 1326 const CORE_ADDR pc = get_frame_pc (this_frame);
27fd2f50
Q
1327 CORE_ADDR start_addr;
1328
1329 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1330 if (start_addr == 0)
1331 return cache;
5f814c3b
DL
1332
1333 if (target_mach == bfd_mach_score3)
19ba03f4
SM
1334 score3_analyze_prologue (start_addr, pc, this_frame,
1335 (struct score_frame_cache *) *this_cache);
5f814c3b 1336 else
19ba03f4
SM
1337 score7_analyze_prologue (start_addr, pc, this_frame,
1338 (struct score_frame_cache *) *this_cache);
27fd2f50
Q
1339 }
1340
1341 /* Save SP. */
1342 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1343
19ba03f4 1344 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
1345}
1346
1347static void
94afd7a6 1348score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
1349 struct frame_id *this_id)
1350{
94afd7a6 1351 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1352 this_cache);
94afd7a6 1353 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
1354}
1355
94afd7a6
UW
1356static struct value *
1357score_prologue_prev_register (struct frame_info *this_frame,
1358 void **this_cache, int regnum)
27fd2f50 1359{
94afd7a6 1360 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1361 this_cache);
94afd7a6 1362 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
1363}
1364
1365static const struct frame_unwind score_prologue_unwind =
1366{
1367 NORMAL_FRAME,
8fbca658 1368 default_frame_unwind_stop_reason,
27fd2f50 1369 score_prologue_this_id,
94afd7a6
UW
1370 score_prologue_prev_register,
1371 NULL,
5f814c3b
DL
1372 default_frame_sniffer,
1373 NULL
27fd2f50
Q
1374};
1375
27fd2f50 1376static CORE_ADDR
94afd7a6 1377score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1378 void **this_cache)
1379{
1380 struct score_frame_cache *info =
94afd7a6 1381 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1382 return info->fp;
27fd2f50
Q
1383}
1384
1385static const struct frame_base score_prologue_frame_base =
1386{
1387 &score_prologue_unwind,
1388 score_prologue_frame_base_address,
1389 score_prologue_frame_base_address,
1390 score_prologue_frame_base_address,
1391};
1392
1393static const struct frame_base *
94afd7a6 1394score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1395{
1396 return &score_prologue_frame_base;
1397}
1398
c5741217
AA
1399/* Core file support. */
1400
1401static const struct regcache_map_entry score7_linux_gregmap[] =
1402 {
1403 /* FIXME: According to the current Linux kernel, r0 is preceded by
1404 9 rather than 7 words. */
1405 { 7, REGCACHE_MAP_SKIP, 4 },
1406 { 32, 0, 4 }, /* r0 ... r31 */
1407 { 1, 55, 4 }, /* CEL */
1408 { 1, 54, 4 }, /* CEH */
1409 { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */
1410 { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */
1411 { 1, 51, 4 }, /* sr2, i.e. scr or STCR */
1412 { 1, 49, 4 }, /* PC (same slot as EPC) */
1413 { 1, 38, 4 }, /* EMA */
1414 { 1, 32, 4 }, /* PSR */
1415 { 1, 34, 4 }, /* ECR */
1416 { 1, 33, 4 }, /* COND */
1417 { 0 }
1418 };
1419
1420#define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1421#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
5f814c3b
DL
1422
1423static void
1424score7_linux_supply_gregset(const struct regset *regset,
c5741217
AA
1425 struct regcache *regcache,
1426 int regnum, const void *buf,
1427 size_t size)
5f814c3b 1428{
c5741217
AA
1429 regcache_supply_regset (regset, regcache, regnum, buf, size);
1430
1431 /* Supply the EPC from the same slot as the PC. Note that the
1432 collect function will store the PC in that slot. */
1433 if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1434 && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1435 regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
1436 (const gdb_byte *) buf
1437 + SCORE7_LINUX_EPC_OFFSET);
5f814c3b
DL
1438}
1439
8fea3224
AA
1440static const struct regset score7_linux_gregset =
1441 {
c5741217
AA
1442 score7_linux_gregmap,
1443 score7_linux_supply_gregset,
1444 regcache_collect_regset
8fea3224
AA
1445 };
1446
9845a0b5 1447/* Iterate over core file register note sections. */
5f814c3b 1448
9845a0b5
AA
1449static void
1450score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1451 iterate_over_regset_sections_cb *cb,
1452 void *cb_data,
1453 const struct regcache *regcache)
5f814c3b 1454{
9845a0b5
AA
1455 cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
1456 NULL, cb_data);
5f814c3b
DL
1457}
1458
27fd2f50
Q
1459static struct gdbarch *
1460score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1461{
1462 struct gdbarch *gdbarch;
5f814c3b 1463 target_mach = info.bfd_arch_info->mach;
27fd2f50
Q
1464
1465 arches = gdbarch_list_lookup_by_info (arches, &info);
1466 if (arches != NULL)
1467 {
1468 return (arches->gdbarch);
1469 }
8fea3224 1470 gdbarch = gdbarch_alloc (&info, NULL);
27fd2f50
Q
1471
1472 set_gdbarch_short_bit (gdbarch, 16);
1473 set_gdbarch_int_bit (gdbarch, 32);
1474 set_gdbarch_float_bit (gdbarch, 32);
1475 set_gdbarch_double_bit (gdbarch, 64);
1476 set_gdbarch_long_double_bit (gdbarch, 64);
5f814c3b 1477#if WITH_SIM
27fd2f50 1478 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
5f814c3b 1479#endif
27fd2f50
Q
1480 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1481 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
c378eb4e
MS
1482 set_gdbarch_adjust_breakpoint_address (gdbarch,
1483 score_adjust_breakpoint_address);
27fd2f50
Q
1484 set_gdbarch_register_type (gdbarch, score_register_type);
1485 set_gdbarch_frame_align (gdbarch, score_frame_align);
1486 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
30244cd8 1487 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
5f814c3b 1488 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
27fd2f50 1489 set_gdbarch_print_insn (gdbarch, score_print_insn);
5f814c3b
DL
1490
1491 switch (target_mach)
1492 {
1493 case bfd_mach_score7:
1494 set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
1495 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
c9cf6e20
MG
1496 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1497 score7_stack_frame_destroyed_p);
5f814c3b
DL
1498 set_gdbarch_register_name (gdbarch, score7_register_name);
1499 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
c378eb4e 1500 /* Core file support. */
9845a0b5
AA
1501 set_gdbarch_iterate_over_regset_sections
1502 (gdbarch, score7_linux_iterate_over_regset_sections);
5f814c3b
DL
1503 break;
1504
1505 case bfd_mach_score3:
1506 set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
1507 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
c9cf6e20
MG
1508 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1509 score3_stack_frame_destroyed_p);
5f814c3b
DL
1510 set_gdbarch_register_name (gdbarch, score3_register_name);
1511 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1512 break;
1513 }
5e29c264
Q
1514
1515 /* Watchpoint hooks. */
1516 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1517
1518 /* Dummy frame hooks. */
27fd2f50 1519 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1520 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1521 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1522 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1523
5e29c264 1524 /* Normal frame hooks. */
94afd7a6 1525 dwarf2_append_unwinders (gdbarch);
27fd2f50 1526 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1527 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1528 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1529
1530 return gdbarch;
1531}
1532
1533extern initialize_file_ftype _initialize_score_tdep;
1534
1535void
1536_initialize_score_tdep (void)
1537{
1538 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1539}
This page took 1.038305 seconds and 4 git commands to generate.