Add some more casts (1/2)
[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
32d0add0 4 Copyright (C) 2006-2015 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
JB
552 int odd_sized_struct_p;
553 int arg_last_part_p = 0;
27fd2f50 554
1cfd2c3e
JB
555 arglen = TYPE_LENGTH (arg_type);
556 odd_sized_struct_p = (arglen > SCORE_REGSIZE
5e29c264 557 && arglen % SCORE_REGSIZE != 0);
27fd2f50
Q
558
559 /* If a arg should be aligned to 8 bytes (long long or double),
560 the value should be put to even register numbers. */
561 if (score_type_needs_double_align (arg_type))
562 {
563 if (argreg & 1)
564 argreg++;
565 }
566
567 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
568 the default "downward"/"upward" method:
569
570 Example:
571
572 struct struc
573 {
574 char a; char b; char c;
575 } s = {'a', 'b', 'c'};
576
577 Big endian: s = {X, 'a', 'b', 'c'}
578 Little endian: s = {'a', 'b', 'c', X}
579
580 Where X is a hole. */
581
5f814c3b 582 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
583 && (typecode == TYPE_CODE_STRUCT
584 || typecode == TYPE_CODE_UNION)
585 && argreg > SCORE_LAST_ARG_REGNUM
586 && arglen < SCORE_REGSIZE)
587 downward_offset += (SCORE_REGSIZE - arglen);
588
589 while (arglen > 0)
590 {
591 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
e17a4113 592 ULONGEST regval = extract_unsigned_integer (val, partial_len,
5f814c3b 593 byte_order);
27fd2f50
Q
594
595 /* The last part of a arg should shift left when
4c6b5505 596 gdbarch_byte_order is BFD_ENDIAN_BIG. */
5f814c3b 597 if (byte_order == BFD_ENDIAN_BIG
27fd2f50
Q
598 && arg_last_part_p == 1
599 && (typecode == TYPE_CODE_STRUCT
600 || typecode == TYPE_CODE_UNION))
601 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
602
603 /* Always increase the stack_offset and save args to stack. */
604 addr = sp + stack_offset + downward_offset;
605 write_memory (addr, val, partial_len);
606
607 if (argreg <= SCORE_LAST_ARG_REGNUM)
608 {
609 regcache_cooked_write_unsigned (regcache, argreg++, regval);
610 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
611 arg_last_part_p = 1;
612 }
613
614 val += partial_len;
615 arglen -= partial_len;
616 stack_offset += align_up (partial_len, SCORE_REGSIZE);
617 }
618 }
619
620 /* Step 5, Save SP. */
621 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
622
623 return sp;
624}
625
27fd2f50 626static CORE_ADDR
5f814c3b 627score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
628{
629 CORE_ADDR cpc = pc;
630 int iscan = 32, stack_sub = 0;
631 while (iscan-- > 0)
632 {
5f814c3b 633 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
634 if (!inst)
635 break;
5f814c3b 636 if ((inst->len == 4) && !stack_sub
27fd2f50
Q
637 && (G_FLD (inst->v, 29, 25) == 0x1
638 && G_FLD (inst->v, 24, 20) == 0x0))
639 {
640 /* addi r0, offset */
5f814c3b
DL
641 stack_sub = cpc + SCORE_INSTLEN;
642 pc = cpc + SCORE_INSTLEN;
27fd2f50 643 }
5f814c3b
DL
644 else if ((inst->len == 4)
645 && (G_FLD (inst->v, 29, 25) == 0x0)
646 && (G_FLD (inst->v, 24, 20) == 0x2)
647 && (G_FLD (inst->v, 19, 15) == 0x0)
648 && (G_FLD (inst->v, 14, 10) == 0xF)
649 && (G_FLD (inst->v, 9, 0) == 0x56))
27fd2f50
Q
650 {
651 /* mv r2, r0 */
652 pc = cpc + SCORE_INSTLEN;
653 break;
654 }
5f814c3b
DL
655 else if ((inst->len == 2)
656 && (G_FLD (inst->v, 14, 12) == 0x0)
657 && (G_FLD (inst->v, 11, 8) == 0x2)
658 && (G_FLD (inst->v, 7, 4) == 0x0)
659 && (G_FLD (inst->v, 3, 0) == 0x3))
27fd2f50
Q
660 {
661 /* mv! r2, r0 */
662 pc = cpc + SCORE16_INSTLEN;
663 break;
664 }
5f814c3b 665 else if ((inst->len == 2)
27fd2f50
Q
666 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
667 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
668 || (G_FLD (inst->v, 14, 12) == 0x0
669 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
670 break;
5f814c3b 671 else if ((inst->len == 4)
27fd2f50
Q
672 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
673 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
674 || (G_FLD (inst->v, 29, 25) == 0x0
675 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
676 break;
677
5f814c3b 678 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
27fd2f50
Q
679 }
680 return pc;
681}
682
5f814c3b
DL
683static CORE_ADDR
684score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50 685{
5f814c3b
DL
686 CORE_ADDR cpc = pc;
687 int iscan = 32, stack_sub = 0;
688 while (iscan-- > 0)
689 {
690 inst_t *inst
c378eb4e
MS
691 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
692 gdbarch_byte_order (gdbarch));
27fd2f50 693
5f814c3b
DL
694 if (!inst)
695 break;
696 if (inst->len == 4 && !stack_sub
697 && (G_FLD (inst->v, 29, 25) == 0x1)
698 && (G_FLD (inst->v, 19, 17) == 0x0)
699 && (G_FLD (inst->v, 24, 20) == 0x0))
700 {
701 /* addi r0, offset */
702 stack_sub = cpc + inst->len;
703 pc = cpc + inst->len;
704 }
705 else if (inst->len == 4
706 && (G_FLD (inst->v, 29, 25) == 0x0)
707 && (G_FLD (inst->v, 24, 20) == 0x2)
708 && (G_FLD (inst->v, 19, 15) == 0x0)
709 && (G_FLD (inst->v, 14, 10) == 0xF)
710 && (G_FLD (inst->v, 9, 0) == 0x56))
711 {
712 /* mv r2, r0 */
713 pc = cpc + inst->len;
714 break;
715 }
716 else if ((inst->len == 2)
717 && (G_FLD (inst->v, 14, 10) == 0x10)
718 && (G_FLD (inst->v, 9, 5) == 0x2)
719 && (G_FLD (inst->v, 4, 0) == 0x0))
720 {
721 /* mv! r2, r0 */
722 pc = cpc + inst->len;
723 break;
724 }
725 else if (inst->len == 2
726 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
727 || (G_FLD (inst->v, 14, 12) == 0x0
728 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
729 break;
730 else if (inst->len == 4
731 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
732 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
733 break;
734
735 cpc += inst->len;
736 }
737 return pc;
738}
739
c9cf6e20
MG
740/* Implement the stack_frame_destroyed_p gdbarch method. */
741
5f814c3b 742static int
c9cf6e20 743score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
744{
745 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
746
747 if (inst->v == 0x23)
748 return 1; /* mv! r0, r2 */
749 else if (G_FLD (inst->v, 14, 12) == 0x2
750 && G_FLD (inst->v, 3, 0) == 0xa)
751 return 1; /* pop! */
27fd2f50
Q
752 else if (G_FLD (inst->v, 14, 12) == 0x0
753 && G_FLD (inst->v, 7, 0) == 0x34)
754 return 1; /* br! r3 */
755 else if (G_FLD (inst->v, 29, 15) == 0x2
756 && G_FLD (inst->v, 6, 1) == 0x2b)
757 return 1; /* mv r0, r2 */
758 else if (G_FLD (inst->v, 29, 25) == 0x0
759 && G_FLD (inst->v, 6, 1) == 0x4
760 && G_FLD (inst->v, 19, 15) == 0x3)
761 return 1; /* br r3 */
762 else
763 return 0;
764}
765
c9cf6e20
MG
766/* Implement the stack_frame_destroyed_p gdbarch method. */
767
5f814c3b 768static int
c9cf6e20 769score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
770{
771 CORE_ADDR pc = cur_pc;
772 inst_t *inst
c378eb4e
MS
773 = score3_adjust_pc_and_fetch_inst (&pc, NULL,
774 gdbarch_byte_order (gdbarch));
5f814c3b
DL
775
776 if (inst->len == 2
777 && (G_FLD (inst->v, 14, 10) == 0x10)
778 && (G_FLD (inst->v, 9, 5) == 0x0)
779 && (G_FLD (inst->v, 4, 0) == 0x2))
780 return 1; /* mv! r0, r2 */
781 else if (inst->len == 4
782 && (G_FLD (inst->v, 29, 25) == 0x0)
783 && (G_FLD (inst->v, 24, 20) == 0x2)
784 && (G_FLD (inst->v, 19, 15) == 0x0)
785 && (G_FLD (inst->v, 14, 10) == 0xF)
786 && (G_FLD (inst->v, 9, 0) == 0x56))
787 return 1; /* mv r0, r2 */
788 else if (inst->len == 2
789 && (G_FLD (inst->v, 14, 12) == 0x0)
790 && (G_FLD (inst->v, 11, 5) == 0x2))
791 return 1; /* pop! */
792 else if (inst->len == 2
793 && (G_FLD (inst->v, 14, 12) == 0x0)
794 && (G_FLD (inst->v, 11, 7) == 0x0)
795 && (G_FLD (inst->v, 6, 5) == 0x2))
796 return 1; /* rpop! */
797 else if (inst->len == 2
798 && (G_FLD (inst->v, 14, 12) == 0x0)
799 && (G_FLD (inst->v, 11, 5) == 0x4)
800 && (G_FLD (inst->v, 4, 0) == 0x3))
801 return 1; /* br! r3 */
802 else if (inst->len == 4
803 && (G_FLD (inst->v, 29, 25) == 0x0)
804 && (G_FLD (inst->v, 24, 20) == 0x0)
805 && (G_FLD (inst->v, 19, 15) == 0x3)
806 && (G_FLD (inst->v, 14, 10) == 0xF)
807 && (G_FLD (inst->v, 9, 0) == 0x8))
808 return 1; /* br r3 */
809 else
810 return 0;
811}
812
e362b510 813static gdb_byte *
5f814c3b
DL
814score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
815{
816 int ret;
e362b510 817 gdb_byte *memblock = NULL;
5f814c3b
DL
818
819 if (size < 0)
820 {
a73c6dcd 821 error (_("Error: malloc size < 0 in file:%s, line:%d!"),
5f814c3b
DL
822 __FILE__, __LINE__);
823 return NULL;
824 }
825 else if (size == 0)
826 return NULL;
827
224c3ddb 828 memblock = (gdb_byte *) xmalloc (size);
5f814c3b
DL
829 memset (memblock, 0, size);
830 ret = target_read_memory (addr & ~0x3, memblock, size);
831 if (ret)
832 {
a73c6dcd 833 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
834 __FILE__, __LINE__);
835 return NULL;
836 }
837 return memblock;
838}
839
27fd2f50 840static void
948f8e3d 841score7_free_memblock (gdb_byte *memblock)
5f814c3b
DL
842{
843 xfree (memblock);
844}
845
846static void
e362b510 847score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
5f814c3b
DL
848 CORE_ADDR cur_pc)
849{
850 if (prev_pc == -1)
851 {
852 /* First time call this function, do nothing. */
853 }
854 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
855 {
856 /* First 16-bit instruction, then 32-bit instruction. */
857 *memblock += SCORE_INSTLEN;
858 }
859 else if (cur_pc - prev_pc == 4)
860 {
861 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
862 *memblock += SCORE_INSTLEN;
863 }
864}
865
866static void
867score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
94afd7a6 868 struct frame_info *this_frame,
27fd2f50
Q
869 struct score_frame_cache *this_cache)
870{
94afd7a6 871 struct gdbarch *gdbarch = get_frame_arch (this_frame);
27fd2f50 872 CORE_ADDR sp;
5e29c264 873 CORE_ADDR fp;
27fd2f50
Q
874 CORE_ADDR cur_pc = startaddr;
875
876 int sp_offset = 0;
877 int ra_offset = 0;
878 int fp_offset = 0;
879 int ra_offset_p = 0;
880 int fp_offset_p = 0;
881 int inst_len = 0;
882
e362b510
PA
883 gdb_byte *memblock = NULL;
884 gdb_byte *memblock_ptr = NULL;
5e29c264
Q
885 CORE_ADDR prev_pc = -1;
886
887 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
888 memblock_ptr = memblock =
5f814c3b 889 score7_malloc_and_get_memblock (startaddr, pc - startaddr);
5e29c264 890
94afd7a6
UW
891 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
892 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
27fd2f50 893
5e29c264 894 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
27fd2f50 895 {
5e29c264
Q
896 inst_t *inst = NULL;
897 if (memblock != NULL)
898 {
899 /* Reading memory block from target succefully and got all
900 the instructions(from STARTADDR to PC) needed. */
5f814c3b
DL
901 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
902 inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
5e29c264
Q
903 }
904 else
905 {
906 /* Otherwise, we fetch 4 bytes from target, and GDB also
907 work correctly. */
5f814c3b 908 inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
5e29c264
Q
909 }
910
c378eb4e 911 /* FIXME: make a full-power prologue analyzer. */
5f814c3b 912 if (inst->len == 2)
27fd2f50
Q
913 {
914 inst_len = SCORE16_INSTLEN;
915
916 if (G_FLD (inst->v, 14, 12) == 0x2
917 && G_FLD (inst->v, 3, 0) == 0xe)
918 {
919 /* push! */
920 sp_offset += 4;
921
922 if (G_FLD (inst->v, 11, 7) == 0x6
923 && ra_offset_p == 0)
924 {
925 /* push! r3, [r0] */
926 ra_offset = sp_offset;
927 ra_offset_p = 1;
928 }
929 else if (G_FLD (inst->v, 11, 7) == 0x4
930 && fp_offset_p == 0)
931 {
932 /* push! r2, [r0] */
933 fp_offset = sp_offset;
934 fp_offset_p = 1;
935 }
936 }
937 else if (G_FLD (inst->v, 14, 12) == 0x2
938 && G_FLD (inst->v, 3, 0) == 0xa)
939 {
940 /* pop! */
941 sp_offset -= 4;
942 }
943 else if (G_FLD (inst->v, 14, 7) == 0xc1
944 && G_FLD (inst->v, 2, 0) == 0x0)
945 {
946 /* subei! r0, n */
947 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
948 }
949 else if (G_FLD (inst->v, 14, 7) == 0xc0
950 && G_FLD (inst->v, 2, 0) == 0x0)
951 {
952 /* addei! r0, n */
953 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
954 }
955 }
956 else
957 {
958 inst_len = SCORE_INSTLEN;
959
5f814c3b
DL
960 if (G_FLD(inst->v, 29, 25) == 0x3
961 && G_FLD(inst->v, 2, 0) == 0x4
962 && G_FLD(inst->v, 19, 15) == 0)
27fd2f50 963 {
5f814c3b
DL
964 /* sw rD, [r0, offset]+ */
965 sp_offset += SCORE_INSTLEN;
966
967 if (G_FLD(inst->v, 24, 20) == 0x3)
968 {
969 /* rD = r3 */
970 if (ra_offset_p == 0)
971 {
972 ra_offset = sp_offset;
973 ra_offset_p = 1;
974 }
975 }
976 else if (G_FLD(inst->v, 24, 20) == 0x2)
977 {
978 /* rD = r2 */
979 if (fp_offset_p == 0)
980 {
981 fp_offset = sp_offset;
982 fp_offset_p = 1;
983 }
984 }
27fd2f50 985 }
5f814c3b
DL
986 else if (G_FLD(inst->v, 29, 25) == 0x14
987 && G_FLD(inst->v, 19,15) == 0)
27fd2f50 988 {
5f814c3b
DL
989 /* sw rD, [r0, offset] */
990 if (G_FLD(inst->v, 24, 20) == 0x3)
991 {
992 /* rD = r3 */
993 ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
994 ra_offset_p = 1;
995 }
996 else if (G_FLD(inst->v, 24, 20) == 0x2)
997 {
998 /* rD = r2 */
999 fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
1000 fp_offset_p = 1;
1001 }
27fd2f50
Q
1002 }
1003 else if (G_FLD (inst->v, 29, 15) == 0x1c60
1004 && G_FLD (inst->v, 2, 0) == 0x0)
1005 {
1006 /* lw r3, [r0]+, 4 */
1007 sp_offset -= SCORE_INSTLEN;
1008 ra_offset_p = 1;
1009 }
1010 else if (G_FLD (inst->v, 29, 15) == 0x1c40
1011 && G_FLD (inst->v, 2, 0) == 0x0)
1012 {
1013 /* lw r2, [r0]+, 4 */
1014 sp_offset -= SCORE_INSTLEN;
1015 fp_offset_p = 1;
1016 }
1017
1018 else if (G_FLD (inst->v, 29, 17) == 0x100
1019 && G_FLD (inst->v, 0, 0) == 0x0)
1020 {
1021 /* addi r0, -offset */
1022 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1023 }
1024 else if (G_FLD (inst->v, 29, 17) == 0x110
1025 && G_FLD (inst->v, 0, 0) == 0x0)
1026 {
1027 /* addi r2, offset */
1028 if (pc - cur_pc > 4)
1029 {
1030 unsigned int save_v = inst->v;
1031 inst_t *inst2 =
5f814c3b 1032 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
27fd2f50 1033 if (inst2->v == 0x23)
5e29c264
Q
1034 {
1035 /* mv! r0, r2 */
1036 sp_offset -= G_FLD (save_v, 16, 1);
1037 }
27fd2f50
Q
1038 }
1039 }
1040 }
1041 }
1042
1043 /* Save RA. */
1044 if (ra_offset_p == 1)
1045 {
1046 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1047 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1048 sp + sp_offset - ra_offset;
1049 }
1050 else
1051 {
1052 this_cache->saved_regs[SCORE_PC_REGNUM] =
1053 this_cache->saved_regs[SCORE_RA_REGNUM];
1054 }
1055
1056 /* Save FP. */
1057 if (fp_offset_p == 1)
1058 {
1059 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1060 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1061 sp + sp_offset - fp_offset;
1062 }
1063
5e29c264
Q
1064 /* Save SP and FP. */
1065 this_cache->base = sp + sp_offset;
1066 this_cache->fp = fp;
1067
1068 /* Don't forget to free MEMBLOCK if we allocated it. */
1069 if (memblock_ptr != NULL)
5f814c3b
DL
1070 score7_free_memblock (memblock_ptr);
1071}
1072
1073static void
1074score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1075 struct frame_info *this_frame,
1076 struct score_frame_cache *this_cache)
1077{
1078 CORE_ADDR sp;
1079 CORE_ADDR fp;
1080 CORE_ADDR cur_pc = startaddr;
c378eb4e
MS
1081 enum bfd_endian byte_order
1082 = gdbarch_byte_order (get_frame_arch (this_frame));
5f814c3b
DL
1083
1084 int sp_offset = 0;
1085 int ra_offset = 0;
1086 int fp_offset = 0;
1087 int ra_offset_p = 0;
1088 int fp_offset_p = 0;
1089 int inst_len = 0;
1090
1091 CORE_ADDR prev_pc = -1;
1092
1093 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1094 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1095
1096 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
1097 {
1098 inst_t *inst = NULL;
1099
1100 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1101
c378eb4e 1102 /* FIXME: make a full-power prologue analyzer. */
5f814c3b
DL
1103 if (inst->len == 2)
1104 {
1105 if (G_FLD (inst->v, 14, 12) == 0x0
1106 && G_FLD (inst->v, 11, 7) == 0x0
1107 && G_FLD (inst->v, 6, 5) == 0x3)
1108 {
1109 /* push! */
1110 sp_offset += 4;
1111
1112 if (G_FLD (inst->v, 4, 0) == 0x3
1113 && ra_offset_p == 0)
1114 {
1115 /* push! r3, [r0] */
1116 ra_offset = sp_offset;
1117 ra_offset_p = 1;
1118 }
1119 else if (G_FLD (inst->v, 4, 0) == 0x2
1120 && fp_offset_p == 0)
1121 {
1122 /* push! r2, [r0] */
1123 fp_offset = sp_offset;
1124 fp_offset_p = 1;
1125 }
1126 }
1127 else if (G_FLD (inst->v, 14, 12) == 0x6
1128 && G_FLD (inst->v, 11, 10) == 0x3)
1129 {
1130 /* rpush! */
1131 int start_r = G_FLD (inst->v, 9, 5);
1132 int cnt = G_FLD (inst->v, 4, 0);
1133
1134 if ((ra_offset_p == 0)
1135 && (start_r <= SCORE_RA_REGNUM)
1136 && (SCORE_RA_REGNUM < start_r + cnt))
1137 {
1138 /* rpush! contains r3 */
1139 ra_offset_p = 1;
1140 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1141 }
1142
1143 if ((fp_offset_p == 0)
1144 && (start_r <= SCORE_FP_REGNUM)
1145 && (SCORE_FP_REGNUM < start_r + cnt))
1146 {
1147 /* rpush! contains r2 */
1148 fp_offset_p = 1;
1149 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1150 }
1151
1152 sp_offset += 4 * cnt;
1153 }
1154 else if (G_FLD (inst->v, 14, 12) == 0x0
1155 && G_FLD (inst->v, 11, 7) == 0x0
1156 && G_FLD (inst->v, 6, 5) == 0x2)
1157 {
1158 /* pop! */
1159 sp_offset -= 4;
1160 }
1161 else if (G_FLD (inst->v, 14, 12) == 0x6
1162 && G_FLD (inst->v, 11, 10) == 0x2)
1163 {
1164 /* rpop! */
1165 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1166 }
1167 else if (G_FLD (inst->v, 14, 12) == 0x5
1168 && G_FLD (inst->v, 11, 10) == 0x3
1169 && G_FLD (inst->v, 9, 6) == 0x0)
1170 {
1171 /* addi! r0, -offset */
1172 int imm = G_FLD (inst->v, 5, 0);
1173 if (imm >> 5)
1174 imm = -(0x3F - imm + 1);
1175 sp_offset -= imm;
1176 }
1177 else if (G_FLD (inst->v, 14, 12) == 0x5
1178 && G_FLD (inst->v, 11, 10) == 0x3
1179 && G_FLD (inst->v, 9, 6) == 0x2)
1180 {
1181 /* addi! r2, offset */
1182 if (pc - cur_pc >= 2)
1183 {
1184 unsigned int save_v = inst->v;
1185 inst_t *inst2;
1186
1187 cur_pc += inst->len;
c378eb4e
MS
1188 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1189 byte_order);
5f814c3b
DL
1190
1191 if (inst2->len == 2
1192 && G_FLD (inst2->v, 14, 10) == 0x10
1193 && G_FLD (inst2->v, 9, 5) == 0x0
1194 && G_FLD (inst2->v, 4, 0) == 0x2)
1195 {
1196 /* mv! r0, r2 */
1197 int imm = G_FLD (inst->v, 5, 0);
1198 if (imm >> 5)
1199 imm = -(0x3F - imm + 1);
1200 sp_offset -= imm;
1201 }
1202 }
1203 }
1204 }
1205 else if (inst->len == 4)
1206 {
1207 if (G_FLD (inst->v, 29, 25) == 0x3
1208 && G_FLD (inst->v, 2, 0) == 0x4
1209 && G_FLD (inst->v, 24, 20) == 0x3
1210 && G_FLD (inst->v, 19, 15) == 0x0)
1211 {
1212 /* sw r3, [r0, offset]+ */
1213 sp_offset += inst->len;
1214 if (ra_offset_p == 0)
1215 {
1216 ra_offset = sp_offset;
1217 ra_offset_p = 1;
1218 }
1219 }
1220 else if (G_FLD (inst->v, 29, 25) == 0x3
1221 && G_FLD (inst->v, 2, 0) == 0x4
1222 && G_FLD (inst->v, 24, 20) == 0x2
1223 && G_FLD (inst->v, 19, 15) == 0x0)
1224 {
1225 /* sw r2, [r0, offset]+ */
1226 sp_offset += inst->len;
1227 if (fp_offset_p == 0)
1228 {
1229 fp_offset = sp_offset;
1230 fp_offset_p = 1;
1231 }
1232 }
1233 else if (G_FLD (inst->v, 29, 25) == 0x7
1234 && G_FLD (inst->v, 2, 0) == 0x0
1235 && G_FLD (inst->v, 24, 20) == 0x3
1236 && G_FLD (inst->v, 19, 15) == 0x0)
1237 {
1238 /* lw r3, [r0]+, 4 */
1239 sp_offset -= inst->len;
1240 ra_offset_p = 1;
1241 }
1242 else if (G_FLD (inst->v, 29, 25) == 0x7
1243 && G_FLD (inst->v, 2, 0) == 0x0
1244 && G_FLD (inst->v, 24, 20) == 0x2
1245 && G_FLD (inst->v, 19, 15) == 0x0)
1246 {
1247 /* lw r2, [r0]+, 4 */
1248 sp_offset -= inst->len;
1249 fp_offset_p = 1;
1250 }
1251 else if (G_FLD (inst->v, 29, 25) == 0x1
1252 && G_FLD (inst->v, 19, 17) == 0x0
1253 && G_FLD (inst->v, 24, 20) == 0x0
1254 && G_FLD (inst->v, 0, 0) == 0x0)
1255 {
1256 /* addi r0, -offset */
1257 int imm = G_FLD (inst->v, 16, 1);
1258 if (imm >> 15)
1259 imm = -(0xFFFF - imm + 1);
1260 sp_offset -= imm;
1261 }
1262 else if (G_FLD (inst->v, 29, 25) == 0x1
1263 && G_FLD (inst->v, 19, 17) == 0x0
1264 && G_FLD (inst->v, 24, 20) == 0x2
1265 && G_FLD (inst->v, 0, 0) == 0x0)
1266 {
1267 /* addi r2, offset */
1268 if (pc - cur_pc >= 2)
1269 {
1270 unsigned int save_v = inst->v;
1271 inst_t *inst2;
1272
1273 cur_pc += inst->len;
c378eb4e
MS
1274 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1275 byte_order);
5f814c3b
DL
1276
1277 if (inst2->len == 2
1278 && G_FLD (inst2->v, 14, 10) == 0x10
1279 && G_FLD (inst2->v, 9, 5) == 0x0
1280 && G_FLD (inst2->v, 4, 0) == 0x2)
1281 {
1282 /* mv! r0, r2 */
1283 int imm = G_FLD (inst->v, 16, 1);
1284 if (imm >> 15)
1285 imm = -(0xFFFF - imm + 1);
1286 sp_offset -= imm;
1287 }
1288 }
1289 }
1290 }
1291 }
1292
1293 /* Save RA. */
1294 if (ra_offset_p == 1)
1295 {
1296 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1297 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1298 sp + sp_offset - ra_offset;
1299 }
1300 else
1301 {
1302 this_cache->saved_regs[SCORE_PC_REGNUM] =
1303 this_cache->saved_regs[SCORE_RA_REGNUM];
1304 }
1305
1306 /* Save FP. */
1307 if (fp_offset_p == 1)
1308 {
1309 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1310 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1311 sp + sp_offset - fp_offset;
1312 }
1313
1314 /* Save SP and FP. */
1315 this_cache->base = sp + sp_offset;
1316 this_cache->fp = fp;
27fd2f50
Q
1317}
1318
1319static struct score_frame_cache *
94afd7a6 1320score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
27fd2f50
Q
1321{
1322 struct score_frame_cache *cache;
1323
1324 if ((*this_cache) != NULL)
1325 return (*this_cache);
1326
1327 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1328 (*this_cache) = cache;
94afd7a6 1329 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
27fd2f50
Q
1330
1331 /* Analyze the prologue. */
1332 {
94afd7a6 1333 const CORE_ADDR pc = get_frame_pc (this_frame);
27fd2f50
Q
1334 CORE_ADDR start_addr;
1335
1336 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1337 if (start_addr == 0)
1338 return cache;
5f814c3b
DL
1339
1340 if (target_mach == bfd_mach_score3)
1341 score3_analyze_prologue (start_addr, pc, this_frame, *this_cache);
1342 else
1343 score7_analyze_prologue (start_addr, pc, this_frame, *this_cache);
27fd2f50
Q
1344 }
1345
1346 /* Save SP. */
1347 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1348
1349 return (*this_cache);
1350}
1351
1352static void
94afd7a6 1353score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
1354 struct frame_id *this_id)
1355{
94afd7a6 1356 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1357 this_cache);
94afd7a6 1358 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
1359}
1360
94afd7a6
UW
1361static struct value *
1362score_prologue_prev_register (struct frame_info *this_frame,
1363 void **this_cache, int regnum)
27fd2f50 1364{
94afd7a6 1365 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1366 this_cache);
94afd7a6 1367 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
1368}
1369
1370static const struct frame_unwind score_prologue_unwind =
1371{
1372 NORMAL_FRAME,
8fbca658 1373 default_frame_unwind_stop_reason,
27fd2f50 1374 score_prologue_this_id,
94afd7a6
UW
1375 score_prologue_prev_register,
1376 NULL,
5f814c3b
DL
1377 default_frame_sniffer,
1378 NULL
27fd2f50
Q
1379};
1380
27fd2f50 1381static CORE_ADDR
94afd7a6 1382score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1383 void **this_cache)
1384{
1385 struct score_frame_cache *info =
94afd7a6 1386 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1387 return info->fp;
27fd2f50
Q
1388}
1389
1390static const struct frame_base score_prologue_frame_base =
1391{
1392 &score_prologue_unwind,
1393 score_prologue_frame_base_address,
1394 score_prologue_frame_base_address,
1395 score_prologue_frame_base_address,
1396};
1397
1398static const struct frame_base *
94afd7a6 1399score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1400{
1401 return &score_prologue_frame_base;
1402}
1403
c5741217
AA
1404/* Core file support. */
1405
1406static const struct regcache_map_entry score7_linux_gregmap[] =
1407 {
1408 /* FIXME: According to the current Linux kernel, r0 is preceded by
1409 9 rather than 7 words. */
1410 { 7, REGCACHE_MAP_SKIP, 4 },
1411 { 32, 0, 4 }, /* r0 ... r31 */
1412 { 1, 55, 4 }, /* CEL */
1413 { 1, 54, 4 }, /* CEH */
1414 { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */
1415 { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */
1416 { 1, 51, 4 }, /* sr2, i.e. scr or STCR */
1417 { 1, 49, 4 }, /* PC (same slot as EPC) */
1418 { 1, 38, 4 }, /* EMA */
1419 { 1, 32, 4 }, /* PSR */
1420 { 1, 34, 4 }, /* ECR */
1421 { 1, 33, 4 }, /* COND */
1422 { 0 }
1423 };
1424
1425#define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1426#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
5f814c3b
DL
1427
1428static void
1429score7_linux_supply_gregset(const struct regset *regset,
c5741217
AA
1430 struct regcache *regcache,
1431 int regnum, const void *buf,
1432 size_t size)
5f814c3b 1433{
c5741217
AA
1434 regcache_supply_regset (regset, regcache, regnum, buf, size);
1435
1436 /* Supply the EPC from the same slot as the PC. Note that the
1437 collect function will store the PC in that slot. */
1438 if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1439 && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1440 regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
1441 (const gdb_byte *) buf
1442 + SCORE7_LINUX_EPC_OFFSET);
5f814c3b
DL
1443}
1444
8fea3224
AA
1445static const struct regset score7_linux_gregset =
1446 {
c5741217
AA
1447 score7_linux_gregmap,
1448 score7_linux_supply_gregset,
1449 regcache_collect_regset
8fea3224
AA
1450 };
1451
9845a0b5 1452/* Iterate over core file register note sections. */
5f814c3b 1453
9845a0b5
AA
1454static void
1455score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1456 iterate_over_regset_sections_cb *cb,
1457 void *cb_data,
1458 const struct regcache *regcache)
5f814c3b 1459{
9845a0b5
AA
1460 cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
1461 NULL, cb_data);
5f814c3b
DL
1462}
1463
27fd2f50
Q
1464static struct gdbarch *
1465score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1466{
1467 struct gdbarch *gdbarch;
5f814c3b 1468 target_mach = info.bfd_arch_info->mach;
27fd2f50
Q
1469
1470 arches = gdbarch_list_lookup_by_info (arches, &info);
1471 if (arches != NULL)
1472 {
1473 return (arches->gdbarch);
1474 }
8fea3224 1475 gdbarch = gdbarch_alloc (&info, NULL);
27fd2f50
Q
1476
1477 set_gdbarch_short_bit (gdbarch, 16);
1478 set_gdbarch_int_bit (gdbarch, 32);
1479 set_gdbarch_float_bit (gdbarch, 32);
1480 set_gdbarch_double_bit (gdbarch, 64);
1481 set_gdbarch_long_double_bit (gdbarch, 64);
5f814c3b 1482#if WITH_SIM
27fd2f50 1483 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
5f814c3b 1484#endif
27fd2f50
Q
1485 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1486 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
c378eb4e
MS
1487 set_gdbarch_adjust_breakpoint_address (gdbarch,
1488 score_adjust_breakpoint_address);
27fd2f50
Q
1489 set_gdbarch_register_type (gdbarch, score_register_type);
1490 set_gdbarch_frame_align (gdbarch, score_frame_align);
1491 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
30244cd8 1492 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
5f814c3b 1493 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
27fd2f50 1494 set_gdbarch_print_insn (gdbarch, score_print_insn);
5f814c3b
DL
1495
1496 switch (target_mach)
1497 {
1498 case bfd_mach_score7:
1499 set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
1500 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
c9cf6e20
MG
1501 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1502 score7_stack_frame_destroyed_p);
5f814c3b
DL
1503 set_gdbarch_register_name (gdbarch, score7_register_name);
1504 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
c378eb4e 1505 /* Core file support. */
9845a0b5
AA
1506 set_gdbarch_iterate_over_regset_sections
1507 (gdbarch, score7_linux_iterate_over_regset_sections);
5f814c3b
DL
1508 break;
1509
1510 case bfd_mach_score3:
1511 set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
1512 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
c9cf6e20
MG
1513 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1514 score3_stack_frame_destroyed_p);
5f814c3b
DL
1515 set_gdbarch_register_name (gdbarch, score3_register_name);
1516 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1517 break;
1518 }
5e29c264
Q
1519
1520 /* Watchpoint hooks. */
1521 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1522
1523 /* Dummy frame hooks. */
27fd2f50 1524 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1525 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1526 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1527 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1528
5e29c264 1529 /* Normal frame hooks. */
94afd7a6 1530 dwarf2_append_unwinders (gdbarch);
27fd2f50 1531 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1532 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1533 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1534
1535 return gdbarch;
1536}
1537
1538extern initialize_file_ftype _initialize_score_tdep;
1539
1540void
1541_initialize_score_tdep (void)
1542{
1543 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1544}
This page took 1.240802 seconds and 4 git commands to generate.