]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/score-tdep.c
Copyright updates for 2007.
[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
6aba47ca 4 Copyright (C) 2006, 2007 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
13 the Free Software Foundation; either version 2 of the License, or
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
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 Boston, MA 02110-1301, USA. */
25
26#include "defs.h"
27#include "gdb_assert.h"
28#include "inferior.h"
29#include "symtab.h"
30#include "objfiles.h"
31#include "gdbcore.h"
32#include "target.h"
33#include "arch-utils.h"
34#include "regcache.h"
35#include "dis-asm.h"
36#include "frame-unwind.h"
37#include "frame-base.h"
38#include "trad-frame.h"
39#include "dwarf2-frame.h"
40#include "score-tdep.h"
41
42#define G_FLD(_i,_ms,_ls) (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
43#define RM_PBITS(_raw) ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0))
44
45typedef struct{
46 unsigned int v;
47 unsigned int raw;
48 char is15;
49}inst_t;
50
51struct score_frame_cache
52{
53 CORE_ADDR base;
54 struct trad_frame_saved_reg *saved_regs;
55};
56
57#if 0
58/* If S+core GCC will generate these instructions in the prologue:
59
60 lw rx, imm1
61 addi rx, -imm2
62 mv! r2, rx
63
64 then .pdr section is used. */
65
66#define P_SIZE 8
67#define PI_SYM 0
68#define PI_R_MSK 1
69#define PI_R_OFF 2
70#define PI_R_LEF 4
71#define PI_F_OFF 5
72#define PI_F_REG 6
73#define PI_RAREG 7
74
75typedef struct frame_extra_info
76{
77 CORE_ADDR p_frame;
78 unsigned int pdr[P_SIZE];
79} extra_info_t;
80
81struct obj_priv
82{
83 bfd_size_type size;
84 char *contents;
85};
86
87static bfd *the_bfd;
88
89static int
90score_compare_pdr_entries (const void *a, const void *b)
91{
92 CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a);
93 CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b);
94 if (lhs < rhs)
95 return -1;
96 else if (lhs == rhs)
97 return 0;
98 else
99 return 1;
100}
101
102static void
103score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc,
104 struct frame_info *next_frame,
105 struct score_frame_cache *this_cache)
106{
107 struct symbol *sym;
108 struct obj_section *sec;
109 extra_info_t *fci_ext;
110 CORE_ADDR leaf_ra_stack_addr = -1;
111
112 gdb_assert (startaddr <= pc);
113 gdb_assert (this_cache != NULL);
114
115 fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
116 if ((sec = find_pc_section (pc)) == NULL)
117 {
118 error ("Can't find section in file:%s, line:%d!", __FILE__, __LINE__);
119 return;
120 }
121
122 /* Anylyze .pdr section and get coresponding fields. */
123 {
124 static struct obj_priv *priv = NULL;
125
126 if (priv == NULL)
127 {
128 asection *bfdsec;
129 priv = obstack_alloc (&sec->objfile->objfile_obstack,
130 sizeof (struct obj_priv));
131 if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr")))
132 {
133 priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
134 priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
135 priv->size);
136 bfd_get_section_contents (sec->objfile->obfd, bfdsec,
137 priv->contents, 0, priv->size);
138 the_bfd = sec->objfile->obfd;
139 qsort (priv->contents, priv->size / 32, 32,
140 score_compare_pdr_entries);
141 the_bfd = NULL;
142 }
143 else
144 priv->size = 0;
145 }
146 if (priv->size != 0)
147 {
148 int low = 0, mid, high = priv->size / 32;
149 char *ptr;
150 do
151
152 {
153 CORE_ADDR pdr_pc;
154 mid = (low + high) / 2;
155 ptr = priv->contents + mid * 32;
156 pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
157 pdr_pc += ANOFFSET (sec->objfile->section_offsets,
158 SECT_OFF_TEXT (sec->objfile));
159 if (pdr_pc == startaddr)
160 break;
161 if (pdr_pc > startaddr)
162 high = mid;
163 else
164 low = mid + 1;
165 }
166 while (low != high);
167
168 if (low != high)
169 {
170 gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr);
171#define EXT_PDR(_pi) bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2))
172 fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM);
173 fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK);
174 fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF);
175 fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF);
176 fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF);
177 fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG);
178 fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG);
179#undef EXT_PDR
180 }
181 }
182 }
183}
184#endif
185
186static struct type *
187score_register_type (struct gdbarch *gdbarch, int regnum)
188{
189 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
190 return builtin_type_uint32;
191}
192
193static LONGEST
194score_read_unsigned_register (int regnum)
195{
196 LONGEST val;
197 regcache_cooked_read_unsigned (current_regcache, regnum, &val);
198 return val;
199}
200
201static CORE_ADDR
202score_read_sp (void)
203{
204 return score_read_unsigned_register (SCORE_SP_REGNUM);
205}
206
207static CORE_ADDR
208score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
209{
210 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
211}
212
213static const char *
214score_register_name (int regnum)
215{
216 const char *score_register_names[] = {
217 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
218 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
219 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
220 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
221
222 "PSR", "COND", "ECR", "EXCPVEC",
223 "CCR", "EPC", "EMA", "TLBLOCK",
224 "TLBPT", "PEADDR", "TLBRPT", "PEVN",
225 "PECTX", "LIMPFN", "LDMPFN", "PREV",
226 "DREG", "PC", "DSAVE", "COUNTER",
227 "LDCR", "STCR", "CEH", "CEL",
228 };
229
230 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
231 return score_register_names[regnum];
232}
233
234static int
235score_register_sim_regno (int regnum)
236{
237 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
238 return regnum;
239}
240
241static int
242score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
243{
244 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
245 return print_insn_big_score (memaddr, info);
246 else
247 return print_insn_little_score (memaddr, info);
248}
249
250static const gdb_byte *
251score_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
252{
253 gdb_byte buf[SCORE_INSTLEN] = { 0 };
254 int ret;
255 unsigned int raw;
256
257 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
258 {
259 memory_error (ret, *pcptr);
260 }
261 raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
262
263 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
264 {
265 if (!(raw & 0x80008000))
266 {
267 /* 16bits instruction. */
268 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
269 *pcptr &= ~0x1;
270 *lenptr = sizeof (big_breakpoint16);
271 return big_breakpoint16;
272 }
273 else
274 {
275 /* 32bits instruction. */
276 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
277 *pcptr &= ~0x3;
278 *lenptr = sizeof (big_breakpoint32);
279 return big_breakpoint32;
280 }
281 }
282 else
283 {
284 if (!(raw & 0x80008000))
285 {
286 /* 16bits instruction. */
287 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
288 *pcptr &= ~0x1;
289 *lenptr = sizeof (little_breakpoint16);
290 return little_breakpoint16;
291 }
292 else
293 {
294 /* 32bits instruction. */
295 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
296 *pcptr &= ~0x3;
297 *lenptr = sizeof (little_breakpoint32);
298 return little_breakpoint32;
299 }
300 }
301}
302
303static CORE_ADDR
304score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
305{
306 return align_down (addr, 16);
307}
308
309static void
310score_xfer_register (struct regcache *regcache, int regnum, int length,
311 enum bfd_endian endian, gdb_byte *readbuf,
312 const gdb_byte *writebuf, int buf_offset)
313{
314 int reg_offset = 0;
315 gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
316
317 switch (endian)
318 {
319 case BFD_ENDIAN_BIG:
320 reg_offset = SCORE_REGSIZE - length;
321 break;
322 case BFD_ENDIAN_LITTLE:
323 reg_offset = 0;
324 break;
325 case BFD_ENDIAN_UNKNOWN:
326 reg_offset = 0;
327 break;
328 default:
329 internal_error (__FILE__, __LINE__, _("score_xfer_register error!"));
330 }
331
332 if (readbuf != NULL)
333 regcache_cooked_read_part (regcache, regnum, reg_offset, length,
334 readbuf + buf_offset);
335 if (writebuf != NULL)
336 regcache_cooked_write_part (regcache, regnum, reg_offset, length,
337 writebuf + buf_offset);
338}
339
340static enum return_value_convention
341score_return_value (struct gdbarch *gdbarch, struct type *type,
342 struct regcache *regcache,
343 gdb_byte * readbuf, const gdb_byte * writebuf)
344{
345 if (TYPE_CODE (type) == TYPE_CODE_STRUCT
346 || TYPE_CODE (type) == TYPE_CODE_UNION
347 || TYPE_CODE (type) == TYPE_CODE_ARRAY)
348 return RETURN_VALUE_STRUCT_CONVENTION;
349 else
350 {
351 int offset;
352 int regnum;
353 for (offset = 0, regnum = SCORE_A0_REGNUM;
354 offset < TYPE_LENGTH (type);
355 offset += SCORE_REGSIZE, regnum++)
356 {
357 int xfer = SCORE_REGSIZE;
358 if (offset + xfer > TYPE_LENGTH (type))
359 xfer = TYPE_LENGTH (type) - offset;
360 score_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
361 readbuf, writebuf, offset);
362 }
363 return RETURN_VALUE_REGISTER_CONVENTION;
364 }
365}
366
367static struct frame_id
368score_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
369{
370 return frame_id_build (
371 frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
372 frame_pc_unwind (next_frame));
373}
374
375static int
376score_type_needs_double_align (struct type *type)
377{
378 enum type_code typecode = TYPE_CODE (type);
379
380 if (typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
381 return 1;
382 if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
383 return 1;
384 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
385 {
386 int i, n;
387
388 n = TYPE_NFIELDS (type);
389 for (i = 0; i < n; i++)
390 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
391 return 1;
392 return 0;
393 }
394 return 0;
395}
396
397static CORE_ADDR
398score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
399 struct regcache *regcache, CORE_ADDR bp_addr,
400 int nargs, struct value **args, CORE_ADDR sp,
401 int struct_return, CORE_ADDR struct_addr)
402{
403 int argnum;
404 int argreg;
405 int arglen = 0;
406 CORE_ADDR stack_offset = 0;
407 CORE_ADDR addr = 0;
408
409 /* Step 1, Save RA. */
410 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
411
412 /* Step 2, Make space on the stack for the args. */
413 struct_addr = align_down (struct_addr, 16);
414 sp = align_down (sp, 16);
415 for (argnum = 0; argnum < nargs; argnum++)
416 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
417 SCORE_REGSIZE);
418 sp -= align_up (arglen, 16);
419
420 argreg = SCORE_BEGIN_ARG_REGNUM;
421
422 /* Step 3, Check if struct return then save the struct address to r4 and
423 increase the stack_offset by 4. */
424 if (struct_return)
425 {
426 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
427 stack_offset += SCORE_REGSIZE;
428 }
429
430 /* Step 4, Load arguments:
431 If arg length is too long (> 4 bytes),
432 then split the arg and save every parts. */
433 for (argnum = 0; argnum < nargs; argnum++)
434 {
435 struct value *arg = args[argnum];
436 struct type *arg_type = check_typedef (value_type (arg));
437 arglen = TYPE_LENGTH (arg_type);
438 enum type_code typecode = TYPE_CODE (arg_type);
439 const gdb_byte *val = value_contents (arg);
440 int downward_offset = 0;
441
442 int odd_sized_struct_p = (arglen > SCORE_REGSIZE
443 && arglen % SCORE_REGSIZE != 0);
444 int arg_last_part_p = 0;
445
446 /* If a arg should be aligned to 8 bytes (long long or double),
447 the value should be put to even register numbers. */
448 if (score_type_needs_double_align (arg_type))
449 {
450 if (argreg & 1)
451 argreg++;
452 }
453
454 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
455 the default "downward"/"upward" method:
456
457 Example:
458
459 struct struc
460 {
461 char a; char b; char c;
462 } s = {'a', 'b', 'c'};
463
464 Big endian: s = {X, 'a', 'b', 'c'}
465 Little endian: s = {'a', 'b', 'c', X}
466
467 Where X is a hole. */
468
469 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
470 && (typecode == TYPE_CODE_STRUCT
471 || typecode == TYPE_CODE_UNION)
472 && argreg > SCORE_LAST_ARG_REGNUM
473 && arglen < SCORE_REGSIZE)
474 downward_offset += (SCORE_REGSIZE - arglen);
475
476 while (arglen > 0)
477 {
478 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
479 ULONGEST regval = extract_unsigned_integer (val, partial_len);
480
481 /* The last part of a arg should shift left when
482 TARGET_BYTE_ORDER is BFD_ENDIAN_BIG. */
483 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
484 && arg_last_part_p == 1
485 && (typecode == TYPE_CODE_STRUCT
486 || typecode == TYPE_CODE_UNION))
487 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
488
489 /* Always increase the stack_offset and save args to stack. */
490 addr = sp + stack_offset + downward_offset;
491 write_memory (addr, val, partial_len);
492
493 if (argreg <= SCORE_LAST_ARG_REGNUM)
494 {
495 regcache_cooked_write_unsigned (regcache, argreg++, regval);
496 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
497 arg_last_part_p = 1;
498 }
499
500 val += partial_len;
501 arglen -= partial_len;
502 stack_offset += align_up (partial_len, SCORE_REGSIZE);
503 }
504 }
505
506 /* Step 5, Save SP. */
507 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
508
509 return sp;
510}
511
512static inst_t *
513score_fetch_instruction (CORE_ADDR addr)
514{
515 static inst_t inst = { 0, 0 };
516 char buf[SCORE_INSTLEN];
517 int big;
518 int ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
519 unsigned int raw;
520
521 if (ret)
522 {
523 memory_error (ret, addr);
524 return 0;
525 }
526 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
527 inst.is15 = !(inst.raw & 0x80008000);
528 inst.v = RM_PBITS (inst.raw);
529 big = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
530
531 if (inst.is15)
532 {
533 if (big ^ ((addr & 0x2) == 2))
534 inst.v = G_FLD (inst.v, 29, 15);
535 else
536 inst.v = G_FLD (inst.v, 14, 0);
537 }
538 return &inst;
539}
540
541static CORE_ADDR
542score_skip_prologue (CORE_ADDR pc)
543{
544 CORE_ADDR cpc = pc;
545 int iscan = 32, stack_sub = 0;
546 while (iscan-- > 0)
547 {
548 inst_t *inst = score_fetch_instruction (cpc);
549 if (!inst)
550 break;
551 if (!inst->is15 && !stack_sub
552 && (G_FLD (inst->v, 29, 25) == 0x1
553 && G_FLD (inst->v, 24, 20) == 0x0))
554 {
555 /* addi r0, offset */
556 pc = stack_sub = cpc + SCORE_INSTLEN;
557 }
558 else if (!inst->is15
559 && inst->v == RM_PBITS (0x8040bc56))
560 {
561 /* mv r2, r0 */
562 pc = cpc + SCORE_INSTLEN;
563 break;
564 }
565 else if (inst->is15
566 && inst->v == RM_PBITS (0x0203))
567 {
568 /* mv! r2, r0 */
569 pc = cpc + SCORE16_INSTLEN;
570 break;
571 }
572 else if (inst->is15
573 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */
574 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
575 || (G_FLD (inst->v, 14, 12) == 0x0
576 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
577 break;
578 else if (!inst->is15
579 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
580 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
581 || (G_FLD (inst->v, 29, 25) == 0x0
582 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */
583 break;
584
585 cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
586 }
587 return pc;
588}
589
590static int
591score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
592{
593 inst_t *inst = score_fetch_instruction (cur_pc);
594
595 if (inst->v == 0x23)
596 return 1; /* mv! r0, r2 */
597 else if (G_FLD (inst->v, 14, 12) == 0x2
598 && G_FLD (inst->v, 3, 0) == 0xa)
599 return 1; /* pop! */
600 else if (G_FLD (inst->v, 14, 12) == 0x0
601 && G_FLD (inst->v, 7, 0) == 0x34)
602 return 1; /* br! r3 */
603 else if (G_FLD (inst->v, 29, 15) == 0x2
604 && G_FLD (inst->v, 6, 1) == 0x2b)
605 return 1; /* mv r0, r2 */
606 else if (G_FLD (inst->v, 29, 25) == 0x0
607 && G_FLD (inst->v, 6, 1) == 0x4
608 && G_FLD (inst->v, 19, 15) == 0x3)
609 return 1; /* br r3 */
610 else
611 return 0;
612}
613
614static void
615score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
616 struct frame_info *next_frame,
617 struct score_frame_cache *this_cache)
618{
619 CORE_ADDR sp;
620 CORE_ADDR cur_pc = startaddr;
621
622 int sp_offset = 0;
623 int ra_offset = 0;
624 int fp_offset = 0;
625 int ra_offset_p = 0;
626 int fp_offset_p = 0;
627 int inst_len = 0;
628
629 sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
630
631 for (; cur_pc < pc; cur_pc += inst_len)
632 {
633 inst_t *inst = score_fetch_instruction (cur_pc);
634 if (inst->is15 == 1)
635 {
636 inst_len = SCORE16_INSTLEN;
637
638 if (G_FLD (inst->v, 14, 12) == 0x2
639 && G_FLD (inst->v, 3, 0) == 0xe)
640 {
641 /* push! */
642 sp_offset += 4;
643
644 if (G_FLD (inst->v, 11, 7) == 0x6
645 && ra_offset_p == 0)
646 {
647 /* push! r3, [r0] */
648 ra_offset = sp_offset;
649 ra_offset_p = 1;
650 }
651 else if (G_FLD (inst->v, 11, 7) == 0x4
652 && fp_offset_p == 0)
653 {
654 /* push! r2, [r0] */
655 fp_offset = sp_offset;
656 fp_offset_p = 1;
657 }
658 }
659 else if (G_FLD (inst->v, 14, 12) == 0x2
660 && G_FLD (inst->v, 3, 0) == 0xa)
661 {
662 /* pop! */
663 sp_offset -= 4;
664 }
665 else if (G_FLD (inst->v, 14, 7) == 0xc1
666 && G_FLD (inst->v, 2, 0) == 0x0)
667 {
668 /* subei! r0, n */
669 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
670 }
671 else if (G_FLD (inst->v, 14, 7) == 0xc0
672 && G_FLD (inst->v, 2, 0) == 0x0)
673 {
674 /* addei! r0, n */
675 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
676 }
677 }
678 else
679 {
680 inst_len = SCORE_INSTLEN;
681
682 if (G_FLD (inst->v, 29, 15) == 0xc60
683 && G_FLD (inst->v, 2, 0) == 0x4)
684 {
685 /* sw r3, [r0, offset]+ */
686 sp_offset += SCORE_INSTLEN;
687 if (ra_offset_p == 0)
688 {
689 ra_offset = sp_offset;
690 ra_offset_p = 1;
691 }
692 }
693 if (G_FLD (inst->v, 29, 15) == 0xc40
694 && G_FLD (inst->v, 2, 0) == 0x4)
695 {
696 /* sw r2, [r0, offset]+ */
697 sp_offset += SCORE_INSTLEN;
698 if (fp_offset_p == 0)
699 {
700 fp_offset = sp_offset;
701 fp_offset_p = 1;
702 }
703 }
704 else if (G_FLD (inst->v, 29, 15) == 0x1c60
705 && G_FLD (inst->v, 2, 0) == 0x0)
706 {
707 /* lw r3, [r0]+, 4 */
708 sp_offset -= SCORE_INSTLEN;
709 ra_offset_p = 1;
710 }
711 else if (G_FLD (inst->v, 29, 15) == 0x1c40
712 && G_FLD (inst->v, 2, 0) == 0x0)
713 {
714 /* lw r2, [r0]+, 4 */
715 sp_offset -= SCORE_INSTLEN;
716 fp_offset_p = 1;
717 }
718
719 else if (G_FLD (inst->v, 29, 17) == 0x100
720 && G_FLD (inst->v, 0, 0) == 0x0)
721 {
722 /* addi r0, -offset */
723 sp_offset += 65536 - G_FLD (inst->v, 16, 1);
724 }
725 else if (G_FLD (inst->v, 29, 17) == 0x110
726 && G_FLD (inst->v, 0, 0) == 0x0)
727 {
728 /* addi r2, offset */
729 if (pc - cur_pc > 4)
730 {
731 unsigned int save_v = inst->v;
732 inst_t *inst2 =
733 score_fetch_instruction (cur_pc + SCORE_INSTLEN);
734 if (inst2->v == 0x23)
735 /* mv! r0, r2 */
736 sp_offset -= G_FLD (save_v, 16, 1);
737 }
738 }
739 }
740 }
741
742 /* Save RA. */
743 if (ra_offset_p == 1)
744 {
745 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
746 this_cache->saved_regs[SCORE_PC_REGNUM].addr =
747 sp + sp_offset - ra_offset;
748 }
749 else
750 {
751 this_cache->saved_regs[SCORE_PC_REGNUM] =
752 this_cache->saved_regs[SCORE_RA_REGNUM];
753 }
754
755 /* Save FP. */
756 if (fp_offset_p == 1)
757 {
758 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
759 this_cache->saved_regs[SCORE_FP_REGNUM].addr =
760 sp + sp_offset - fp_offset;
761 }
762
763 /* Save SP. */
764 this_cache->base =
765 frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM) + sp_offset;
766}
767
768static struct score_frame_cache *
769score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
770{
771 struct score_frame_cache *cache;
772
773 if ((*this_cache) != NULL)
774 return (*this_cache);
775
776 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
777 (*this_cache) = cache;
778 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
779
780 /* Analyze the prologue. */
781 {
782 const CORE_ADDR pc = frame_pc_unwind (next_frame);
783 CORE_ADDR start_addr;
784
785 find_pc_partial_function (pc, NULL, &start_addr, NULL);
786 if (start_addr == 0)
787 return cache;
788 score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
789 }
790
791 /* Save SP. */
792 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
793
794 return (*this_cache);
795}
796
797static void
798score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
799 struct frame_id *this_id)
800{
801 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
802 this_cache);
803 (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame));
804}
805
806static void
807score_prologue_prev_register (struct frame_info *next_frame,
808 void **this_cache,
809 int regnum, int *optimizedp,
810 enum lval_type *lvalp, CORE_ADDR * addrp,
811 int *realnump, gdb_byte * valuep)
812{
813 struct score_frame_cache *info = score_make_prologue_cache (next_frame,
814 this_cache);
815 trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
816 optimizedp, lvalp, addrp, realnump, valuep);
817}
818
819static const struct frame_unwind score_prologue_unwind =
820{
821 NORMAL_FRAME,
822 score_prologue_this_id,
823 score_prologue_prev_register
824};
825
826static const struct frame_unwind *
827score_prologue_sniffer (struct frame_info *next_frame)
828{
829 return &score_prologue_unwind;
830}
831
832static CORE_ADDR
833score_prologue_frame_base_address (struct frame_info *next_frame,
834 void **this_cache)
835{
836 struct score_frame_cache *info =
837 score_make_prologue_cache (next_frame, this_cache);
838 return info->base;
839}
840
841static const struct frame_base score_prologue_frame_base =
842{
843 &score_prologue_unwind,
844 score_prologue_frame_base_address,
845 score_prologue_frame_base_address,
846 score_prologue_frame_base_address,
847};
848
849static const struct frame_base *
850score_prologue_frame_base_sniffer (struct frame_info *next_frame)
851{
852 return &score_prologue_frame_base;
853}
854
855static struct gdbarch *
856score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
857{
858 struct gdbarch *gdbarch;
859
860 arches = gdbarch_list_lookup_by_info (arches, &info);
861 if (arches != NULL)
862 {
863 return (arches->gdbarch);
864 }
865 gdbarch = gdbarch_alloc (&info, 0);
866
867 set_gdbarch_short_bit (gdbarch, 16);
868 set_gdbarch_int_bit (gdbarch, 32);
869 set_gdbarch_float_bit (gdbarch, 32);
870 set_gdbarch_double_bit (gdbarch, 64);
871 set_gdbarch_long_double_bit (gdbarch, 64);
872 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
873 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
874 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
875 set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
876 set_gdbarch_register_name (gdbarch, score_register_name);
877 set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
878 set_gdbarch_register_type (gdbarch, score_register_type);
879 set_gdbarch_frame_align (gdbarch, score_frame_align);
880 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
881 set_gdbarch_read_sp (gdbarch, score_read_sp);
882 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
883 set_gdbarch_print_insn (gdbarch, score_print_insn);
884 set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
885 set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
886 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
887 set_gdbarch_return_value (gdbarch, score_return_value);
888 set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
889 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
890
891 frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
892 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
893 frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
894 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
895
896 return gdbarch;
897}
898
899extern initialize_file_ftype _initialize_score_tdep;
900
901void
902_initialize_score_tdep (void)
903{
904 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
905}