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