Add default_breakpoint_from_pc
[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
618f726f 4 Copyright (C) 2006-2016 Free Software Foundation, Inc.
27fd2f50
Q
5
6 Contributed by Qinwei (qinwei@sunnorth.com.cn)
7 Contributed by Ching-Peng Lin (cplin@sunplus.com)
8
9 This file is part of GDB.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
a9762ec7 13 the Free Software Foundation; either version 3 of the License, or
27fd2f50
Q
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
a9762ec7 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27fd2f50
Q
23
24#include "defs.h"
27fd2f50
Q
25#include "inferior.h"
26#include "symtab.h"
27#include "objfiles.h"
28#include "gdbcore.h"
29#include "target.h"
30#include "arch-utils.h"
31#include "regcache.h"
5f814c3b 32#include "regset.h"
27fd2f50
Q
33#include "dis-asm.h"
34#include "frame-unwind.h"
35#include "frame-base.h"
36#include "trad-frame.h"
37#include "dwarf2-frame.h"
38#include "score-tdep.h"
39
5f814c3b
DL
40#define G_FLD(_i,_ms,_ls) \
41 ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
27fd2f50
Q
42
43typedef struct{
c378eb4e
MS
44 unsigned long long v;
45 unsigned long long raw;
46 unsigned int len;
27fd2f50
Q
47}inst_t;
48
49struct score_frame_cache
50{
51 CORE_ADDR base;
5e29c264 52 CORE_ADDR fp;
27fd2f50
Q
53 struct trad_frame_saved_reg *saved_regs;
54};
55
5f814c3b 56static int target_mach = bfd_mach_score7;
5e29c264 57
27fd2f50
Q
58static struct type *
59score_register_type (struct gdbarch *gdbarch, int regnum)
60{
5f814c3b 61 gdb_assert (regnum >= 0
c378eb4e
MS
62 && regnum < ((target_mach == bfd_mach_score7)
63 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
df4df182 64 return builtin_type (gdbarch)->builtin_uint32;
27fd2f50
Q
65}
66
5f814c3b
DL
67static CORE_ADDR
68score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
69{
70 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
71}
72
27fd2f50 73static CORE_ADDR
30244cd8 74score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
27fd2f50 75{
30244cd8 76 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
27fd2f50
Q
77}
78
5f814c3b
DL
79static const char *
80score7_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50 81{
5f814c3b
DL
82 const char *score_register_names[] = {
83 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
84 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
85 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
86 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
87
88 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
89 "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR",
90 "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN",
91 "PREV", "DREG", "PC", "DSAVE", "COUNTER",
92 "LDCR", "STCR", "CEH", "CEL",
93 };
94
95 gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
96 return score_register_names[regnum];
27fd2f50
Q
97}
98
99static const char *
5f814c3b 100score3_register_name (struct gdbarch *gdbarch, int regnum)
27fd2f50
Q
101{
102 const char *score_register_names[] = {
103 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
104 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
105 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
106 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
107
5f814c3b
DL
108 "PSR", "COND", "ECR", "EXCPVEC", "CCR",
109 "EPC", "EMA", "PREV", "DREG", "DSAVE",
110 "COUNTER", "LDCR", "STCR", "CEH", "CEL",
111 "", "", "PC",
27fd2f50
Q
112 };
113
5f814c3b 114 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
27fd2f50
Q
115 return score_register_names[regnum];
116}
117
5f814c3b 118#if WITH_SIM
27fd2f50 119static int
e7faf938 120score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
27fd2f50 121{
5f814c3b 122 gdb_assert (regnum >= 0
c378eb4e
MS
123 && regnum < ((target_mach == bfd_mach_score7)
124 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
125 return regnum;
126}
5f814c3b 127#endif
27fd2f50
Q
128
129static int
130score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
131{
f52cb1b8 132 if (info->endian == BFD_ENDIAN_BIG)
27fd2f50
Q
133 return print_insn_big_score (memaddr, info);
134 else
135 return print_insn_little_score (memaddr, info);
136}
137
5f814c3b 138static inst_t *
e362b510 139score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock)
5f814c3b
DL
140{
141 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
142 static inst_t inst = { 0, 0, 0 };
e362b510 143 gdb_byte buf[SCORE_INSTLEN] = { 0 };
5f814c3b
DL
144 int big;
145 int ret;
146
147 if (target_has_execution && memblock != NULL)
148 {
149 /* Fetch instruction from local MEMBLOCK. */
150 memcpy (buf, memblock, SCORE_INSTLEN);
151 }
152 else
153 {
154 /* Fetch instruction from target. */
155 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
156 if (ret)
157 {
a73c6dcd 158 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
159 __FILE__, __LINE__);
160 return 0;
161 }
162 }
163
164 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
165 inst.len = (inst.raw & 0x80008000) ? 4 : 2;
166 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
167 big = (byte_order == BFD_ENDIAN_BIG);
168 if (inst.len == 2)
169 {
170 if (big ^ ((addr & 0x2) == 2))
171 inst.v = G_FLD (inst.v, 29, 15);
172 else
173 inst.v = G_FLD (inst.v, 14, 0);
174 }
175 return &inst;
176}
177
178static inst_t *
179score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
180 enum bfd_endian byte_order)
181{
182 static inst_t inst = { 0, 0, 0 };
183
184 struct breakplace
185 {
186 int break_offset;
187 int inst_len;
188 };
189 /* raw table 1 (column 2, 3, 4)
190 * 0 1 0 * # 2
191 * 0 1 1 0 # 3
192 0 1 1 0 * # 6
193 table 2 (column 1, 2, 3)
194 * 0 0 * * # 0, 4
195 0 1 0 * * # 2
196 1 1 0 * * # 6
197 */
198
199 static const struct breakplace bk_table[16] =
200 {
201 /* table 1 */
202 {0, 0},
203 {0, 0},
204 {0, 4},
205 {0, 6},
206 {0, 0},
207 {0, 0},
208 {-2, 6},
209 {0, 0},
210 /* table 2 */
211 {0, 2},
212 {0, 0},
213 {-2, 4},
214 {0, 0},
215 {0, 2},
216 {0, 0},
217 {-4, 6},
218 {0, 0}
219 };
220
221#define EXTRACT_LEN 2
222 CORE_ADDR adjust_pc = *pcptr & ~0x1;
5f814c3b
DL
223 gdb_byte buf[5][EXTRACT_LEN] =
224 {
225 {'\0', '\0'},
226 {'\0', '\0'},
227 {'\0', '\0'},
228 {'\0', '\0'},
229 {'\0', '\0'}
230 };
231 int ret;
232 unsigned int raw;
233 unsigned int cbits = 0;
234 int bk_index;
235 int i, count;
236
237 inst.v = 0;
238 inst.raw = 0;
239 inst.len = 0;
240
241 adjust_pc -= 4;
242 for (i = 0; i < 5; i++)
243 {
244 ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
245 if (ret != 0)
246 {
247 buf[i][0] = '\0';
248 buf[i][1] = '\0';
249 if (i == 2)
a73c6dcd 250 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
251 __FILE__, __LINE__);
252 }
253
254 raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
255 cbits = (cbits << 1) | (raw >> 15);
256 }
257 adjust_pc += 4;
258
259 if (cbits & 0x4)
260 {
261 /* table 1 */
262 cbits = (cbits >> 1) & 0x7;
263 bk_index = cbits;
264 }
265 else
266 {
267 /* table 2 */
268 cbits = (cbits >> 2) & 0x7;
269 bk_index = cbits + 8;
270 }
271
272 gdb_assert (!((bk_table[bk_index].break_offset == 0)
273 && (bk_table[bk_index].inst_len == 0)));
274
275 inst.len = bk_table[bk_index].inst_len;
276
277 i = (bk_table[bk_index].break_offset + 4) / 2;
278 count = inst.len / 2;
279 for (; count > 0; i++, count--)
280 {
281 inst.raw = (inst.raw << 16)
282 | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
283 }
284
285 switch (inst.len)
286 {
287 case 2:
288 inst.v = inst.raw & 0x7FFF;
289 break;
290 case 4:
291 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
292 break;
293 case 6:
294 inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
295 | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
296 break;
297 }
298
299 if (pcptr)
300 *pcptr = adjust_pc + bk_table[bk_index].break_offset;
301 if (lenptr)
302 *lenptr = bk_table[bk_index].inst_len;
303
304#undef EXTRACT_LEN
305
306 return &inst;
307}
308
cd6c3b4f
YQ
309/* Implement the breakpoint_kind_from_pc gdbarch method. */
310
d19280ad
YQ
311static int
312score7_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
27fd2f50 313{
27fd2f50
Q
314 int ret;
315 unsigned int raw;
d19280ad
YQ
316 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
317 gdb_byte buf[SCORE_INSTLEN] = { 0 };
27fd2f50
Q
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!"),
d19280ad 322 __FILE__, __LINE__);
27fd2f50 323 }
e17a4113 324 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50 325
d19280ad 326 if (!(raw & 0x80008000))
27fd2f50 327 {
d19280ad
YQ
328 /* 16bits instruction. */
329 *pcptr &= ~0x1;
330 return 2;
331 }
332 else
333 {
334 /* 32bits instruction. */
335 *pcptr &= ~0x3;
336 return 4;
337 }
338}
339
cd6c3b4f
YQ
340/* Implement the sw_breakpoint_from_kind gdbarch method. */
341
d19280ad
YQ
342static const gdb_byte *
343score7_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
344{
345 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
346
347 *size = kind;
348
349 if (kind == 4)
350 {
351 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
352 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
353
354 if (byte_order == BFD_ENDIAN_BIG)
355 return big_breakpoint32;
27fd2f50 356 else
d19280ad 357 return little_breakpoint32;
27fd2f50
Q
358 }
359 else
360 {
d19280ad
YQ
361 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
362 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
363
364 if (byte_order == BFD_ENDIAN_BIG)
365 return big_breakpoint16;
27fd2f50 366 else
d19280ad 367 return little_breakpoint16;
27fd2f50
Q
368 }
369}
370
cd6c3b4f
YQ
371/* Implement the breakpoint_kind_from_pc gdbarch method. */
372
d19280ad
YQ
373static int
374score3_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
5f814c3b
DL
375{
376 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5f814c3b 377 int len;
d19280ad
YQ
378
379 score3_adjust_pc_and_fetch_inst (pcptr, &len, byte_order);
380
381 return len;
382}
383
cd6c3b4f
YQ
384/* Implement the sw_breakpoint_from_kind gdbarch method. */
385
d19280ad
YQ
386static const gdb_byte *
387score3_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
388{
389 int index = 0;
390 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5f814c3b
DL
391 static gdb_byte score_break_insns[6][6] = {
392 /* The following three instructions are big endian. */
393 { 0x00, 0x20 },
394 { 0x80, 0x00, 0x00, 0x06 },
395 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
396 /* The following three instructions are little endian. */
397 { 0x20, 0x00 },
398 { 0x00, 0x80, 0x06, 0x00 },
399 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
400
d19280ad 401 *size = kind;
5f814c3b 402
d19280ad
YQ
403 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (kind / 2 - 1);
404 return score_break_insns[index];
5f814c3b
DL
405}
406
407static CORE_ADDR
408score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
409{
410 CORE_ADDR adjust_pc = bpaddr;
411
412 if (target_mach == bfd_mach_score3)
413 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
414 gdbarch_byte_order (gdbarch));
415 else
416 adjust_pc = align_down (adjust_pc, 2);
417
418 return adjust_pc;
419}
420
27fd2f50
Q
421static CORE_ADDR
422score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
423{
424 return align_down (addr, 16);
425}
426
427static void
428score_xfer_register (struct regcache *regcache, int regnum, int length,
429 enum bfd_endian endian, gdb_byte *readbuf,
430 const gdb_byte *writebuf, int buf_offset)
431{
432 int reg_offset = 0;
5f814c3b 433 gdb_assert (regnum >= 0
c378eb4e
MS
434 && regnum < ((target_mach == bfd_mach_score7)
435 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
436
437 switch (endian)
438 {
439 case BFD_ENDIAN_BIG:
440 reg_offset = SCORE_REGSIZE - length;
441 break;
442 case BFD_ENDIAN_LITTLE:
443 reg_offset = 0;
444 break;
445 case BFD_ENDIAN_UNKNOWN:
446 reg_offset = 0;
447 break;
448 default:
a73c6dcd 449 error (_("Error: score_xfer_register in file:%s, line:%d!"),
5e29c264 450 __FILE__, __LINE__);
27fd2f50
Q
451 }
452
453 if (readbuf != NULL)
454 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
455 readbuf + buf_offset);
456 if (writebuf != NULL)
457 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
458 writebuf + buf_offset);
459}
460
461static enum return_value_convention
6a3a010b 462score_return_value (struct gdbarch *gdbarch, struct value *function,
5f814c3b 463 struct type *type, struct regcache *regcache,
27fd2f50
Q
464 gdb_byte * readbuf, const gdb_byte * writebuf)
465{
466 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
467 || TYPE_CODE (type) == TYPE_CODE_UNION
468 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
469 return RETURN_VALUE_STRUCT_CONVENTION;
470 else
471 {
472 int offset;
473 int regnum;
474 for (offset = 0, regnum = SCORE_A0_REGNUM;
475 offset < TYPE_LENGTH (type);
476 offset += SCORE_REGSIZE, regnum++)
477 {
478 int xfer = SCORE_REGSIZE;
c378eb4e 479
27fd2f50
Q
480 if (offset + xfer > TYPE_LENGTH (type))
481 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 482 score_xfer_register (regcache, regnum, xfer,
5f814c3b 483 gdbarch_byte_order(gdbarch),
27fd2f50
Q
484 readbuf, writebuf, offset);
485 }
486 return RETURN_VALUE_REGISTER_CONVENTION;
487 }
488}
489
490static struct frame_id
94afd7a6 491score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27fd2f50 492{
c378eb4e
MS
493 return frame_id_build (get_frame_register_unsigned (this_frame,
494 SCORE_SP_REGNUM),
495 get_frame_pc (this_frame));
27fd2f50
Q
496}
497
498static int
499score_type_needs_double_align (struct type *type)
500{
501 enum type_code typecode = TYPE_CODE (type);
502
5e29c264
Q
503 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
504 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
27fd2f50
Q
505 return 1;
506 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
507 {
508 int i, n;
509
510 n = TYPE_NFIELDS (type);
511 for (i = 0; i < n; i++)
512 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
513 return 1;
514 return 0;
515 }
516 return 0;
517}
518
519static CORE_ADDR
520score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
521 struct regcache *regcache, CORE_ADDR bp_addr,
522 int nargs, struct value **args, CORE_ADDR sp,
523 int struct_return, CORE_ADDR struct_addr)
524{
e17a4113 525 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
526 int argnum;
527 int argreg;
528 int arglen = 0;
529 CORE_ADDR stack_offset = 0;
530 CORE_ADDR addr = 0;
531
532 /* Step 1, Save RA. */
533 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
534
535 /* Step 2, Make space on the stack for the args. */
536 struct_addr = align_down (struct_addr, 16);
537 sp = align_down (sp, 16);
538 for (argnum = 0; argnum < nargs; argnum++)
539 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
540 SCORE_REGSIZE);
541 sp -= align_up (arglen, 16);
542
543 argreg = SCORE_BEGIN_ARG_REGNUM;
544
5e29c264
Q
545 /* Step 3, Check if struct return then save the struct address to
546 r4 and increase the stack_offset by 4. */
27fd2f50
Q
547 if (struct_return)
548 {
549 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
550 stack_offset += SCORE_REGSIZE;
551 }
552
553 /* Step 4, Load arguments:
5e29c264
Q
554 If arg length is too long (> 4 bytes), then split the arg and
555 save every parts. */
27fd2f50
Q
556 for (argnum = 0; argnum < nargs; argnum++)
557 {
558 struct value *arg = args[argnum];
559 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
560 enum type_code typecode = TYPE_CODE (arg_type);
561 const gdb_byte *val = value_contents (arg);
562 int downward_offset = 0;
1cfd2c3e 563 int arg_last_part_p = 0;
27fd2f50 564
1cfd2c3e 565 arglen = TYPE_LENGTH (arg_type);
27fd2f50
Q
566
567 /* If a arg should be aligned to 8 bytes (long long or double),
568 the value should be put to even register numbers. */
569 if (score_type_needs_double_align (arg_type))
570 {
571 if (argreg & 1)
572 argreg++;
573 }
574
575 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
576 the default "downward"/"upward" method:
577
578 Example:
579
580 struct struc
581 {
582 char a; char b; char c;
583 } s = {'a', 'b', 'c'};
584
585 Big endian: s = {X, 'a', 'b', 'c'}
586 Little endian: s = {'a', 'b', 'c', X}
587
588 Where X is a hole. */
589
5f814c3b 590 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
591 && (typecode == TYPE_CODE_STRUCT
592 || typecode == TYPE_CODE_UNION)
593 && argreg > SCORE_LAST_ARG_REGNUM
594 && arglen < SCORE_REGSIZE)
595 downward_offset += (SCORE_REGSIZE - arglen);
596
597 while (arglen > 0)
598 {
599 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
e17a4113 600 ULONGEST regval = extract_unsigned_integer (val, partial_len,
5f814c3b 601 byte_order);
27fd2f50
Q
602
603 /* The last part of a arg should shift left when
4c6b5505 604 gdbarch_byte_order is BFD_ENDIAN_BIG. */
5f814c3b 605 if (byte_order == BFD_ENDIAN_BIG
27fd2f50
Q
606 && arg_last_part_p == 1
607 && (typecode == TYPE_CODE_STRUCT
608 || typecode == TYPE_CODE_UNION))
609 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
610
611 /* Always increase the stack_offset and save args to stack. */
612 addr = sp + stack_offset + downward_offset;
613 write_memory (addr, val, partial_len);
614
615 if (argreg <= SCORE_LAST_ARG_REGNUM)
616 {
617 regcache_cooked_write_unsigned (regcache, argreg++, regval);
618 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
619 arg_last_part_p = 1;
620 }
621
622 val += partial_len;
623 arglen -= partial_len;
624 stack_offset += align_up (partial_len, SCORE_REGSIZE);
625 }
626 }
627
628 /* Step 5, Save SP. */
629 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
630
631 return sp;
632}
633
27fd2f50 634static CORE_ADDR
5f814c3b 635score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
636{
637 CORE_ADDR cpc = pc;
638 int iscan = 32, stack_sub = 0;
639 while (iscan-- > 0)
640 {
5f814c3b 641 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
642 if (!inst)
643 break;
5f814c3b 644 if ((inst->len == 4) && !stack_sub
27fd2f50
Q
645 && (G_FLD (inst->v, 29, 25) == 0x1
646 && G_FLD (inst->v, 24, 20) == 0x0))
647 {
648 /* addi r0, offset */
5f814c3b
DL
649 stack_sub = cpc + SCORE_INSTLEN;
650 pc = cpc + SCORE_INSTLEN;
27fd2f50 651 }
5f814c3b
DL
652 else if ((inst->len == 4)
653 && (G_FLD (inst->v, 29, 25) == 0x0)
654 && (G_FLD (inst->v, 24, 20) == 0x2)
655 && (G_FLD (inst->v, 19, 15) == 0x0)
656 && (G_FLD (inst->v, 14, 10) == 0xF)
657 && (G_FLD (inst->v, 9, 0) == 0x56))
27fd2f50
Q
658 {
659 /* mv r2, r0 */
660 pc = cpc + SCORE_INSTLEN;
661 break;
662 }
5f814c3b
DL
663 else if ((inst->len == 2)
664 && (G_FLD (inst->v, 14, 12) == 0x0)
665 && (G_FLD (inst->v, 11, 8) == 0x2)
666 && (G_FLD (inst->v, 7, 4) == 0x0)
667 && (G_FLD (inst->v, 3, 0) == 0x3))
27fd2f50
Q
668 {
669 /* mv! r2, r0 */
670 pc = cpc + SCORE16_INSTLEN;
671 break;
672 }
5f814c3b 673 else if ((inst->len == 2)
27fd2f50
Q
674 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
675 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
676 || (G_FLD (inst->v, 14, 12) == 0x0
677 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
678 break;
5f814c3b 679 else if ((inst->len == 4)
27fd2f50
Q
680 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
681 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
682 || (G_FLD (inst->v, 29, 25) == 0x0
683 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
684 break;
685
5f814c3b 686 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
27fd2f50
Q
687 }
688 return pc;
689}
690
5f814c3b
DL
691static CORE_ADDR
692score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50 693{
5f814c3b
DL
694 CORE_ADDR cpc = pc;
695 int iscan = 32, stack_sub = 0;
696 while (iscan-- > 0)
697 {
698 inst_t *inst
c378eb4e
MS
699 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
700 gdbarch_byte_order (gdbarch));
27fd2f50 701
5f814c3b
DL
702 if (!inst)
703 break;
704 if (inst->len == 4 && !stack_sub
705 && (G_FLD (inst->v, 29, 25) == 0x1)
706 && (G_FLD (inst->v, 19, 17) == 0x0)
707 && (G_FLD (inst->v, 24, 20) == 0x0))
708 {
709 /* addi r0, offset */
710 stack_sub = cpc + inst->len;
711 pc = cpc + inst->len;
712 }
713 else if (inst->len == 4
714 && (G_FLD (inst->v, 29, 25) == 0x0)
715 && (G_FLD (inst->v, 24, 20) == 0x2)
716 && (G_FLD (inst->v, 19, 15) == 0x0)
717 && (G_FLD (inst->v, 14, 10) == 0xF)
718 && (G_FLD (inst->v, 9, 0) == 0x56))
719 {
720 /* mv r2, r0 */
721 pc = cpc + inst->len;
722 break;
723 }
724 else if ((inst->len == 2)
725 && (G_FLD (inst->v, 14, 10) == 0x10)
726 && (G_FLD (inst->v, 9, 5) == 0x2)
727 && (G_FLD (inst->v, 4, 0) == 0x0))
728 {
729 /* mv! r2, r0 */
730 pc = cpc + inst->len;
731 break;
732 }
733 else if (inst->len == 2
734 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
735 || (G_FLD (inst->v, 14, 12) == 0x0
736 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
737 break;
738 else if (inst->len == 4
739 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
740 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
741 break;
742
743 cpc += inst->len;
744 }
745 return pc;
746}
747
c9cf6e20
MG
748/* Implement the stack_frame_destroyed_p gdbarch method. */
749
5f814c3b 750static int
c9cf6e20 751score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
752{
753 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
754
755 if (inst->v == 0x23)
756 return 1; /* mv! r0, r2 */
757 else if (G_FLD (inst->v, 14, 12) == 0x2
758 && G_FLD (inst->v, 3, 0) == 0xa)
759 return 1; /* pop! */
27fd2f50
Q
760 else if (G_FLD (inst->v, 14, 12) == 0x0
761 && G_FLD (inst->v, 7, 0) == 0x34)
762 return 1; /* br! r3 */
763 else if (G_FLD (inst->v, 29, 15) == 0x2
764 && G_FLD (inst->v, 6, 1) == 0x2b)
765 return 1; /* mv r0, r2 */
766 else if (G_FLD (inst->v, 29, 25) == 0x0
767 && G_FLD (inst->v, 6, 1) == 0x4
768 && G_FLD (inst->v, 19, 15) == 0x3)
769 return 1; /* br r3 */
770 else
771 return 0;
772}
773
c9cf6e20
MG
774/* Implement the stack_frame_destroyed_p gdbarch method. */
775
5f814c3b 776static int
c9cf6e20 777score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
778{
779 CORE_ADDR pc = cur_pc;
780 inst_t *inst
c378eb4e
MS
781 = score3_adjust_pc_and_fetch_inst (&pc, NULL,
782 gdbarch_byte_order (gdbarch));
5f814c3b
DL
783
784 if (inst->len == 2
785 && (G_FLD (inst->v, 14, 10) == 0x10)
786 && (G_FLD (inst->v, 9, 5) == 0x0)
787 && (G_FLD (inst->v, 4, 0) == 0x2))
788 return 1; /* mv! r0, r2 */
789 else if (inst->len == 4
790 && (G_FLD (inst->v, 29, 25) == 0x0)
791 && (G_FLD (inst->v, 24, 20) == 0x2)
792 && (G_FLD (inst->v, 19, 15) == 0x0)
793 && (G_FLD (inst->v, 14, 10) == 0xF)
794 && (G_FLD (inst->v, 9, 0) == 0x56))
795 return 1; /* mv r0, r2 */
796 else if (inst->len == 2
797 && (G_FLD (inst->v, 14, 12) == 0x0)
798 && (G_FLD (inst->v, 11, 5) == 0x2))
799 return 1; /* pop! */
800 else if (inst->len == 2
801 && (G_FLD (inst->v, 14, 12) == 0x0)
802 && (G_FLD (inst->v, 11, 7) == 0x0)
803 && (G_FLD (inst->v, 6, 5) == 0x2))
804 return 1; /* rpop! */
805 else if (inst->len == 2
806 && (G_FLD (inst->v, 14, 12) == 0x0)
807 && (G_FLD (inst->v, 11, 5) == 0x4)
808 && (G_FLD (inst->v, 4, 0) == 0x3))
809 return 1; /* br! r3 */
810 else if (inst->len == 4
811 && (G_FLD (inst->v, 29, 25) == 0x0)
812 && (G_FLD (inst->v, 24, 20) == 0x0)
813 && (G_FLD (inst->v, 19, 15) == 0x3)
814 && (G_FLD (inst->v, 14, 10) == 0xF)
815 && (G_FLD (inst->v, 9, 0) == 0x8))
816 return 1; /* br r3 */
817 else
818 return 0;
819}
820
e362b510 821static gdb_byte *
5f814c3b
DL
822score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
823{
824 int ret;
e362b510 825 gdb_byte *memblock = NULL;
5f814c3b 826
d66ff635 827 if (size == 0)
5f814c3b
DL
828 return NULL;
829
224c3ddb 830 memblock = (gdb_byte *) xmalloc (size);
5f814c3b
DL
831 memset (memblock, 0, size);
832 ret = target_read_memory (addr & ~0x3, memblock, size);
833 if (ret)
834 {
a73c6dcd 835 error (_("Error: target_read_memory in file:%s, line:%d!"),
5f814c3b
DL
836 __FILE__, __LINE__);
837 return NULL;
838 }
839 return memblock;
840}
841
27fd2f50 842static void
948f8e3d 843score7_free_memblock (gdb_byte *memblock)
5f814c3b
DL
844{
845 xfree (memblock);
846}
847
848static void
e362b510 849score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
5f814c3b
DL
850 CORE_ADDR cur_pc)
851{
852 if (prev_pc == -1)
853 {
854 /* First time call this function, do nothing. */
855 }
856 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
857 {
858 /* First 16-bit instruction, then 32-bit instruction. */
859 *memblock += SCORE_INSTLEN;
860 }
861 else if (cur_pc - prev_pc == 4)
862 {
863 /* Is 32-bit instruction, increase MEMBLOCK by 4. */
864 *memblock += SCORE_INSTLEN;
865 }
866}
867
868static void
869score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
94afd7a6 870 struct frame_info *this_frame,
27fd2f50
Q
871 struct score_frame_cache *this_cache)
872{
94afd7a6 873 struct gdbarch *gdbarch = get_frame_arch (this_frame);
27fd2f50 874 CORE_ADDR sp;
5e29c264 875 CORE_ADDR fp;
27fd2f50
Q
876 CORE_ADDR cur_pc = startaddr;
877
878 int sp_offset = 0;
879 int ra_offset = 0;
880 int fp_offset = 0;
881 int ra_offset_p = 0;
882 int fp_offset_p = 0;
883 int inst_len = 0;
884
e362b510
PA
885 gdb_byte *memblock = NULL;
886 gdb_byte *memblock_ptr = NULL;
5e29c264
Q
887 CORE_ADDR prev_pc = -1;
888
889 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */
890 memblock_ptr = memblock =
5f814c3b 891 score7_malloc_and_get_memblock (startaddr, pc - startaddr);
5e29c264 892
94afd7a6
UW
893 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
894 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
27fd2f50 895
5e29c264 896 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
27fd2f50 897 {
5e29c264
Q
898 inst_t *inst = NULL;
899 if (memblock != NULL)
900 {
901 /* Reading memory block from target succefully and got all
902 the instructions(from STARTADDR to PC) needed. */
5f814c3b
DL
903 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
904 inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
5e29c264
Q
905 }
906 else
907 {
908 /* Otherwise, we fetch 4 bytes from target, and GDB also
909 work correctly. */
5f814c3b 910 inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
5e29c264
Q
911 }
912
c378eb4e 913 /* FIXME: make a full-power prologue analyzer. */
5f814c3b 914 if (inst->len == 2)
27fd2f50
Q
915 {
916 inst_len = SCORE16_INSTLEN;
917
918 if (G_FLD (inst->v, 14, 12) == 0x2
919 && G_FLD (inst->v, 3, 0) == 0xe)
920 {
921 /* push! */
922 sp_offset += 4;
923
924 if (G_FLD (inst->v, 11, 7) == 0x6
925 && ra_offset_p == 0)
926 {
927 /* push! r3, [r0] */
928 ra_offset = sp_offset;
929 ra_offset_p = 1;
930 }
931 else if (G_FLD (inst->v, 11, 7) == 0x4
932 && fp_offset_p == 0)
933 {
934 /* push! r2, [r0] */
935 fp_offset = sp_offset;
936 fp_offset_p = 1;
937 }
938 }
939 else if (G_FLD (inst->v, 14, 12) == 0x2
940 && G_FLD (inst->v, 3, 0) == 0xa)
941 {
942 /* pop! */
943 sp_offset -= 4;
944 }
945 else if (G_FLD (inst->v, 14, 7) == 0xc1
946 && G_FLD (inst->v, 2, 0) == 0x0)
947 {
948 /* subei! r0, n */
949 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
950 }
951 else if (G_FLD (inst->v, 14, 7) == 0xc0
952 && G_FLD (inst->v, 2, 0) == 0x0)
953 {
954 /* addei! r0, n */
955 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
956 }
957 }
958 else
959 {
960 inst_len = SCORE_INSTLEN;
961
5f814c3b
DL
962 if (G_FLD(inst->v, 29, 25) == 0x3
963 && G_FLD(inst->v, 2, 0) == 0x4
964 && G_FLD(inst->v, 19, 15) == 0)
27fd2f50 965 {
5f814c3b
DL
966 /* sw rD, [r0, offset]+ */
967 sp_offset += SCORE_INSTLEN;
968
969 if (G_FLD(inst->v, 24, 20) == 0x3)
970 {
971 /* rD = r3 */
972 if (ra_offset_p == 0)
973 {
974 ra_offset = sp_offset;
975 ra_offset_p = 1;
976 }
977 }
978 else if (G_FLD(inst->v, 24, 20) == 0x2)
979 {
980 /* rD = r2 */
981 if (fp_offset_p == 0)
982 {
983 fp_offset = sp_offset;
984 fp_offset_p = 1;
985 }
986 }
27fd2f50 987 }
5f814c3b
DL
988 else if (G_FLD(inst->v, 29, 25) == 0x14
989 && G_FLD(inst->v, 19,15) == 0)
27fd2f50 990 {
5f814c3b
DL
991 /* sw rD, [r0, offset] */
992 if (G_FLD(inst->v, 24, 20) == 0x3)
993 {
994 /* rD = r3 */
995 ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
996 ra_offset_p = 1;
997 }
998 else if (G_FLD(inst->v, 24, 20) == 0x2)
999 {
1000 /* rD = r2 */
1001 fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
1002 fp_offset_p = 1;
1003 }
27fd2f50
Q
1004 }
1005 else if (G_FLD (inst->v, 29, 15) == 0x1c60
1006 && G_FLD (inst->v, 2, 0) == 0x0)
1007 {
1008 /* lw r3, [r0]+, 4 */
1009 sp_offset -= SCORE_INSTLEN;
1010 ra_offset_p = 1;
1011 }
1012 else if (G_FLD (inst->v, 29, 15) == 0x1c40
1013 && G_FLD (inst->v, 2, 0) == 0x0)
1014 {
1015 /* lw r2, [r0]+, 4 */
1016 sp_offset -= SCORE_INSTLEN;
1017 fp_offset_p = 1;
1018 }
1019
1020 else if (G_FLD (inst->v, 29, 17) == 0x100
1021 && G_FLD (inst->v, 0, 0) == 0x0)
1022 {
1023 /* addi r0, -offset */
1024 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1025 }
1026 else if (G_FLD (inst->v, 29, 17) == 0x110
1027 && G_FLD (inst->v, 0, 0) == 0x0)
1028 {
1029 /* addi r2, offset */
1030 if (pc - cur_pc > 4)
1031 {
1032 unsigned int save_v = inst->v;
1033 inst_t *inst2 =
5f814c3b 1034 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
27fd2f50 1035 if (inst2->v == 0x23)
5e29c264
Q
1036 {
1037 /* mv! r0, r2 */
1038 sp_offset -= G_FLD (save_v, 16, 1);
1039 }
27fd2f50
Q
1040 }
1041 }
1042 }
1043 }
1044
1045 /* Save RA. */
1046 if (ra_offset_p == 1)
1047 {
1048 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1049 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1050 sp + sp_offset - ra_offset;
1051 }
1052 else
1053 {
1054 this_cache->saved_regs[SCORE_PC_REGNUM] =
1055 this_cache->saved_regs[SCORE_RA_REGNUM];
1056 }
1057
1058 /* Save FP. */
1059 if (fp_offset_p == 1)
1060 {
1061 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1062 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1063 sp + sp_offset - fp_offset;
1064 }
1065
5e29c264
Q
1066 /* Save SP and FP. */
1067 this_cache->base = sp + sp_offset;
1068 this_cache->fp = fp;
1069
1070 /* Don't forget to free MEMBLOCK if we allocated it. */
1071 if (memblock_ptr != NULL)
5f814c3b
DL
1072 score7_free_memblock (memblock_ptr);
1073}
1074
1075static void
1076score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1077 struct frame_info *this_frame,
1078 struct score_frame_cache *this_cache)
1079{
1080 CORE_ADDR sp;
1081 CORE_ADDR fp;
1082 CORE_ADDR cur_pc = startaddr;
c378eb4e
MS
1083 enum bfd_endian byte_order
1084 = gdbarch_byte_order (get_frame_arch (this_frame));
5f814c3b
DL
1085
1086 int sp_offset = 0;
1087 int ra_offset = 0;
1088 int fp_offset = 0;
1089 int ra_offset_p = 0;
1090 int fp_offset_p = 0;
1091 int inst_len = 0;
1092
5f814c3b
DL
1093 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1094 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1095
870f88f7 1096 for (; cur_pc < pc; cur_pc += inst_len)
5f814c3b
DL
1097 {
1098 inst_t *inst = NULL;
1099
1100 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1101
c378eb4e 1102 /* FIXME: make a full-power prologue analyzer. */
5f814c3b
DL
1103 if (inst->len == 2)
1104 {
1105 if (G_FLD (inst->v, 14, 12) == 0x0
1106 && G_FLD (inst->v, 11, 7) == 0x0
1107 && G_FLD (inst->v, 6, 5) == 0x3)
1108 {
1109 /* push! */
1110 sp_offset += 4;
1111
1112 if (G_FLD (inst->v, 4, 0) == 0x3
1113 && ra_offset_p == 0)
1114 {
1115 /* push! r3, [r0] */
1116 ra_offset = sp_offset;
1117 ra_offset_p = 1;
1118 }
1119 else if (G_FLD (inst->v, 4, 0) == 0x2
1120 && fp_offset_p == 0)
1121 {
1122 /* push! r2, [r0] */
1123 fp_offset = sp_offset;
1124 fp_offset_p = 1;
1125 }
1126 }
1127 else if (G_FLD (inst->v, 14, 12) == 0x6
1128 && G_FLD (inst->v, 11, 10) == 0x3)
1129 {
1130 /* rpush! */
1131 int start_r = G_FLD (inst->v, 9, 5);
1132 int cnt = G_FLD (inst->v, 4, 0);
1133
1134 if ((ra_offset_p == 0)
1135 && (start_r <= SCORE_RA_REGNUM)
1136 && (SCORE_RA_REGNUM < start_r + cnt))
1137 {
1138 /* rpush! contains r3 */
1139 ra_offset_p = 1;
1140 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1141 }
1142
1143 if ((fp_offset_p == 0)
1144 && (start_r <= SCORE_FP_REGNUM)
1145 && (SCORE_FP_REGNUM < start_r + cnt))
1146 {
1147 /* rpush! contains r2 */
1148 fp_offset_p = 1;
1149 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1150 }
1151
1152 sp_offset += 4 * cnt;
1153 }
1154 else if (G_FLD (inst->v, 14, 12) == 0x0
1155 && G_FLD (inst->v, 11, 7) == 0x0
1156 && G_FLD (inst->v, 6, 5) == 0x2)
1157 {
1158 /* pop! */
1159 sp_offset -= 4;
1160 }
1161 else if (G_FLD (inst->v, 14, 12) == 0x6
1162 && G_FLD (inst->v, 11, 10) == 0x2)
1163 {
1164 /* rpop! */
1165 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1166 }
1167 else if (G_FLD (inst->v, 14, 12) == 0x5
1168 && G_FLD (inst->v, 11, 10) == 0x3
1169 && G_FLD (inst->v, 9, 6) == 0x0)
1170 {
1171 /* addi! r0, -offset */
1172 int imm = G_FLD (inst->v, 5, 0);
1173 if (imm >> 5)
1174 imm = -(0x3F - imm + 1);
1175 sp_offset -= imm;
1176 }
1177 else if (G_FLD (inst->v, 14, 12) == 0x5
1178 && G_FLD (inst->v, 11, 10) == 0x3
1179 && G_FLD (inst->v, 9, 6) == 0x2)
1180 {
1181 /* addi! r2, offset */
1182 if (pc - cur_pc >= 2)
1183 {
5f814c3b
DL
1184 inst_t *inst2;
1185
1186 cur_pc += inst->len;
c378eb4e
MS
1187 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1188 byte_order);
5f814c3b
DL
1189
1190 if (inst2->len == 2
1191 && G_FLD (inst2->v, 14, 10) == 0x10
1192 && G_FLD (inst2->v, 9, 5) == 0x0
1193 && G_FLD (inst2->v, 4, 0) == 0x2)
1194 {
1195 /* mv! r0, r2 */
1196 int imm = G_FLD (inst->v, 5, 0);
1197 if (imm >> 5)
1198 imm = -(0x3F - imm + 1);
1199 sp_offset -= imm;
1200 }
1201 }
1202 }
1203 }
1204 else if (inst->len == 4)
1205 {
1206 if (G_FLD (inst->v, 29, 25) == 0x3
1207 && G_FLD (inst->v, 2, 0) == 0x4
1208 && G_FLD (inst->v, 24, 20) == 0x3
1209 && G_FLD (inst->v, 19, 15) == 0x0)
1210 {
1211 /* sw r3, [r0, offset]+ */
1212 sp_offset += inst->len;
1213 if (ra_offset_p == 0)
1214 {
1215 ra_offset = sp_offset;
1216 ra_offset_p = 1;
1217 }
1218 }
1219 else if (G_FLD (inst->v, 29, 25) == 0x3
1220 && G_FLD (inst->v, 2, 0) == 0x4
1221 && G_FLD (inst->v, 24, 20) == 0x2
1222 && G_FLD (inst->v, 19, 15) == 0x0)
1223 {
1224 /* sw r2, [r0, offset]+ */
1225 sp_offset += inst->len;
1226 if (fp_offset_p == 0)
1227 {
1228 fp_offset = sp_offset;
1229 fp_offset_p = 1;
1230 }
1231 }
1232 else if (G_FLD (inst->v, 29, 25) == 0x7
1233 && G_FLD (inst->v, 2, 0) == 0x0
1234 && G_FLD (inst->v, 24, 20) == 0x3
1235 && G_FLD (inst->v, 19, 15) == 0x0)
1236 {
1237 /* lw r3, [r0]+, 4 */
1238 sp_offset -= inst->len;
1239 ra_offset_p = 1;
1240 }
1241 else if (G_FLD (inst->v, 29, 25) == 0x7
1242 && G_FLD (inst->v, 2, 0) == 0x0
1243 && G_FLD (inst->v, 24, 20) == 0x2
1244 && G_FLD (inst->v, 19, 15) == 0x0)
1245 {
1246 /* lw r2, [r0]+, 4 */
1247 sp_offset -= inst->len;
1248 fp_offset_p = 1;
1249 }
1250 else if (G_FLD (inst->v, 29, 25) == 0x1
1251 && G_FLD (inst->v, 19, 17) == 0x0
1252 && G_FLD (inst->v, 24, 20) == 0x0
1253 && G_FLD (inst->v, 0, 0) == 0x0)
1254 {
1255 /* addi r0, -offset */
1256 int imm = G_FLD (inst->v, 16, 1);
1257 if (imm >> 15)
1258 imm = -(0xFFFF - imm + 1);
1259 sp_offset -= imm;
1260 }
1261 else if (G_FLD (inst->v, 29, 25) == 0x1
1262 && G_FLD (inst->v, 19, 17) == 0x0
1263 && G_FLD (inst->v, 24, 20) == 0x2
1264 && G_FLD (inst->v, 0, 0) == 0x0)
1265 {
1266 /* addi r2, offset */
1267 if (pc - cur_pc >= 2)
1268 {
5f814c3b
DL
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)
19ba03f4 1323 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
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)
19ba03f4
SM
1339 score3_analyze_prologue (start_addr, pc, this_frame,
1340 (struct score_frame_cache *) *this_cache);
5f814c3b 1341 else
19ba03f4
SM
1342 score7_analyze_prologue (start_addr, pc, this_frame,
1343 (struct score_frame_cache *) *this_cache);
27fd2f50
Q
1344 }
1345
1346 /* Save SP. */
1347 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1348
19ba03f4 1349 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
1350}
1351
1352static void
94afd7a6 1353score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
1354 struct frame_id *this_id)
1355{
94afd7a6 1356 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1357 this_cache);
94afd7a6 1358 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
1359}
1360
94afd7a6
UW
1361static struct value *
1362score_prologue_prev_register (struct frame_info *this_frame,
1363 void **this_cache, int regnum)
27fd2f50 1364{
94afd7a6 1365 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1366 this_cache);
94afd7a6 1367 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
1368}
1369
1370static const struct frame_unwind score_prologue_unwind =
1371{
1372 NORMAL_FRAME,
8fbca658 1373 default_frame_unwind_stop_reason,
27fd2f50 1374 score_prologue_this_id,
94afd7a6
UW
1375 score_prologue_prev_register,
1376 NULL,
5f814c3b
DL
1377 default_frame_sniffer,
1378 NULL
27fd2f50
Q
1379};
1380
27fd2f50 1381static CORE_ADDR
94afd7a6 1382score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1383 void **this_cache)
1384{
1385 struct score_frame_cache *info =
94afd7a6 1386 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1387 return info->fp;
27fd2f50
Q
1388}
1389
1390static const struct frame_base score_prologue_frame_base =
1391{
1392 &score_prologue_unwind,
1393 score_prologue_frame_base_address,
1394 score_prologue_frame_base_address,
1395 score_prologue_frame_base_address,
1396};
1397
1398static const struct frame_base *
94afd7a6 1399score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1400{
1401 return &score_prologue_frame_base;
1402}
1403
c5741217
AA
1404/* Core file support. */
1405
1406static const struct regcache_map_entry score7_linux_gregmap[] =
1407 {
1408 /* FIXME: According to the current Linux kernel, r0 is preceded by
1409 9 rather than 7 words. */
1410 { 7, REGCACHE_MAP_SKIP, 4 },
1411 { 32, 0, 4 }, /* r0 ... r31 */
1412 { 1, 55, 4 }, /* CEL */
1413 { 1, 54, 4 }, /* CEH */
1414 { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */
1415 { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */
1416 { 1, 51, 4 }, /* sr2, i.e. scr or STCR */
1417 { 1, 49, 4 }, /* PC (same slot as EPC) */
1418 { 1, 38, 4 }, /* EMA */
1419 { 1, 32, 4 }, /* PSR */
1420 { 1, 34, 4 }, /* ECR */
1421 { 1, 33, 4 }, /* COND */
1422 { 0 }
1423 };
1424
1425#define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1426#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
5f814c3b
DL
1427
1428static void
1429score7_linux_supply_gregset(const struct regset *regset,
c5741217
AA
1430 struct regcache *regcache,
1431 int regnum, const void *buf,
1432 size_t size)
5f814c3b 1433{
c5741217
AA
1434 regcache_supply_regset (regset, regcache, regnum, buf, size);
1435
1436 /* Supply the EPC from the same slot as the PC. Note that the
1437 collect function will store the PC in that slot. */
1438 if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1439 && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1440 regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
1441 (const gdb_byte *) buf
1442 + SCORE7_LINUX_EPC_OFFSET);
5f814c3b
DL
1443}
1444
8fea3224
AA
1445static const struct regset score7_linux_gregset =
1446 {
c5741217
AA
1447 score7_linux_gregmap,
1448 score7_linux_supply_gregset,
1449 regcache_collect_regset
8fea3224
AA
1450 };
1451
9845a0b5 1452/* Iterate over core file register note sections. */
5f814c3b 1453
9845a0b5
AA
1454static void
1455score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1456 iterate_over_regset_sections_cb *cb,
1457 void *cb_data,
1458 const struct regcache *regcache)
5f814c3b 1459{
9845a0b5
AA
1460 cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
1461 NULL, cb_data);
5f814c3b
DL
1462}
1463
27fd2f50
Q
1464static struct gdbarch *
1465score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1466{
1467 struct gdbarch *gdbarch;
5f814c3b 1468 target_mach = info.bfd_arch_info->mach;
27fd2f50
Q
1469
1470 arches = gdbarch_list_lookup_by_info (arches, &info);
1471 if (arches != NULL)
1472 {
1473 return (arches->gdbarch);
1474 }
8fea3224 1475 gdbarch = gdbarch_alloc (&info, NULL);
27fd2f50
Q
1476
1477 set_gdbarch_short_bit (gdbarch, 16);
1478 set_gdbarch_int_bit (gdbarch, 32);
1479 set_gdbarch_float_bit (gdbarch, 32);
1480 set_gdbarch_double_bit (gdbarch, 64);
1481 set_gdbarch_long_double_bit (gdbarch, 64);
5f814c3b 1482#if WITH_SIM
27fd2f50 1483 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
5f814c3b 1484#endif
27fd2f50
Q
1485 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1486 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
c378eb4e
MS
1487 set_gdbarch_adjust_breakpoint_address (gdbarch,
1488 score_adjust_breakpoint_address);
27fd2f50
Q
1489 set_gdbarch_register_type (gdbarch, score_register_type);
1490 set_gdbarch_frame_align (gdbarch, score_frame_align);
1491 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
30244cd8 1492 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
5f814c3b 1493 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
27fd2f50 1494 set_gdbarch_print_insn (gdbarch, score_print_insn);
5f814c3b
DL
1495
1496 switch (target_mach)
1497 {
1498 case bfd_mach_score7:
d19280ad 1499 SET_GDBARCH_BREAKPOINT_MANIPULATION (score7);
5f814c3b 1500 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
c9cf6e20
MG
1501 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1502 score7_stack_frame_destroyed_p);
5f814c3b
DL
1503 set_gdbarch_register_name (gdbarch, score7_register_name);
1504 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
c378eb4e 1505 /* Core file support. */
9845a0b5
AA
1506 set_gdbarch_iterate_over_regset_sections
1507 (gdbarch, score7_linux_iterate_over_regset_sections);
5f814c3b
DL
1508 break;
1509
1510 case bfd_mach_score3:
d19280ad 1511 SET_GDBARCH_BREAKPOINT_MANIPULATION (score3);
5f814c3b 1512 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
c9cf6e20
MG
1513 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1514 score3_stack_frame_destroyed_p);
5f814c3b
DL
1515 set_gdbarch_register_name (gdbarch, score3_register_name);
1516 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1517 break;
1518 }
5e29c264
Q
1519
1520 /* Watchpoint hooks. */
1521 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1522
1523 /* Dummy frame hooks. */
27fd2f50 1524 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1525 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1526 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1527 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1528
5e29c264 1529 /* Normal frame hooks. */
94afd7a6 1530 dwarf2_append_unwinders (gdbarch);
27fd2f50 1531 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1532 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1533 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1534
1535 return gdbarch;
1536}
1537
1538extern initialize_file_ftype _initialize_score_tdep;
1539
1540void
1541_initialize_score_tdep (void)
1542{
1543 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1544}
This page took 1.220668 seconds and 4 git commands to generate.