2007-01-04 Qinwei <qinwei@sunnorth.com.cn>
[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
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
46 typedef struct{
47     unsigned int v;
48     unsigned int raw;
49     char         is15;
50 }inst_t;
51
52 struct 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
76 typedef struct frame_extra_info
77 {
78   CORE_ADDR p_frame;
79   unsigned int pdr[P_SIZE];
80 } extra_info_t;
81
82 struct obj_priv
83 {
84   bfd_size_type size;
85   char *contents;
86 };
87
88 static bfd *the_bfd;
89
90 static int
91 score_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
103 static void
104 score_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
187 static struct type *
188 score_register_type (struct gdbarch *gdbarch, int regnum)
189 {
190   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
191   return builtin_type_uint32;
192 }
193
194 static LONGEST
195 score_read_unsigned_register (int regnum)
196 {
197   LONGEST val;
198   regcache_cooked_read_unsigned (current_regcache, regnum, &val);
199   return val;
200 }
201
202 static CORE_ADDR
203 score_read_sp (void)
204 {
205   return score_read_unsigned_register (SCORE_SP_REGNUM);
206 }
207
208 static CORE_ADDR
209 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
210 {
211   return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
212 }
213
214 static const char *
215 score_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
235 static int
236 score_register_sim_regno (int regnum)
237 {
238   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
239   return regnum;
240 }
241
242 static int
243 score_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
251 static const gdb_byte *
252 score_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
304 static CORE_ADDR
305 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
306 {
307   return align_down (addr, 16);
308 }
309
310 static void
311 score_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
341 static enum return_value_convention
342 score_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
368 static struct frame_id
369 score_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
376 static int
377 score_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
398 static CORE_ADDR
399 score_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
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, frame_func_unwind (next_frame));
805 }
806
807 static void
808 score_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
820 static const struct frame_unwind score_prologue_unwind =
821 {
822   NORMAL_FRAME,
823   score_prologue_this_id,
824   score_prologue_prev_register
825 };
826
827 static const struct frame_unwind *
828 score_prologue_sniffer (struct frame_info *next_frame)
829 {
830   return &score_prologue_unwind;
831 }
832
833 static CORE_ADDR
834 score_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
842 static 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
850 static const struct frame_base *
851 score_prologue_frame_base_sniffer (struct frame_info *next_frame)
852 {
853   return &score_prologue_frame_base;
854 }
855
856 static struct gdbarch *
857 score_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
900 extern initialize_file_ftype _initialize_score_tdep;
901
902 void
903 _initialize_score_tdep (void)
904 {
905   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
906 }