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