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