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