]> Git Repo - binutils.git/blame - gdb/score-tdep.c
Split breakpoint_from_pc to breakpoint_kind_from_pc and sw_breakpoint_from_kind
[binutils.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 ([email protected])
7 Contributed by Ching-Peng Lin ([email protected])
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
d19280ad
YQ
309static int
310score7_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
27fd2f50 311{
27fd2f50
Q
312 int ret;
313 unsigned int raw;
d19280ad
YQ
314 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
315 gdb_byte buf[SCORE_INSTLEN] = { 0 };
27fd2f50
Q
316
317 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
318 {
a73c6dcd 319 error (_("Error: target_read_memory in file:%s, line:%d!"),
d19280ad 320 __FILE__, __LINE__);
27fd2f50 321 }
e17a4113 322 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
27fd2f50 323
d19280ad 324 if (!(raw & 0x80008000))
27fd2f50 325 {
d19280ad
YQ
326 /* 16bits instruction. */
327 *pcptr &= ~0x1;
328 return 2;
329 }
330 else
331 {
332 /* 32bits instruction. */
333 *pcptr &= ~0x3;
334 return 4;
335 }
336}
337
338static const gdb_byte *
339score7_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
340{
341 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
342
343 *size = kind;
344
345 if (kind == 4)
346 {
347 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
348 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
349
350 if (byte_order == BFD_ENDIAN_BIG)
351 return big_breakpoint32;
27fd2f50 352 else
d19280ad 353 return little_breakpoint32;
27fd2f50
Q
354 }
355 else
356 {
d19280ad
YQ
357 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
358 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
359
360 if (byte_order == BFD_ENDIAN_BIG)
361 return big_breakpoint16;
27fd2f50 362 else
d19280ad 363 return little_breakpoint16;
27fd2f50
Q
364 }
365}
366
d19280ad
YQ
367GDBARCH_BREAKPOINT_FROM_PC (score7)
368
369static int
370score3_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
5f814c3b
DL
371{
372 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5f814c3b 373 int len;
d19280ad
YQ
374
375 score3_adjust_pc_and_fetch_inst (pcptr, &len, byte_order);
376
377 return len;
378}
379
380static const gdb_byte *
381score3_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
382{
383 int index = 0;
384 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5f814c3b
DL
385 static gdb_byte score_break_insns[6][6] = {
386 /* The following three instructions are big endian. */
387 { 0x00, 0x20 },
388 { 0x80, 0x00, 0x00, 0x06 },
389 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
390 /* The following three instructions are little endian. */
391 { 0x20, 0x00 },
392 { 0x00, 0x80, 0x06, 0x00 },
393 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
394
d19280ad 395 *size = kind;
5f814c3b 396
d19280ad
YQ
397 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (kind / 2 - 1);
398 return score_break_insns[index];
5f814c3b
DL
399}
400
d19280ad
YQ
401GDBARCH_BREAKPOINT_FROM_PC (score3)
402
5f814c3b
DL
403static CORE_ADDR
404score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
405{
406 CORE_ADDR adjust_pc = bpaddr;
407
408 if (target_mach == bfd_mach_score3)
409 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
410 gdbarch_byte_order (gdbarch));
411 else
412 adjust_pc = align_down (adjust_pc, 2);
413
414 return adjust_pc;
415}
416
27fd2f50
Q
417static CORE_ADDR
418score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
419{
420 return align_down (addr, 16);
421}
422
423static void
424score_xfer_register (struct regcache *regcache, int regnum, int length,
425 enum bfd_endian endian, gdb_byte *readbuf,
426 const gdb_byte *writebuf, int buf_offset)
427{
428 int reg_offset = 0;
5f814c3b 429 gdb_assert (regnum >= 0
c378eb4e
MS
430 && regnum < ((target_mach == bfd_mach_score7)
431 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
27fd2f50
Q
432
433 switch (endian)
434 {
435 case BFD_ENDIAN_BIG:
436 reg_offset = SCORE_REGSIZE - length;
437 break;
438 case BFD_ENDIAN_LITTLE:
439 reg_offset = 0;
440 break;
441 case BFD_ENDIAN_UNKNOWN:
442 reg_offset = 0;
443 break;
444 default:
a73c6dcd 445 error (_("Error: score_xfer_register in file:%s, line:%d!"),
5e29c264 446 __FILE__, __LINE__);
27fd2f50
Q
447 }
448
449 if (readbuf != NULL)
450 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
451 readbuf + buf_offset);
452 if (writebuf != NULL)
453 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
454 writebuf + buf_offset);
455}
456
457static enum return_value_convention
6a3a010b 458score_return_value (struct gdbarch *gdbarch, struct value *function,
5f814c3b 459 struct type *type, struct regcache *regcache,
27fd2f50
Q
460 gdb_byte * readbuf, const gdb_byte * writebuf)
461{
462 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
463 || TYPE_CODE (type) == TYPE_CODE_UNION
464 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
465 return RETURN_VALUE_STRUCT_CONVENTION;
466 else
467 {
468 int offset;
469 int regnum;
470 for (offset = 0, regnum = SCORE_A0_REGNUM;
471 offset < TYPE_LENGTH (type);
472 offset += SCORE_REGSIZE, regnum++)
473 {
474 int xfer = SCORE_REGSIZE;
c378eb4e 475
27fd2f50
Q
476 if (offset + xfer > TYPE_LENGTH (type))
477 xfer = TYPE_LENGTH (type) - offset;
4c6b5505 478 score_xfer_register (regcache, regnum, xfer,
5f814c3b 479 gdbarch_byte_order(gdbarch),
27fd2f50
Q
480 readbuf, writebuf, offset);
481 }
482 return RETURN_VALUE_REGISTER_CONVENTION;
483 }
484}
485
486static struct frame_id
94afd7a6 487score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27fd2f50 488{
c378eb4e
MS
489 return frame_id_build (get_frame_register_unsigned (this_frame,
490 SCORE_SP_REGNUM),
491 get_frame_pc (this_frame));
27fd2f50
Q
492}
493
494static int
495score_type_needs_double_align (struct type *type)
496{
497 enum type_code typecode = TYPE_CODE (type);
498
5e29c264
Q
499 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
500 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
27fd2f50
Q
501 return 1;
502 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
503 {
504 int i, n;
505
506 n = TYPE_NFIELDS (type);
507 for (i = 0; i < n; i++)
508 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
509 return 1;
510 return 0;
511 }
512 return 0;
513}
514
515static CORE_ADDR
516score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
517 struct regcache *regcache, CORE_ADDR bp_addr,
518 int nargs, struct value **args, CORE_ADDR sp,
519 int struct_return, CORE_ADDR struct_addr)
520{
e17a4113 521 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
27fd2f50
Q
522 int argnum;
523 int argreg;
524 int arglen = 0;
525 CORE_ADDR stack_offset = 0;
526 CORE_ADDR addr = 0;
527
528 /* Step 1, Save RA. */
529 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
530
531 /* Step 2, Make space on the stack for the args. */
532 struct_addr = align_down (struct_addr, 16);
533 sp = align_down (sp, 16);
534 for (argnum = 0; argnum < nargs; argnum++)
535 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
536 SCORE_REGSIZE);
537 sp -= align_up (arglen, 16);
538
539 argreg = SCORE_BEGIN_ARG_REGNUM;
540
5e29c264
Q
541 /* Step 3, Check if struct return then save the struct address to
542 r4 and increase the stack_offset by 4. */
27fd2f50
Q
543 if (struct_return)
544 {
545 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
546 stack_offset += SCORE_REGSIZE;
547 }
548
549 /* Step 4, Load arguments:
5e29c264
Q
550 If arg length is too long (> 4 bytes), then split the arg and
551 save every parts. */
27fd2f50
Q
552 for (argnum = 0; argnum < nargs; argnum++)
553 {
554 struct value *arg = args[argnum];
555 struct type *arg_type = check_typedef (value_type (arg));
27fd2f50
Q
556 enum type_code typecode = TYPE_CODE (arg_type);
557 const gdb_byte *val = value_contents (arg);
558 int downward_offset = 0;
1cfd2c3e 559 int arg_last_part_p = 0;
27fd2f50 560
1cfd2c3e 561 arglen = TYPE_LENGTH (arg_type);
27fd2f50
Q
562
563 /* If a arg should be aligned to 8 bytes (long long or double),
564 the value should be put to even register numbers. */
565 if (score_type_needs_double_align (arg_type))
566 {
567 if (argreg & 1)
568 argreg++;
569 }
570
571 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
572 the default "downward"/"upward" method:
573
574 Example:
575
576 struct struc
577 {
578 char a; char b; char c;
579 } s = {'a', 'b', 'c'};
580
581 Big endian: s = {X, 'a', 'b', 'c'}
582 Little endian: s = {'a', 'b', 'c', X}
583
584 Where X is a hole. */
585
5f814c3b 586 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
27fd2f50
Q
587 && (typecode == TYPE_CODE_STRUCT
588 || typecode == TYPE_CODE_UNION)
589 && argreg > SCORE_LAST_ARG_REGNUM
590 && arglen < SCORE_REGSIZE)
591 downward_offset += (SCORE_REGSIZE - arglen);
592
593 while (arglen > 0)
594 {
595 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
e17a4113 596 ULONGEST regval = extract_unsigned_integer (val, partial_len,
5f814c3b 597 byte_order);
27fd2f50
Q
598
599 /* The last part of a arg should shift left when
4c6b5505 600 gdbarch_byte_order is BFD_ENDIAN_BIG. */
5f814c3b 601 if (byte_order == BFD_ENDIAN_BIG
27fd2f50
Q
602 && arg_last_part_p == 1
603 && (typecode == TYPE_CODE_STRUCT
604 || typecode == TYPE_CODE_UNION))
605 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
606
607 /* Always increase the stack_offset and save args to stack. */
608 addr = sp + stack_offset + downward_offset;
609 write_memory (addr, val, partial_len);
610
611 if (argreg <= SCORE_LAST_ARG_REGNUM)
612 {
613 regcache_cooked_write_unsigned (regcache, argreg++, regval);
614 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
615 arg_last_part_p = 1;
616 }
617
618 val += partial_len;
619 arglen -= partial_len;
620 stack_offset += align_up (partial_len, SCORE_REGSIZE);
621 }
622 }
623
624 /* Step 5, Save SP. */
625 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
626
627 return sp;
628}
629
27fd2f50 630static CORE_ADDR
5f814c3b 631score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50
Q
632{
633 CORE_ADDR cpc = pc;
634 int iscan = 32, stack_sub = 0;
635 while (iscan-- > 0)
636 {
5f814c3b 637 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
27fd2f50
Q
638 if (!inst)
639 break;
5f814c3b 640 if ((inst->len == 4) && !stack_sub
27fd2f50
Q
641 && (G_FLD (inst->v, 29, 25) == 0x1
642 && G_FLD (inst->v, 24, 20) == 0x0))
643 {
644 /* addi r0, offset */
5f814c3b
DL
645 stack_sub = cpc + SCORE_INSTLEN;
646 pc = cpc + SCORE_INSTLEN;
27fd2f50 647 }
5f814c3b
DL
648 else if ((inst->len == 4)
649 && (G_FLD (inst->v, 29, 25) == 0x0)
650 && (G_FLD (inst->v, 24, 20) == 0x2)
651 && (G_FLD (inst->v, 19, 15) == 0x0)
652 && (G_FLD (inst->v, 14, 10) == 0xF)
653 && (G_FLD (inst->v, 9, 0) == 0x56))
27fd2f50
Q
654 {
655 /* mv r2, r0 */
656 pc = cpc + SCORE_INSTLEN;
657 break;
658 }
5f814c3b
DL
659 else if ((inst->len == 2)
660 && (G_FLD (inst->v, 14, 12) == 0x0)
661 && (G_FLD (inst->v, 11, 8) == 0x2)
662 && (G_FLD (inst->v, 7, 4) == 0x0)
663 && (G_FLD (inst->v, 3, 0) == 0x3))
27fd2f50
Q
664 {
665 /* mv! r2, r0 */
666 pc = cpc + SCORE16_INSTLEN;
667 break;
668 }
5f814c3b 669 else if ((inst->len == 2)
27fd2f50
Q
670 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
671 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
672 || (G_FLD (inst->v, 14, 12) == 0x0
673 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
674 break;
5f814c3b 675 else if ((inst->len == 4)
27fd2f50
Q
676 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
677 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
678 || (G_FLD (inst->v, 29, 25) == 0x0
679 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
680 break;
681
5f814c3b 682 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
27fd2f50
Q
683 }
684 return pc;
685}
686
5f814c3b
DL
687static CORE_ADDR
688score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
27fd2f50 689{
5f814c3b
DL
690 CORE_ADDR cpc = pc;
691 int iscan = 32, stack_sub = 0;
692 while (iscan-- > 0)
693 {
694 inst_t *inst
c378eb4e
MS
695 = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
696 gdbarch_byte_order (gdbarch));
27fd2f50 697
5f814c3b
DL
698 if (!inst)
699 break;
700 if (inst->len == 4 && !stack_sub
701 && (G_FLD (inst->v, 29, 25) == 0x1)
702 && (G_FLD (inst->v, 19, 17) == 0x0)
703 && (G_FLD (inst->v, 24, 20) == 0x0))
704 {
705 /* addi r0, offset */
706 stack_sub = cpc + inst->len;
707 pc = cpc + inst->len;
708 }
709 else if (inst->len == 4
710 && (G_FLD (inst->v, 29, 25) == 0x0)
711 && (G_FLD (inst->v, 24, 20) == 0x2)
712 && (G_FLD (inst->v, 19, 15) == 0x0)
713 && (G_FLD (inst->v, 14, 10) == 0xF)
714 && (G_FLD (inst->v, 9, 0) == 0x56))
715 {
716 /* mv r2, r0 */
717 pc = cpc + inst->len;
718 break;
719 }
720 else if ((inst->len == 2)
721 && (G_FLD (inst->v, 14, 10) == 0x10)
722 && (G_FLD (inst->v, 9, 5) == 0x2)
723 && (G_FLD (inst->v, 4, 0) == 0x0))
724 {
725 /* mv! r2, r0 */
726 pc = cpc + inst->len;
727 break;
728 }
729 else if (inst->len == 2
730 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
731 || (G_FLD (inst->v, 14, 12) == 0x0
732 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
733 break;
734 else if (inst->len == 4
735 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
736 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
737 break;
738
739 cpc += inst->len;
740 }
741 return pc;
742}
743
c9cf6e20
MG
744/* Implement the stack_frame_destroyed_p gdbarch method. */
745
5f814c3b 746static int
c9cf6e20 747score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
748{
749 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
750
751 if (inst->v == 0x23)
752 return 1; /* mv! r0, r2 */
753 else if (G_FLD (inst->v, 14, 12) == 0x2
754 && G_FLD (inst->v, 3, 0) == 0xa)
755 return 1; /* pop! */
27fd2f50
Q
756 else if (G_FLD (inst->v, 14, 12) == 0x0
757 && G_FLD (inst->v, 7, 0) == 0x34)
758 return 1; /* br! r3 */
759 else if (G_FLD (inst->v, 29, 15) == 0x2
760 && G_FLD (inst->v, 6, 1) == 0x2b)
761 return 1; /* mv r0, r2 */
762 else if (G_FLD (inst->v, 29, 25) == 0x0
763 && G_FLD (inst->v, 6, 1) == 0x4
764 && G_FLD (inst->v, 19, 15) == 0x3)
765 return 1; /* br r3 */
766 else
767 return 0;
768}
769
c9cf6e20
MG
770/* Implement the stack_frame_destroyed_p gdbarch method. */
771
5f814c3b 772static int
c9cf6e20 773score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
5f814c3b
DL
774{
775 CORE_ADDR pc = cur_pc;
776 inst_t *inst
c378eb4e
MS
777 = score3_adjust_pc_and_fetch_inst (&pc, NULL,
778 gdbarch_byte_order (gdbarch));
5f814c3b
DL
779
780 if (inst->len == 2
781 && (G_FLD (inst->v, 14, 10) == 0x10)
782 && (G_FLD (inst->v, 9, 5) == 0x0)
783 && (G_FLD (inst->v, 4, 0) == 0x2))
784 return 1; /* mv! r0, r2 */
785 else if (inst->len == 4
786 && (G_FLD (inst->v, 29, 25) == 0x0)
787 && (G_FLD (inst->v, 24, 20) == 0x2)
788 && (G_FLD (inst->v, 19, 15) == 0x0)
789 && (G_FLD (inst->v, 14, 10) == 0xF)
790 && (G_FLD (inst->v, 9, 0) == 0x56))
791 return 1; /* mv r0, r2 */
792 else if (inst->len == 2
793 && (G_FLD (inst->v, 14, 12) == 0x0)
794 && (G_FLD (inst->v, 11, 5) == 0x2))
795 return 1; /* pop! */
796 else if (inst->len == 2
797 && (G_FLD (inst->v, 14, 12) == 0x0)
798 && (G_FLD (inst->v, 11, 7) == 0x0)
799 && (G_FLD (inst->v, 6, 5) == 0x2))
800 return 1; /* rpop! */
801 else if (inst->len == 2
802 && (G_FLD (inst->v, 14, 12) == 0x0)
803 && (G_FLD (inst->v, 11, 5) == 0x4)
804 && (G_FLD (inst->v, 4, 0) == 0x3))
805 return 1; /* br! r3 */
806 else if (inst->len == 4
807 && (G_FLD (inst->v, 29, 25) == 0x0)
808 && (G_FLD (inst->v, 24, 20) == 0x0)
809 && (G_FLD (inst->v, 19, 15) == 0x3)
810 && (G_FLD (inst->v, 14, 10) == 0xF)
811 && (G_FLD (inst->v, 9, 0) == 0x8))
812 return 1; /* br r3 */
813 else
814 return 0;
815}
816
e362b510 817static gdb_byte *
5f814c3b
DL
818score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
819{
820 int ret;
e362b510 821 gdb_byte *memblock = NULL;
5f814c3b 822
d66ff635 823 if (size == 0)
5f814c3b
DL
824 return NULL;
825
224c3ddb 826 memblock = (gdb_byte *) xmalloc (size);
5f814c3b
DL
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
948f8e3d 839score7_free_memblock (gdb_byte *memblock)
5f814c3b
DL
840{
841 xfree (memblock);
842}
843
844static void
e362b510 845score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
5f814c3b
DL
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
e362b510
PA
881 gdb_byte *memblock = NULL;
882 gdb_byte *memblock_ptr = NULL;
5e29c264
Q
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
5f814c3b
DL
1089 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1090 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1091
870f88f7 1092 for (; cur_pc < pc; cur_pc += inst_len)
5f814c3b
DL
1093 {
1094 inst_t *inst = NULL;
1095
1096 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1097
c378eb4e 1098 /* FIXME: make a full-power prologue analyzer. */
5f814c3b
DL
1099 if (inst->len == 2)
1100 {
1101 if (G_FLD (inst->v, 14, 12) == 0x0
1102 && G_FLD (inst->v, 11, 7) == 0x0
1103 && G_FLD (inst->v, 6, 5) == 0x3)
1104 {
1105 /* push! */
1106 sp_offset += 4;
1107
1108 if (G_FLD (inst->v, 4, 0) == 0x3
1109 && ra_offset_p == 0)
1110 {
1111 /* push! r3, [r0] */
1112 ra_offset = sp_offset;
1113 ra_offset_p = 1;
1114 }
1115 else if (G_FLD (inst->v, 4, 0) == 0x2
1116 && fp_offset_p == 0)
1117 {
1118 /* push! r2, [r0] */
1119 fp_offset = sp_offset;
1120 fp_offset_p = 1;
1121 }
1122 }
1123 else if (G_FLD (inst->v, 14, 12) == 0x6
1124 && G_FLD (inst->v, 11, 10) == 0x3)
1125 {
1126 /* rpush! */
1127 int start_r = G_FLD (inst->v, 9, 5);
1128 int cnt = G_FLD (inst->v, 4, 0);
1129
1130 if ((ra_offset_p == 0)
1131 && (start_r <= SCORE_RA_REGNUM)
1132 && (SCORE_RA_REGNUM < start_r + cnt))
1133 {
1134 /* rpush! contains r3 */
1135 ra_offset_p = 1;
1136 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1137 }
1138
1139 if ((fp_offset_p == 0)
1140 && (start_r <= SCORE_FP_REGNUM)
1141 && (SCORE_FP_REGNUM < start_r + cnt))
1142 {
1143 /* rpush! contains r2 */
1144 fp_offset_p = 1;
1145 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1146 }
1147
1148 sp_offset += 4 * cnt;
1149 }
1150 else if (G_FLD (inst->v, 14, 12) == 0x0
1151 && G_FLD (inst->v, 11, 7) == 0x0
1152 && G_FLD (inst->v, 6, 5) == 0x2)
1153 {
1154 /* pop! */
1155 sp_offset -= 4;
1156 }
1157 else if (G_FLD (inst->v, 14, 12) == 0x6
1158 && G_FLD (inst->v, 11, 10) == 0x2)
1159 {
1160 /* rpop! */
1161 sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1162 }
1163 else if (G_FLD (inst->v, 14, 12) == 0x5
1164 && G_FLD (inst->v, 11, 10) == 0x3
1165 && G_FLD (inst->v, 9, 6) == 0x0)
1166 {
1167 /* addi! r0, -offset */
1168 int imm = G_FLD (inst->v, 5, 0);
1169 if (imm >> 5)
1170 imm = -(0x3F - imm + 1);
1171 sp_offset -= imm;
1172 }
1173 else if (G_FLD (inst->v, 14, 12) == 0x5
1174 && G_FLD (inst->v, 11, 10) == 0x3
1175 && G_FLD (inst->v, 9, 6) == 0x2)
1176 {
1177 /* addi! r2, offset */
1178 if (pc - cur_pc >= 2)
1179 {
5f814c3b
DL
1180 inst_t *inst2;
1181
1182 cur_pc += inst->len;
c378eb4e
MS
1183 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1184 byte_order);
5f814c3b
DL
1185
1186 if (inst2->len == 2
1187 && G_FLD (inst2->v, 14, 10) == 0x10
1188 && G_FLD (inst2->v, 9, 5) == 0x0
1189 && G_FLD (inst2->v, 4, 0) == 0x2)
1190 {
1191 /* mv! r0, r2 */
1192 int imm = G_FLD (inst->v, 5, 0);
1193 if (imm >> 5)
1194 imm = -(0x3F - imm + 1);
1195 sp_offset -= imm;
1196 }
1197 }
1198 }
1199 }
1200 else if (inst->len == 4)
1201 {
1202 if (G_FLD (inst->v, 29, 25) == 0x3
1203 && G_FLD (inst->v, 2, 0) == 0x4
1204 && G_FLD (inst->v, 24, 20) == 0x3
1205 && G_FLD (inst->v, 19, 15) == 0x0)
1206 {
1207 /* sw r3, [r0, offset]+ */
1208 sp_offset += inst->len;
1209 if (ra_offset_p == 0)
1210 {
1211 ra_offset = sp_offset;
1212 ra_offset_p = 1;
1213 }
1214 }
1215 else if (G_FLD (inst->v, 29, 25) == 0x3
1216 && G_FLD (inst->v, 2, 0) == 0x4
1217 && G_FLD (inst->v, 24, 20) == 0x2
1218 && G_FLD (inst->v, 19, 15) == 0x0)
1219 {
1220 /* sw r2, [r0, offset]+ */
1221 sp_offset += inst->len;
1222 if (fp_offset_p == 0)
1223 {
1224 fp_offset = sp_offset;
1225 fp_offset_p = 1;
1226 }
1227 }
1228 else if (G_FLD (inst->v, 29, 25) == 0x7
1229 && G_FLD (inst->v, 2, 0) == 0x0
1230 && G_FLD (inst->v, 24, 20) == 0x3
1231 && G_FLD (inst->v, 19, 15) == 0x0)
1232 {
1233 /* lw r3, [r0]+, 4 */
1234 sp_offset -= inst->len;
1235 ra_offset_p = 1;
1236 }
1237 else if (G_FLD (inst->v, 29, 25) == 0x7
1238 && G_FLD (inst->v, 2, 0) == 0x0
1239 && G_FLD (inst->v, 24, 20) == 0x2
1240 && G_FLD (inst->v, 19, 15) == 0x0)
1241 {
1242 /* lw r2, [r0]+, 4 */
1243 sp_offset -= inst->len;
1244 fp_offset_p = 1;
1245 }
1246 else if (G_FLD (inst->v, 29, 25) == 0x1
1247 && G_FLD (inst->v, 19, 17) == 0x0
1248 && G_FLD (inst->v, 24, 20) == 0x0
1249 && G_FLD (inst->v, 0, 0) == 0x0)
1250 {
1251 /* addi r0, -offset */
1252 int imm = G_FLD (inst->v, 16, 1);
1253 if (imm >> 15)
1254 imm = -(0xFFFF - imm + 1);
1255 sp_offset -= imm;
1256 }
1257 else if (G_FLD (inst->v, 29, 25) == 0x1
1258 && G_FLD (inst->v, 19, 17) == 0x0
1259 && G_FLD (inst->v, 24, 20) == 0x2
1260 && G_FLD (inst->v, 0, 0) == 0x0)
1261 {
1262 /* addi r2, offset */
1263 if (pc - cur_pc >= 2)
1264 {
5f814c3b
DL
1265 inst_t *inst2;
1266
1267 cur_pc += inst->len;
c378eb4e
MS
1268 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1269 byte_order);
5f814c3b
DL
1270
1271 if (inst2->len == 2
1272 && G_FLD (inst2->v, 14, 10) == 0x10
1273 && G_FLD (inst2->v, 9, 5) == 0x0
1274 && G_FLD (inst2->v, 4, 0) == 0x2)
1275 {
1276 /* mv! r0, r2 */
1277 int imm = G_FLD (inst->v, 16, 1);
1278 if (imm >> 15)
1279 imm = -(0xFFFF - imm + 1);
1280 sp_offset -= imm;
1281 }
1282 }
1283 }
1284 }
1285 }
1286
1287 /* Save RA. */
1288 if (ra_offset_p == 1)
1289 {
1290 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1291 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1292 sp + sp_offset - ra_offset;
1293 }
1294 else
1295 {
1296 this_cache->saved_regs[SCORE_PC_REGNUM] =
1297 this_cache->saved_regs[SCORE_RA_REGNUM];
1298 }
1299
1300 /* Save FP. */
1301 if (fp_offset_p == 1)
1302 {
1303 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1304 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1305 sp + sp_offset - fp_offset;
1306 }
1307
1308 /* Save SP and FP. */
1309 this_cache->base = sp + sp_offset;
1310 this_cache->fp = fp;
27fd2f50
Q
1311}
1312
1313static struct score_frame_cache *
94afd7a6 1314score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
27fd2f50
Q
1315{
1316 struct score_frame_cache *cache;
1317
1318 if ((*this_cache) != NULL)
19ba03f4 1319 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
1320
1321 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1322 (*this_cache) = cache;
94afd7a6 1323 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
27fd2f50
Q
1324
1325 /* Analyze the prologue. */
1326 {
94afd7a6 1327 const CORE_ADDR pc = get_frame_pc (this_frame);
27fd2f50
Q
1328 CORE_ADDR start_addr;
1329
1330 find_pc_partial_function (pc, NULL, &start_addr, NULL);
1331 if (start_addr == 0)
1332 return cache;
5f814c3b
DL
1333
1334 if (target_mach == bfd_mach_score3)
19ba03f4
SM
1335 score3_analyze_prologue (start_addr, pc, this_frame,
1336 (struct score_frame_cache *) *this_cache);
5f814c3b 1337 else
19ba03f4
SM
1338 score7_analyze_prologue (start_addr, pc, this_frame,
1339 (struct score_frame_cache *) *this_cache);
27fd2f50
Q
1340 }
1341
1342 /* Save SP. */
1343 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1344
19ba03f4 1345 return (struct score_frame_cache *) (*this_cache);
27fd2f50
Q
1346}
1347
1348static void
94afd7a6 1349score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
27fd2f50
Q
1350 struct frame_id *this_id)
1351{
94afd7a6 1352 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1353 this_cache);
94afd7a6 1354 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
27fd2f50
Q
1355}
1356
94afd7a6
UW
1357static struct value *
1358score_prologue_prev_register (struct frame_info *this_frame,
1359 void **this_cache, int regnum)
27fd2f50 1360{
94afd7a6 1361 struct score_frame_cache *info = score_make_prologue_cache (this_frame,
27fd2f50 1362 this_cache);
94afd7a6 1363 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
27fd2f50
Q
1364}
1365
1366static const struct frame_unwind score_prologue_unwind =
1367{
1368 NORMAL_FRAME,
8fbca658 1369 default_frame_unwind_stop_reason,
27fd2f50 1370 score_prologue_this_id,
94afd7a6
UW
1371 score_prologue_prev_register,
1372 NULL,
5f814c3b
DL
1373 default_frame_sniffer,
1374 NULL
27fd2f50
Q
1375};
1376
27fd2f50 1377static CORE_ADDR
94afd7a6 1378score_prologue_frame_base_address (struct frame_info *this_frame,
27fd2f50
Q
1379 void **this_cache)
1380{
1381 struct score_frame_cache *info =
94afd7a6 1382 score_make_prologue_cache (this_frame, this_cache);
5e29c264 1383 return info->fp;
27fd2f50
Q
1384}
1385
1386static const struct frame_base score_prologue_frame_base =
1387{
1388 &score_prologue_unwind,
1389 score_prologue_frame_base_address,
1390 score_prologue_frame_base_address,
1391 score_prologue_frame_base_address,
1392};
1393
1394static const struct frame_base *
94afd7a6 1395score_prologue_frame_base_sniffer (struct frame_info *this_frame)
27fd2f50
Q
1396{
1397 return &score_prologue_frame_base;
1398}
1399
c5741217
AA
1400/* Core file support. */
1401
1402static const struct regcache_map_entry score7_linux_gregmap[] =
1403 {
1404 /* FIXME: According to the current Linux kernel, r0 is preceded by
1405 9 rather than 7 words. */
1406 { 7, REGCACHE_MAP_SKIP, 4 },
1407 { 32, 0, 4 }, /* r0 ... r31 */
1408 { 1, 55, 4 }, /* CEL */
1409 { 1, 54, 4 }, /* CEH */
1410 { 1, 53, 4 }, /* sr0, i.e. cnt or COUNTER */
1411 { 1, 52, 4 }, /* sr1, i.e. lcr or LDCR */
1412 { 1, 51, 4 }, /* sr2, i.e. scr or STCR */
1413 { 1, 49, 4 }, /* PC (same slot as EPC) */
1414 { 1, 38, 4 }, /* EMA */
1415 { 1, 32, 4 }, /* PSR */
1416 { 1, 34, 4 }, /* ECR */
1417 { 1, 33, 4 }, /* COND */
1418 { 0 }
1419 };
1420
1421#define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1422#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
5f814c3b
DL
1423
1424static void
1425score7_linux_supply_gregset(const struct regset *regset,
c5741217
AA
1426 struct regcache *regcache,
1427 int regnum, const void *buf,
1428 size_t size)
5f814c3b 1429{
c5741217
AA
1430 regcache_supply_regset (regset, regcache, regnum, buf, size);
1431
1432 /* Supply the EPC from the same slot as the PC. Note that the
1433 collect function will store the PC in that slot. */
1434 if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1435 && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1436 regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
1437 (const gdb_byte *) buf
1438 + SCORE7_LINUX_EPC_OFFSET);
5f814c3b
DL
1439}
1440
8fea3224
AA
1441static const struct regset score7_linux_gregset =
1442 {
c5741217
AA
1443 score7_linux_gregmap,
1444 score7_linux_supply_gregset,
1445 regcache_collect_regset
8fea3224
AA
1446 };
1447
9845a0b5 1448/* Iterate over core file register note sections. */
5f814c3b 1449
9845a0b5
AA
1450static void
1451score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1452 iterate_over_regset_sections_cb *cb,
1453 void *cb_data,
1454 const struct regcache *regcache)
5f814c3b 1455{
9845a0b5
AA
1456 cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
1457 NULL, cb_data);
5f814c3b
DL
1458}
1459
27fd2f50
Q
1460static struct gdbarch *
1461score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1462{
1463 struct gdbarch *gdbarch;
5f814c3b 1464 target_mach = info.bfd_arch_info->mach;
27fd2f50
Q
1465
1466 arches = gdbarch_list_lookup_by_info (arches, &info);
1467 if (arches != NULL)
1468 {
1469 return (arches->gdbarch);
1470 }
8fea3224 1471 gdbarch = gdbarch_alloc (&info, NULL);
27fd2f50
Q
1472
1473 set_gdbarch_short_bit (gdbarch, 16);
1474 set_gdbarch_int_bit (gdbarch, 32);
1475 set_gdbarch_float_bit (gdbarch, 32);
1476 set_gdbarch_double_bit (gdbarch, 64);
1477 set_gdbarch_long_double_bit (gdbarch, 64);
5f814c3b 1478#if WITH_SIM
27fd2f50 1479 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
5f814c3b 1480#endif
27fd2f50
Q
1481 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1482 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
c378eb4e
MS
1483 set_gdbarch_adjust_breakpoint_address (gdbarch,
1484 score_adjust_breakpoint_address);
27fd2f50
Q
1485 set_gdbarch_register_type (gdbarch, score_register_type);
1486 set_gdbarch_frame_align (gdbarch, score_frame_align);
1487 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
30244cd8 1488 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
5f814c3b 1489 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
27fd2f50 1490 set_gdbarch_print_insn (gdbarch, score_print_insn);
5f814c3b
DL
1491
1492 switch (target_mach)
1493 {
1494 case bfd_mach_score7:
d19280ad 1495 SET_GDBARCH_BREAKPOINT_MANIPULATION (score7);
5f814c3b 1496 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
c9cf6e20
MG
1497 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1498 score7_stack_frame_destroyed_p);
5f814c3b
DL
1499 set_gdbarch_register_name (gdbarch, score7_register_name);
1500 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
c378eb4e 1501 /* Core file support. */
9845a0b5
AA
1502 set_gdbarch_iterate_over_regset_sections
1503 (gdbarch, score7_linux_iterate_over_regset_sections);
5f814c3b
DL
1504 break;
1505
1506 case bfd_mach_score3:
d19280ad 1507 SET_GDBARCH_BREAKPOINT_MANIPULATION (score3);
5f814c3b 1508 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
c9cf6e20
MG
1509 set_gdbarch_stack_frame_destroyed_p (gdbarch,
1510 score3_stack_frame_destroyed_p);
5f814c3b
DL
1511 set_gdbarch_register_name (gdbarch, score3_register_name);
1512 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1513 break;
1514 }
5e29c264
Q
1515
1516 /* Watchpoint hooks. */
1517 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1518
1519 /* Dummy frame hooks. */
27fd2f50 1520 set_gdbarch_return_value (gdbarch, score_return_value);
5e29c264 1521 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
94afd7a6 1522 set_gdbarch_dummy_id (gdbarch, score_dummy_id);
27fd2f50
Q
1523 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1524
5e29c264 1525 /* Normal frame hooks. */
94afd7a6 1526 dwarf2_append_unwinders (gdbarch);
27fd2f50 1527 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
94afd7a6 1528 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
27fd2f50
Q
1529 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1530
1531 return gdbarch;
1532}
1533
1534extern initialize_file_ftype _initialize_score_tdep;
1535
1536void
1537_initialize_score_tdep (void)
1538{
1539 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1540}
This page took 2.458221 seconds and 4 git commands to generate.