Revise the commit date of my ChangeLog entry.
[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
28e7fd62 4 Copyright (C) 2006-2013 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{
c378eb4e
MS
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 62 gdb_assert (regnum >= 0
c378eb4e
MS
63 && regnum < ((target_mach == bfd_mach_score7)
64 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
df4df182 65 return builtin_type (gdbarch)->builtin_uint32;
27fd2f50
Q
66}
67
5f814c3b
DL
68static CORE_ADDR
69score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
70{
71 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
72}
73
27fd2f50 74static CORE_ADDR
30244cd8 75score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
27fd2f50 76{
30244cd8 77 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
27fd2f50
Q
78}
79
5f814c3b
DL
80static const char *
81score7_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50 82{
5f814c3b
DL
83 const char *score_register_names[] = {
84 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
86 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
87 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
88
89 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
90 "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR",
91 "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN",
92 "PREV", "DREG", "PC", "DSAVE", "COUNTER",
93 "LDCR", "STCR", "CEH", "CEL",
94 };
95
96 gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
97 return score_register_names[regnum];
27fd2f50
Q
98}
99
100static const char *
5f814c3b 101score3_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50
Q
102{
103 const char *score_register_names[] = {
104 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
106 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
107 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
108
5f814c3b
DL
109 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
110 "EPC", "EMA", "PREV", "DREG", "DSAVE",
111 "COUNTER", "LDCR", "STCR", "CEH", "CEL",
112 "", "", "PC",
27fd2f50
Q
113 };
114
5f814c3b 115 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
27fd2f50
Q
116 return score_register_names[regnum];
117}
118
5f814c3b 119#if WITH_SIM
27fd2f50 120static int
e7faf938 121score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
27fd2f50 122{
5f814c3b 123 gdb_assert (regnum >= 0
c378eb4e
MS
124 && regnum < ((target_mach == bfd_mach_score7)
125 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
126 return regnum;
127}
5f814c3b 128#endif
27fd2f50
Q
129
130static int
131score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
132{
f52cb1b8 133 if (info->endian == BFD_ENDIAN_BIG)
27fd2f50
Q
134 return print_insn_big_score (memaddr, info);
135 else
136 return print_insn_little_score (memaddr, info);
137}
138
5f814c3b
DL
139static inst_t *
140score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
141{
142 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
143 static inst_t inst = { 0, 0, 0 };
144 char buf[SCORE_INSTLEN] = { 0 };
145 int big;
146 int ret;
147
148 if (target_has_execution && memblock != NULL)
149 {
150 /* Fetch instruction from local MEMBLOCK. */
151 memcpy (buf, memblock, SCORE_INSTLEN);
152 }
153 else
154 {
155 /* Fetch instruction from target. */
156 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
157 if (ret)
158 {
a73c6dcd 159 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
160 __FILE__, __LINE__);
161 return 0;
162 }
163 }
164
165 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
166 inst.len = (inst.raw & 0x80008000) ? 4 : 2;
167 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
168 big = (byte_order == BFD_ENDIAN_BIG);
169 if (inst.len == 2)
170 {
171 if (big ^ ((addr & 0x2) == 2))
172 inst.v = G_FLD (inst.v, 29, 15);
173 else
174 inst.v = G_FLD (inst.v, 14, 0);
175 }
176 return &inst;
177}
178
179static inst_t *
180score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
181 enum bfd_endian byte_order)
182{
183 static inst_t inst = { 0, 0, 0 };
184
185 struct breakplace
186 {
187 int break_offset;
188 int inst_len;
189 };
190 /* raw table 1 (column 2, 3, 4)
191 * 0 1 0 * # 2
192 * 0 1 1 0 # 3
193 0 1 1 0 * # 6
194 table 2 (column 1, 2, 3)
195 * 0 0 * * # 0, 4
196 0 1 0 * * # 2
197 1 1 0 * * # 6
198 */
199
200 static const struct breakplace bk_table[16] =
201 {
202 /* table 1 */
203 {0, 0},
204 {0, 0},
205 {0, 4},
206 {0, 6},
207 {0, 0},
208 {0, 0},
209 {-2, 6},
210 {0, 0},
211 /* table 2 */
212 {0, 2},
213 {0, 0},
214 {-2, 4},
215 {0, 0},
216 {0, 2},
217 {0, 0},
218 {-4, 6},
219 {0, 0}
220 };
221
222#define EXTRACT_LEN 2
223 CORE_ADDR adjust_pc = *pcptr & ~0x1;
5f814c3b
DL
224 gdb_byte buf[5][EXTRACT_LEN] =
225 {
226 {'\0', '\0'},
227 {'\0', '\0'},
228 {'\0', '\0'},
229 {'\0', '\0'},
230 {'\0', '\0'}
231 };
232 int ret;
233 unsigned int raw;
234 unsigned int cbits = 0;
235 int bk_index;
236 int i, count;
237
238 inst.v = 0;
239 inst.raw = 0;
240 inst.len = 0;
241
242 adjust_pc -= 4;
243 for (i = 0; i < 5; i++)
244 {
245 ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
246 if (ret != 0)
247 {
248 buf[i][0] = '\0';
249 buf[i][1] = '\0';
250 if (i == 2)
a73c6dcd 251 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
252 __FILE__, __LINE__);
253 }
254
255 raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
256 cbits = (cbits << 1) | (raw >> 15);
257 }
258 adjust_pc += 4;
259
260 if (cbits & 0x4)
261 {
262 /* table 1 */
263 cbits = (cbits >> 1) & 0x7;
264 bk_index = cbits;
265 }
266 else
267 {
268 /* table 2 */
269 cbits = (cbits >> 2) & 0x7;
270 bk_index = cbits + 8;
271 }
272
273 gdb_assert (!((bk_table[bk_index].break_offset == 0)
274 && (bk_table[bk_index].inst_len == 0)));
275
276 inst.len = bk_table[bk_index].inst_len;
277
278 i = (bk_table[bk_index].break_offset + 4) / 2;
279 count = inst.len / 2;
280 for (; count > 0; i++, count--)
281 {
282 inst.raw = (inst.raw << 16)
283 | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
284 }
285
286 switch (inst.len)
287 {
288 case 2:
289 inst.v = inst.raw & 0x7FFF;
290 break;
291 case 4:
292 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
293 break;
294 case 6:
295 inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
296 | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
297 break;
298 }
299
300 if (pcptr)
301 *pcptr = adjust_pc + bk_table[bk_index].break_offset;
302 if (lenptr)
303 *lenptr = bk_table[bk_index].inst_len;
304
305#undef EXTRACT_LEN
306
307 return &inst;
308}
309
27fd2f50 310static const gdb_byte *
5f814c3b
DL
311score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
312 int *lenptr)
27fd2f50 313{
e17a4113 314 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
315 gdb_byte buf[SCORE_INSTLEN] = { 0 };
316 int ret;
317 unsigned int raw;
318
319 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
320 {
a73c6dcd 321 error (_("Error: target_read_memory in file:%s, line:%d!"),
5e29c264 322 __FILE__, __LINE__);
27fd2f50 323 }
e17a4113 324 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50 325
e17a4113 326 if (byte_order == BFD_ENDIAN_BIG)
27fd2f50
Q
327 {
328 if (!(raw & 0x80008000))
329 {
330 /* 16bits instruction. */
331 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
332 *pcptr &= ~0x1;
333 *lenptr = sizeof (big_breakpoint16);
334 return big_breakpoint16;
335 }
336 else
337 {
338 /* 32bits instruction. */
339 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
340 *pcptr &= ~0x3;
341 *lenptr = sizeof (big_breakpoint32);
342 return big_breakpoint32;
343 }
344 }
345 else
346 {
347 if (!(raw & 0x80008000))
348 {
349 /* 16bits instruction. */
350 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
351 *pcptr &= ~0x1;
352 *lenptr = sizeof (little_breakpoint16);
353 return little_breakpoint16;
354 }
355 else
356 {
357 /* 32bits instruction. */
358 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
359 *pcptr &= ~0x3;
360 *lenptr = sizeof (little_breakpoint32);
361 return little_breakpoint32;
362 }
363 }
364}
365
5f814c3b
DL
366static const gdb_byte *
367score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
368 int *lenptr)
369{
370 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
371 CORE_ADDR adjust_pc = *pcptr;
372 int len;
373 static gdb_byte score_break_insns[6][6] = {
374 /* The following three instructions are big endian. */
375 { 0x00, 0x20 },
376 { 0x80, 0x00, 0x00, 0x06 },
377 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
378 /* The following three instructions are little endian. */
379 { 0x20, 0x00 },
380 { 0x00, 0x80, 0x06, 0x00 },
381 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
382
383 gdb_byte *p = NULL;
384 int index = 0;
385
386 score3_adjust_pc_and_fetch_inst (&adjust_pc, &len, byte_order);
387
388 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1);
389 p = score_break_insns[index];
390
391 *pcptr = adjust_pc;
392 *lenptr = len;
393
394 return p;
395}
396
397static CORE_ADDR
398score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
399{
400 CORE_ADDR adjust_pc = bpaddr;
401
402 if (target_mach == bfd_mach_score3)
403 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
404 gdbarch_byte_order (gdbarch));
405 else
406 adjust_pc = align_down (adjust_pc, 2);
407
408 return adjust_pc;
409}
410
27fd2f50
Q
411static CORE_ADDR
412score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
413{
414 return align_down (addr, 16);
415}
416
417static void
418score_xfer_register (struct regcache *regcache, int regnum, int length,
419 enum bfd_endian endian, gdb_byte *readbuf,
420 const gdb_byte *writebuf, int buf_offset)
421{
422 int reg_offset = 0;
5f814c3b 423 gdb_assert (regnum >= 0
c378eb4e
MS
424 && regnum < ((target_mach == bfd_mach_score7)
425 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
426
427 switch (endian)
428 {
429 case BFD_ENDIAN_BIG:
430 reg_offset = SCORE_REGSIZE - length;
431 break;
432 case BFD_ENDIAN_LITTLE:
433 reg_offset = 0;
434 break;
435 case BFD_ENDIAN_UNKNOWN:
436 reg_offset = 0;
437 break;
438 default:
a73c6dcd 439 error (_("Error: score_xfer_register in file:%s, line:%d!"),
5e29c264 440 __FILE__, __LINE__);
27fd2f50
Q
441 }
442
443 if (readbuf != NULL)
444 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
445 readbuf + buf_offset);
446 if (writebuf != NULL)
447 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
448 writebuf + buf_offset);
449}
450
451static enum return_value_convention
6a3a010b 452score_return_value (struct gdbarch *gdbarch, struct value *function,
5f814c3b 453 struct type *type, struct regcache *regcache,
27fd2f50
Q
454 gdb_byte * readbuf, const gdb_byte * writebuf)
455{
456 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
457 || TYPE_CODE (type) == TYPE_CODE_UNION
458 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
459 return RETURN_VALUE_STRUCT_CONVENTION;
460 else
461 {
462 int offset;
463 int regnum;
464 for (offset = 0, regnum = SCORE_A0_REGNUM;
465 offset < TYPE_LENGTH (type);
466 offset += SCORE_REGSIZE, regnum++)
467 {
468 int xfer = SCORE_REGSIZE;
c378eb4e 469
27fd2f50
Q
470 if (offset + xfer > TYPE_LENGTH (type))
471 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 472 score_xfer_register (regcache, regnum, xfer,
5f814c3b 473 gdbarch_byte_order(gdbarch),
27fd2f50
Q
474 readbuf, writebuf, offset);
475 }
476 return RETURN_VALUE_REGISTER_CONVENTION;
477 }
478}
479
480static struct frame_id
94afd7a6 481score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27fd2f50 482{
c378eb4e
MS
483 return frame_id_build (get_frame_register_unsigned (this_frame,
484 SCORE_SP_REGNUM),
485 get_frame_pc (this_frame));
27fd2f50
Q
486}
487
488static int
489score_type_needs_double_align (struct type *type)
490{
491 enum type_code typecode = TYPE_CODE (type);
492
5e29c264
Q
493 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
494 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
27fd2f50
Q
495 return 1;
496 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
497 {
498 int i, n;
499
500 n = TYPE_NFIELDS (type);
501 for (i = 0; i < n; i++)
502 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
503 return 1;
504 return 0;
505 }
506 return 0;
507}
508
509static CORE_ADDR
510score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
511 struct regcache *regcache, CORE_ADDR bp_addr,
512 int nargs, struct value **args, CORE_ADDR sp,
513 int struct_return, CORE_ADDR struct_addr)
514{
e17a4113 515 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
516 int argnum;
517 int argreg;
518 int arglen = 0;
519 CORE_ADDR stack_offset = 0;
520 CORE_ADDR addr = 0;
521
522 /* Step 1, Save RA. */
523 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
524
525 /* Step 2, Make space on the stack for the args. */
526 struct_addr = align_down (struct_addr, 16);
527 sp = align_down (sp, 16);
528 for (argnum = 0; argnum < nargs; argnum++)
529 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
530 SCORE_REGSIZE);
531 sp -= align_up (arglen, 16);
532
533 argreg = SCORE_BEGIN_ARG_REGNUM;
534
5e29c264
Q
535 /* Step 3, Check if struct return then save the struct address to
536 r4 and increase the stack_offset by 4. */
27fd2f50
Q
537 if (struct_return)
538 {
539 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
540 stack_offset += SCORE_REGSIZE;
541 }
542
543 /* Step 4, Load arguments:
5e29c264
Q
544 If arg length is too long (> 4 bytes), then split the arg and
545 save every parts. */
27fd2f50
Q
546 for (argnum = 0; argnum < nargs; argnum++)
547 {
548 struct value *arg = args[argnum];
549 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
550 enum type_code typecode = TYPE_CODE (arg_type);
551 const gdb_byte *val = value_contents (arg);
552 int downward_offset = 0;
1cfd2c3e
JB
553 int odd_sized_struct_p;
554 int arg_last_part_p = 0;
27fd2f50 555
1cfd2c3e
JB
556 arglen = TYPE_LENGTH (arg_type);
557 odd_sized_struct_p = (arglen > SCORE_REGSIZE
5e29c264 558 && arglen % SCORE_REGSIZE != 0);
27fd2f50
Q
559
560 /* If a arg should be aligned to 8 bytes (long long or double),
561 the value should be put to even register numbers. */
562 if (score_type_needs_double_align (arg_type))
563 {
564 if (argreg & 1)
565 argreg++;
566 }
567
568 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
569 the default "downward"/"upward" method:
570
571 Example:
572
573 struct struc
574 {
575 char a; char b; char c;
576 } s = {'a', 'b', 'c'};
577
578 Big endian: s = {X, 'a', 'b', 'c'}
579 Little endian: s = {'a', 'b', 'c', X}
580
581 Where X is a hole. */
582
5f814c3b 583 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
584 && (typecode == TYPE_CODE_STRUCT
585 || typecode == TYPE_CODE_UNION)
586 && argreg > SCORE_LAST_ARG_REGNUM
587 && arglen < SCORE_REGSIZE)
588 downward_offset += (SCORE_REGSIZE - arglen);
589
590 while (arglen > 0)
591 {
592 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
e17a4113 593 ULONGEST regval = extract_unsigned_integer (val, partial_len,
5f814c3b 594 byte_order);
27fd2f50
Q
595
596 /* The last part of a arg should shift left when
4c6b5505 597 gdbarch_byte_order is BFD_ENDIAN_BIG. */
5f814c3b 598 if (byte_order == BFD_ENDIAN_BIG
27fd2f50
Q
599 && arg_last_part_p == 1
600 && (typecode == TYPE_CODE_STRUCT
601 || typecode == TYPE_CODE_UNION))
602 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
603
604 /* Always increase the stack_offset and save args to stack. */
605 addr = sp + stack_offset + downward_offset;
606 write_memory (addr, val, partial_len);
607
608 if (argreg <= SCORE_LAST_ARG_REGNUM)
609 {
610 regcache_cooked_write_unsigned (regcache, argreg++, regval);
611 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
612 arg_last_part_p = 1;
613 }
614
615 val += partial_len;
616 arglen -= partial_len;
617 stack_offset += align_up (partial_len, SCORE_REGSIZE);
618 }
619 }
620
621 /* Step 5, Save SP. */
622 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
623
624 return sp;
625}
626
27fd2f50 627static CORE_ADDR
5f814c3b 628score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
629{
630 CORE_ADDR cpc = pc;
631 int iscan = 32, stack_sub = 0;
632 while (iscan-- > 0)
633 {
5f814c3b 634 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
635 if (!inst)
636 break;
5f814c3b 637 if ((inst->len == 4) && !stack_sub
27fd2f50
Q
638 && (G_FLD (inst->v, 29, 25) == 0x1
639 && G_FLD (inst->v, 24, 20) == 0x0))
640 {
641 /* addi r0, offset */
5f814c3b
DL
642 stack_sub = cpc + SCORE_INSTLEN;
643 pc = cpc + SCORE_INSTLEN;
27fd2f50 644 }
5f814c3b
DL
645 else if ((inst->len == 4)
646 && (G_FLD (inst->v, 29, 25) == 0x0)
647 && (G_FLD (inst->v, 24, 20) == 0x2)
648 && (G_FLD (inst->v, 19, 15) == 0x0)
649 && (G_FLD (inst->v, 14, 10) == 0xF)
650 && (G_FLD (inst->v, 9, 0) == 0x56))
27fd2f50
Q
651 {
652 /* mv r2, r0 */
653 pc = cpc + SCORE_INSTLEN;
654 break;
655 }
5f814c3b
DL
656 else if ((inst->len == 2)
657 && (G_FLD (inst->v, 14, 12) == 0x0)
658 && (G_FLD (inst->v, 11, 8) == 0x2)
659 && (G_FLD (inst->v, 7, 4) == 0x0)
660 && (G_FLD (inst->v, 3, 0) == 0x3))
27fd2f50
Q
661 {
662 /* mv! r2, r0 */
663 pc = cpc + SCORE16_INSTLEN;
664 break;
665 }
5f814c3b 666 else if ((inst->len == 2)
27fd2f50
Q
667 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
668 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
669 || (G_FLD (inst->v, 14, 12) == 0x0
670 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
671 break;
5f814c3b 672 else if ((inst->len == 4)
27fd2f50
Q
673 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
674 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
675 || (G_FLD (inst->v, 29, 25) == 0x0
676 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
677 break;
678
5f814c3b 679 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
27fd2f50
Q
680 }
681 return pc;
682}
683
5f814c3b
DL
684static CORE_ADDR
685score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50 686{
5f814c3b
DL
687 CORE_ADDR cpc = pc;
688 int iscan = 32, stack_sub = 0;
689 while (iscan-- > 0)
690 {
691 inst_t *inst
c378eb4e
MS
692 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
693 gdbarch_byte_order (gdbarch));
27fd2f50 694
5f814c3b
DL
695 if (!inst)
696 break;
697 if (inst->len == 4 && !stack_sub
698 && (G_FLD (inst->v, 29, 25) == 0x1)
699 && (G_FLD (inst->v, 19, 17) == 0x0)
700 && (G_FLD (inst->v, 24, 20) == 0x0))
701 {
702 /* addi r0, offset */
703 stack_sub = cpc + inst->len;
704 pc = cpc + inst->len;
705 }
706 else if (inst->len == 4
707 && (G_FLD (inst->v, 29, 25) == 0x0)
708 && (G_FLD (inst->v, 24, 20) == 0x2)
709 && (G_FLD (inst->v, 19, 15) == 0x0)
710 && (G_FLD (inst->v, 14, 10) == 0xF)
711 && (G_FLD (inst->v, 9, 0) == 0x56))
712 {
713 /* mv r2, r0 */
714 pc = cpc + inst->len;
715 break;
716 }
717 else if ((inst->len == 2)
718 && (G_FLD (inst->v, 14, 10) == 0x10)
719 && (G_FLD (inst->v, 9, 5) == 0x2)
720 && (G_FLD (inst->v, 4, 0) == 0x0))
721 {
722 /* mv! r2, r0 */
723 pc = cpc + inst->len;
724 break;
725 }
726 else if (inst->len == 2
727 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
728 || (G_FLD (inst->v, 14, 12) == 0x0
729 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
730 break;
731 else if (inst->len == 4
732 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
733 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
734 break;
735
736 cpc += inst->len;
737 }
738 return pc;
739}
740
741static int
742score7_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
743{
744 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
745
746 if (inst->v == 0x23)
747 return 1; /* mv! r0, r2 */
748 else if (G_FLD (inst->v, 14, 12) == 0x2
749 && G_FLD (inst->v, 3, 0) == 0xa)
750 return 1; /* pop! */
27fd2f50
Q
751 else if (G_FLD (inst->v, 14, 12) == 0x0
752 && G_FLD (inst->v, 7, 0) == 0x34)
753 return 1; /* br! r3 */
754 else if (G_FLD (inst->v, 29, 15) == 0x2
755 && G_FLD (inst->v, 6, 1) == 0x2b)
756 return 1; /* mv r0, r2 */
757 else if (G_FLD (inst->v, 29, 25) == 0x0
758 && G_FLD (inst->v, 6, 1) == 0x4
759 && G_FLD (inst->v, 19, 15) == 0x3)
760 return 1; /* br r3 */
761 else
762 return 0;
763}
764
5f814c3b
DL
765static int
766score3_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
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
810static char *
811score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
812{
813 int ret;
814 char *memblock = NULL;
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
825 memblock = (char *) xmalloc (size);
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
5f814c3b
DL
838score7_free_memblock (char *memblock)
839{
840 xfree (memblock);
841}
842
843static void
844score7_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
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
5e29c264
Q
880 char *memblock = NULL;
881 char *memblock_ptr = NULL;
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
1088 CORE_ADDR prev_pc = -1;
1089
1090 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1091 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1092
1093 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
1094 {
1095 inst_t *inst = NULL;
1096
1097 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1098
c378eb4e 1099 /* FIXME: make a full-power prologue analyzer. */
5f814c3b
DL
1100 if (inst->len == 2)
1101 {
1102 if (G_FLD (inst->v, 14, 12) == 0x0
1103 && G_FLD (inst->v, 11, 7) == 0x0
1104 && G_FLD (inst->v, 6, 5) == 0x3)
1105 {
1106 /* push! */
1107 sp_offset += 4;
1108
1109 if (G_FLD (inst->v, 4, 0) == 0x3
1110 && ra_offset_p == 0)
1111 {
1112 /* push! r3, [r0] */
1113 ra_offset = sp_offset;
1114 ra_offset_p = 1;
1115 }
1116 else if (G_FLD (inst->v, 4, 0) == 0x2
1117 && fp_offset_p == 0)
1118 {
1119 /* push! r2, [r0] */
1120 fp_offset = sp_offset;
1121 fp_offset_p = 1;
1122 }
1123 }
1124 else if (G_FLD (inst->v, 14, 12) == 0x6
1125 && G_FLD (inst->v, 11, 10) == 0x3)
1126 {
1127 /* rpush! */
1128 int start_r = G_FLD (inst->v, 9, 5);
1129 int cnt = G_FLD (inst->v, 4, 0);
1130
1131 if ((ra_offset_p == 0)
1132 && (start_r <= SCORE_RA_REGNUM)
1133 && (SCORE_RA_REGNUM < start_r + cnt))
1134 {
1135 /* rpush! contains r3 */
1136 ra_offset_p = 1;
1137 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1138 }
1139
1140 if ((fp_offset_p == 0)
1141 && (start_r <= SCORE_FP_REGNUM)
1142 && (SCORE_FP_REGNUM < start_r + cnt))
1143 {
1144 /* rpush! contains r2 */
1145 fp_offset_p = 1;
1146 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1147 }
1148
1149 sp_offset += 4 * cnt;
1150 }
1151 else if (G_FLD (inst->v, 14, 12) == 0x0
1152 && G_FLD (inst->v, 11, 7) == 0x0
1153 && G_FLD (inst->v, 6, 5) == 0x2)
1154 {
1155 /* pop! */
1156 sp_offset -= 4;
1157 }
1158 else if (G_FLD (inst->v, 14, 12) == 0x6
1159 && G_FLD (inst->v, 11, 10) == 0x2)
1160 {
1161 /* rpop! */
1162 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1163 }
1164 else if (G_FLD (inst->v, 14, 12) == 0x5
1165 && G_FLD (inst->v, 11, 10) == 0x3
1166 && G_FLD (inst->v, 9, 6) == 0x0)
1167 {
1168 /* addi! r0, -offset */
1169 int imm = G_FLD (inst->v, 5, 0);
1170 if (imm >> 5)
1171 imm = -(0x3F - imm + 1);
1172 sp_offset -= imm;
1173 }
1174 else if (G_FLD (inst->v, 14, 12) == 0x5
1175 && G_FLD (inst->v, 11, 10) == 0x3
1176 && G_FLD (inst->v, 9, 6) == 0x2)
1177 {
1178 /* addi! r2, offset */
1179 if (pc - cur_pc >= 2)
1180 {
1181 unsigned int save_v = inst->v;
1182 inst_t *inst2;
1183
1184 cur_pc += inst->len;
c378eb4e
MS
1185 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1186 byte_order);
5f814c3b
DL
1187
1188 if (inst2->len == 2
1189 && G_FLD (inst2->v, 14, 10) == 0x10
1190 && G_FLD (inst2->v, 9, 5) == 0x0
1191 && G_FLD (inst2->v, 4, 0) == 0x2)
1192 {
1193 /* mv! r0, r2 */
1194 int imm = G_FLD (inst->v, 5, 0);
1195 if (imm >> 5)
1196 imm = -(0x3F - imm + 1);
1197 sp_offset -= imm;
1198 }
1199 }
1200 }
1201 }
1202 else if (inst->len == 4)
1203 {
1204 if (G_FLD (inst->v, 29, 25) == 0x3
1205 && G_FLD (inst->v, 2, 0) == 0x4
1206 && G_FLD (inst->v, 24, 20) == 0x3
1207 && G_FLD (inst->v, 19, 15) == 0x0)
1208 {
1209 /* sw r3, [r0, offset]+ */
1210 sp_offset += inst->len;
1211 if (ra_offset_p == 0)
1212 {
1213 ra_offset = sp_offset;
1214 ra_offset_p = 1;
1215 }
1216 }
1217 else if (G_FLD (inst->v, 29, 25) == 0x3
1218 && G_FLD (inst->v, 2, 0) == 0x4
1219 && G_FLD (inst->v, 24, 20) == 0x2
1220 && G_FLD (inst->v, 19, 15) == 0x0)
1221 {
1222 /* sw r2, [r0, offset]+ */
1223 sp_offset += inst->len;
1224 if (fp_offset_p == 0)
1225 {
1226 fp_offset = sp_offset;
1227 fp_offset_p = 1;
1228 }
1229 }
1230 else if (G_FLD (inst->v, 29, 25) == 0x7
1231 && G_FLD (inst->v, 2, 0) == 0x0
1232 && G_FLD (inst->v, 24, 20) == 0x3
1233 && G_FLD (inst->v, 19, 15) == 0x0)
1234 {
1235 /* lw r3, [r0]+, 4 */
1236 sp_offset -= inst->len;
1237 ra_offset_p = 1;
1238 }
1239 else if (G_FLD (inst->v, 29, 25) == 0x7
1240 && G_FLD (inst->v, 2, 0) == 0x0
1241 && G_FLD (inst->v, 24, 20) == 0x2
1242 && G_FLD (inst->v, 19, 15) == 0x0)
1243 {
1244 /* lw r2, [r0]+, 4 */
1245 sp_offset -= inst->len;
1246 fp_offset_p = 1;
1247 }
1248 else if (G_FLD (inst->v, 29, 25) == 0x1
1249 && G_FLD (inst->v, 19, 17) == 0x0
1250 && G_FLD (inst->v, 24, 20) == 0x0
1251 && G_FLD (inst->v, 0, 0) == 0x0)
1252 {
1253 /* addi r0, -offset */
1254 int imm = G_FLD (inst->v, 16, 1);
1255 if (imm >> 15)
1256 imm = -(0xFFFF - imm + 1);
1257 sp_offset -= imm;
1258 }
1259 else if (G_FLD (inst->v, 29, 25) == 0x1
1260 && G_FLD (inst->v, 19, 17) == 0x0
1261 && G_FLD (inst->v, 24, 20) == 0x2
1262 && G_FLD (inst->v, 0, 0) == 0x0)
1263 {
1264 /* addi r2, offset */
1265 if (pc - cur_pc >= 2)
1266 {
1267 unsigned int save_v = inst->v;
1268 inst_t *inst2;
1269
1270 cur_pc += inst->len;
c378eb4e
MS
1271 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1272 byte_order);
5f814c3b
DL
1273
1274 if (inst2->len == 2
1275 && G_FLD (inst2->v, 14, 10) == 0x10
1276 && G_FLD (inst2->v, 9, 5) == 0x0
1277 && G_FLD (inst2->v, 4, 0) == 0x2)
1278 {
1279 /* mv! r0, r2 */
1280 int imm = G_FLD (inst->v, 16, 1);
1281 if (imm >> 15)
1282 imm = -(0xFFFF - imm + 1);
1283 sp_offset -= imm;
1284 }
1285 }
1286 }
1287 }
1288 }
1289
1290 /* Save RA. */
1291 if (ra_offset_p == 1)
1292 {
1293 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1294 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1295 sp + sp_offset - ra_offset;
1296 }
1297 else
1298 {
1299 this_cache->saved_regs[SCORE_PC_REGNUM] =
1300 this_cache->saved_regs[SCORE_RA_REGNUM];
1301 }
1302
1303 /* Save FP. */
1304 if (fp_offset_p == 1)
1305 {
1306 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1307 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1308 sp + sp_offset - fp_offset;
1309 }
1310
1311 /* Save SP and FP. */
1312 this_cache->base = sp + sp_offset;
1313 this_cache->fp = fp;
27fd2f50
Q
1314}
1315
1316static struct score_frame_cache *
94afd7a6 1317score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
27fd2f50
Q
1318{
1319 struct score_frame_cache *cache;
1320
1321 if ((*this_cache) != NULL)
1322 return (*this_cache);
1323
1324 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1325 (*this_cache) = cache;
94afd7a6 1326 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
27fd2f50
Q
1327
1328 /* Analyze the prologue. */
1329 {
94afd7a6 1330 const CORE_ADDR pc = get_frame_pc (this_frame);
27fd2f50
Q
1331 CORE_ADDR start_addr;
1332
1333 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1334 if (start_addr == 0)
1335 return cache;
5f814c3b
DL
1336
1337 if (target_mach == bfd_mach_score3)
1338 score3_analyze_prologue (start_addr, pc, this_frame, *this_cache);
1339 else
1340 score7_analyze_prologue (start_addr, pc, this_frame, *this_cache);
27fd2f50
Q
1341 }
1342
1343 /* Save SP. */
1344 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1345
1346 return (*this_cache);
1347}
1348
1349static void
94afd7a6 1350score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
1351 struct frame_id *this_id)
1352{
94afd7a6 1353 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1354 this_cache);
94afd7a6 1355 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
1356}
1357
94afd7a6
UW
1358static struct value *
1359score_prologue_prev_register (struct frame_info *this_frame,
1360 void **this_cache, int regnum)
27fd2f50 1361{
94afd7a6 1362 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1363 this_cache);
94afd7a6 1364 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
1365}
1366
1367static const struct frame_unwind score_prologue_unwind =
1368{
1369 NORMAL_FRAME,
8fbca658 1370 default_frame_unwind_stop_reason,
27fd2f50 1371 score_prologue_this_id,
94afd7a6
UW
1372 score_prologue_prev_register,
1373 NULL,
5f814c3b
DL
1374 default_frame_sniffer,
1375 NULL
27fd2f50
Q
1376};
1377
27fd2f50 1378static CORE_ADDR
94afd7a6 1379score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1380 void **this_cache)
1381{
1382 struct score_frame_cache *info =
94afd7a6 1383 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1384 return info->fp;
27fd2f50
Q
1385}
1386
1387static const struct frame_base score_prologue_frame_base =
1388{
1389 &score_prologue_unwind,
1390 score_prologue_frame_base_address,
1391 score_prologue_frame_base_address,
1392 score_prologue_frame_base_address,
1393};
1394
1395static const struct frame_base *
94afd7a6 1396score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1397{
1398 return &score_prologue_frame_base;
1399}
1400
5f814c3b
DL
1401/* Core file support (dirty hack)
1402
c378eb4e 1403 The core file MUST be generated by GNU/Linux on S+core. */
5f814c3b
DL
1404
1405static void
1406score7_linux_supply_gregset(const struct regset *regset,
1407 struct regcache *regcache,
1408 int regnum, const void *gregs_buf, size_t len)
1409{
c378eb4e
MS
1410 int regno;
1411 elf_gregset_t *gregs;
5f814c3b 1412
c378eb4e
MS
1413 gdb_assert (regset != NULL);
1414 gdb_assert ((regcache != NULL) && (gregs_buf != NULL));
5f814c3b 1415
c378eb4e 1416 gregs = (elf_gregset_t *) gregs_buf;
5f814c3b 1417
c378eb4e
MS
1418 for (regno = 0; regno < 32; regno++)
1419 if (regnum == -1 || regnum == regno)
1420 regcache_raw_supply (regcache, regno, gregs->regs + regno);
5f814c3b 1421
c378eb4e
MS
1422 {
1423 struct sreg {
1424 int regnum;
1425 void *buf;
1426 } sregs [] = {
1427 { 55, &(gregs->cel) }, /* CEL */
1428 { 54, &(gregs->ceh) }, /* CEH */
1429 { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */
1430 { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */
1431 { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */
1432
1433 /* Exception occured at this address, exactly the PC we want */
1434 { 49, &(gregs->cp0_epc) }, /* PC */
1435
1436 { 38, &(gregs->cp0_ema) }, /* EMA */
1437 { 37, &(gregs->cp0_epc) }, /* EPC */
1438 { 34, &(gregs->cp0_ecr) }, /* ECR */
1439 { 33, &(gregs->cp0_condition) }, /* COND */
1440 { 32, &(gregs->cp0_psr) }, /* PSR */
1441 };
1442
1443 for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++)
1444 if (regnum == -1 || regnum == sregs[regno].regnum)
1445 regcache_raw_supply (regcache,
1446 sregs[regno].regnum, sregs[regno].buf);
1447 }
5f814c3b
DL
1448}
1449
1450/* Return the appropriate register set from the core section identified
c378eb4e 1451 by SECT_NAME and SECT_SIZE. */
5f814c3b
DL
1452
1453static const struct regset *
1454score7_linux_regset_from_core_section(struct gdbarch *gdbarch,
1455 const char *sect_name, size_t sect_size)
1456{
c378eb4e 1457 struct gdbarch_tdep *tdep;
5f814c3b 1458
c378eb4e
MS
1459 gdb_assert (gdbarch != NULL);
1460 gdb_assert (sect_name != NULL);
5f814c3b 1461
c378eb4e 1462 tdep = gdbarch_tdep (gdbarch);
5f814c3b 1463
c378eb4e 1464 if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t))
5f814c3b 1465 {
c378eb4e
MS
1466 if (tdep->gregset == NULL)
1467 tdep->gregset = regset_alloc (gdbarch,
1468 score7_linux_supply_gregset, NULL);
1469 return tdep->gregset;
5f814c3b
DL
1470 }
1471
c378eb4e 1472 return NULL;
5f814c3b
DL
1473}
1474
27fd2f50
Q
1475static struct gdbarch *
1476score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1477{
1478 struct gdbarch *gdbarch;
5f814c3b
DL
1479 struct gdbarch_tdep *tdep;
1480 target_mach = info.bfd_arch_info->mach;
27fd2f50
Q
1481
1482 arches = gdbarch_list_lookup_by_info (arches, &info);
1483 if (arches != NULL)
1484 {
1485 return (arches->gdbarch);
1486 }
5f814c3b
DL
1487 tdep = xcalloc(1, sizeof(struct gdbarch_tdep));
1488 gdbarch = gdbarch_alloc (&info, tdep);
27fd2f50
Q
1489
1490 set_gdbarch_short_bit (gdbarch, 16);
1491 set_gdbarch_int_bit (gdbarch, 32);
1492 set_gdbarch_float_bit (gdbarch, 32);
1493 set_gdbarch_double_bit (gdbarch, 64);
1494 set_gdbarch_long_double_bit (gdbarch, 64);
5f814c3b 1495#if WITH_SIM
27fd2f50 1496 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
5f814c3b 1497#endif
27fd2f50
Q
1498 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1499 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
c378eb4e
MS
1500 set_gdbarch_adjust_breakpoint_address (gdbarch,
1501 score_adjust_breakpoint_address);
27fd2f50
Q
1502 set_gdbarch_register_type (gdbarch, score_register_type);
1503 set_gdbarch_frame_align (gdbarch, score_frame_align);
1504 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
30244cd8 1505 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
5f814c3b 1506 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
27fd2f50 1507 set_gdbarch_print_insn (gdbarch, score_print_insn);
5f814c3b
DL
1508
1509 switch (target_mach)
1510 {
1511 case bfd_mach_score7:
1512 set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
1513 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
c378eb4e
MS
1514 set_gdbarch_in_function_epilogue_p (gdbarch,
1515 score7_in_function_epilogue_p);
5f814c3b
DL
1516 set_gdbarch_register_name (gdbarch, score7_register_name);
1517 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
c378eb4e
MS
1518 /* Core file support. */
1519 set_gdbarch_regset_from_core_section (gdbarch,
1520 score7_linux_regset_from_core_section);
5f814c3b
DL
1521 break;
1522
1523 case bfd_mach_score3:
1524 set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
1525 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
c378eb4e
MS
1526 set_gdbarch_in_function_epilogue_p (gdbarch,
1527 score3_in_function_epilogue_p);
5f814c3b
DL
1528 set_gdbarch_register_name (gdbarch, score3_register_name);
1529 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1530 break;
1531 }
5e29c264
Q
1532
1533 /* Watchpoint hooks. */
1534 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1535
1536 /* Dummy frame hooks. */
27fd2f50 1537 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1538 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1539 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1540 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1541
5e29c264 1542 /* Normal frame hooks. */
94afd7a6 1543 dwarf2_append_unwinders (gdbarch);
27fd2f50 1544 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1545 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1546 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1547
1548 return gdbarch;
1549}
1550
1551extern initialize_file_ftype _initialize_score_tdep;
1552
1553void
1554_initialize_score_tdep (void)
1555{
1556 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1557}
This page took 1.226763 seconds and 4 git commands to generate.