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