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