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