* dwarf2-frame.c (dwarf2_frame_cache, dwarf2_frame_this_id)
[external/binutils.git] / gdb / score-tdep.c
1 /* Target-dependent code for the S+core architecture, for GDB,
2    the GNU Debugger.
3
4    Copyright (C) 2006, 2007 Free Software Foundation, Inc.
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
45 typedef struct{
46     unsigned int v;
47     unsigned int raw;
48     char         is15;
49 }inst_t;
50
51 struct 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
75 typedef struct frame_extra_info
76 {
77   CORE_ADDR p_frame;
78   unsigned int pdr[P_SIZE];
79 } extra_info_t;
80
81 struct obj_priv
82 {
83   bfd_size_type size;
84   char *contents;
85 };
86
87 static bfd *the_bfd;
88
89 static int
90 score_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
102 static void
103 score_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
186 static struct type *
187 score_register_type (struct gdbarch *gdbarch, int regnum)
188 {
189   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
190   return builtin_type_uint32;
191 }
192
193 static LONGEST
194 score_read_unsigned_register (int regnum)
195 {
196   LONGEST val;
197   regcache_cooked_read_unsigned (current_regcache, regnum, &val);
198   return val;
199 }
200
201 static CORE_ADDR
202 score_read_sp (void)
203 {
204   return score_read_unsigned_register (SCORE_SP_REGNUM);
205 }
206
207 static CORE_ADDR
208 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
209 {
210   return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
211 }
212
213 static const char *
214 score_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
234 static int
235 score_register_sim_regno (int regnum)
236 {
237   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
238   return regnum;
239 }
240
241 static int
242 score_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
250 static const gdb_byte *
251 score_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
303 static CORE_ADDR
304 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
305 {
306   return align_down (addr, 16);
307 }
308
309 static void
310 score_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
340 static enum return_value_convention
341 score_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
367 static struct frame_id
368 score_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
375 static int
376 score_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
397 static CORE_ADDR
398 score_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       enum type_code typecode = TYPE_CODE (arg_type);
438       const gdb_byte *val = value_contents (arg);
439       int downward_offset = 0;
440       int odd_sized_struct_p;
441       int arg_last_part_p = 0;
442
443       arglen = TYPE_LENGTH (arg_type);
444       odd_sized_struct_p = (arglen > SCORE_REGSIZE
445                                 && arglen % SCORE_REGSIZE != 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
513 static inst_t *
514 score_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
542 static CORE_ADDR
543 score_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
591 static int
592 score_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
615 static void
616 score_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
769 static struct score_frame_cache *
770 score_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
798 static void
799 score_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,
805                                frame_func_unwind (next_frame, NORMAL_FRAME));
806 }
807
808 static void
809 score_prologue_prev_register (struct frame_info *next_frame,
810                               void **this_cache,
811                               int regnum, int *optimizedp,
812                               enum lval_type *lvalp, CORE_ADDR * addrp,
813                               int *realnump, gdb_byte * valuep)
814 {
815   struct score_frame_cache *info = score_make_prologue_cache (next_frame,
816                                                               this_cache);
817   trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
818                                 optimizedp, lvalp, addrp, realnump, valuep);
819 }
820
821 static const struct frame_unwind score_prologue_unwind =
822 {
823   NORMAL_FRAME,
824   score_prologue_this_id,
825   score_prologue_prev_register
826 };
827
828 static const struct frame_unwind *
829 score_prologue_sniffer (struct frame_info *next_frame)
830 {
831   return &score_prologue_unwind;
832 }
833
834 static CORE_ADDR
835 score_prologue_frame_base_address (struct frame_info *next_frame,
836                                    void **this_cache)
837 {
838   struct score_frame_cache *info =
839     score_make_prologue_cache (next_frame, this_cache);
840   return info->base;
841 }
842
843 static const struct frame_base score_prologue_frame_base =
844 {
845   &score_prologue_unwind,
846   score_prologue_frame_base_address,
847   score_prologue_frame_base_address,
848   score_prologue_frame_base_address,
849 };
850
851 static const struct frame_base *
852 score_prologue_frame_base_sniffer (struct frame_info *next_frame)
853 {
854   return &score_prologue_frame_base;
855 }
856
857 static struct gdbarch *
858 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
859 {
860   struct gdbarch *gdbarch;
861
862   arches = gdbarch_list_lookup_by_info (arches, &info);
863   if (arches != NULL)
864     {
865       return (arches->gdbarch);
866     }
867   gdbarch = gdbarch_alloc (&info, 0);
868
869   set_gdbarch_short_bit (gdbarch, 16);
870   set_gdbarch_int_bit (gdbarch, 32);
871   set_gdbarch_float_bit (gdbarch, 32);
872   set_gdbarch_double_bit (gdbarch, 64);
873   set_gdbarch_long_double_bit (gdbarch, 64);
874   set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
875   set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
876   set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
877   set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
878   set_gdbarch_register_name (gdbarch, score_register_name);
879   set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
880   set_gdbarch_register_type (gdbarch, score_register_type);
881   set_gdbarch_frame_align (gdbarch, score_frame_align);
882   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
883   set_gdbarch_read_sp (gdbarch, score_read_sp);
884   set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
885   set_gdbarch_print_insn (gdbarch, score_print_insn);
886   set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
887   set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
888   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
889   set_gdbarch_return_value (gdbarch, score_return_value);
890   set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
891   set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
892
893   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
894   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
895   frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
896   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
897
898   return gdbarch;
899 }
900
901 extern initialize_file_ftype _initialize_score_tdep;
902
903 void
904 _initialize_score_tdep (void)
905 {
906   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
907 }