2007-05-17 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, 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   CORE_ADDR fp;
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 ("Error: Can't find section in file:%s, line:%d!",
120              __FILE__, __LINE__);
121       return;
122     }
123
124   /* Anylyze .pdr section and get coresponding fields.  */
125   {
126     static struct obj_priv *priv = NULL;
127
128     if (priv == NULL)
129       {
130         asection *bfdsec;
131         priv = obstack_alloc (&sec->objfile->objfile_obstack,
132                               sizeof (struct obj_priv));
133         if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr")))
134           {
135             priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
136             priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
137                                             priv->size);
138             bfd_get_section_contents (sec->objfile->obfd, bfdsec,
139                                       priv->contents, 0, priv->size);
140             the_bfd = sec->objfile->obfd;
141             qsort (priv->contents, priv->size / 32, 32,
142                    score_compare_pdr_entries);
143             the_bfd = NULL;
144           }
145         else
146           priv->size = 0;
147       }
148     if (priv->size != 0)
149       {
150         int low = 0, mid, high = priv->size / 32;
151         char *ptr;
152         do
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 #if 0
188 /* Open these functions if build with simulator.  */
189
190 int
191 score_target_can_use_watch (int type, int cnt, int othertype)
192 {
193   if (strcmp (current_target.to_shortname, "sim") == 0)
194     {      
195       return soc_gh_can_use_watch (type, cnt);
196     }
197   else
198     {
199       return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
200     }
201 }
202
203 int
204 score_stopped_by_watch (void)
205 {
206   if (strcmp (current_target.to_shortname, "sim") == 0)
207     {      
208       return soc_gh_stopped_by_watch ();
209     }
210   else
211     {
212       return (*current_target.to_stopped_by_watchpoint) ();
213     }
214 }
215
216 int
217 score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
218 {
219   if (strcmp (current_target.to_shortname, "sim") == 0)
220     {      
221       return soc_gh_add_watch (addr, len, type);
222     }
223   else
224     {
225       return (*current_target.to_insert_watchpoint) (addr, len, type); 
226     }
227 }
228
229 int
230 score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
231 {
232   if (strcmp (current_target.to_shortname, "sim") == 0)
233     {      
234       return soc_gh_del_watch (addr, len, type);
235     }
236   else
237     {
238       return (*current_target.to_remove_watchpoint) (addr, len, type); 
239     }
240 }
241
242 int
243 score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt)
244 {
245   if (strcmp (current_target.to_shortname, "sim") == 0)
246     {      
247       return soc_gh_add_hardbp (bp_tgt->placed_address);
248     }
249   else
250     {
251       return (*current_target.to_insert_hw_breakpoint) (bp_tgt); 
252     }
253 }
254
255 int
256 score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt)
257 {
258   if (strcmp (current_target.to_shortname, "sim") == 0)
259     {      
260       return soc_gh_del_hardbp (bp_tgt->placed_address);
261     }
262   else
263     {
264       return (*current_target.to_remove_hw_breakpoint) (bp_tgt); 
265     }
266 }
267 #endif
268
269 static struct type *
270 score_register_type (struct gdbarch *gdbarch, int regnum)
271 {
272   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
273   return builtin_type_uint32;
274 }
275
276 static CORE_ADDR
277 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
278 {
279   return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
280 }
281
282 static CORE_ADDR
283 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
284 {
285   return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
286 }
287
288 static const char *
289 score_register_name (int regnum)
290 {
291   const char *score_register_names[] = {
292     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
293     "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
294     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
295     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
296
297     "PSR",   "COND",   "ECR",    "EXCPVEC",
298     "CCR",   "EPC",    "EMA",    "TLBLOCK",
299     "TLBPT", "PEADDR", "TLBRPT", "PEVN",
300     "PECTX", "LIMPFN", "LDMPFN", "PREV",
301     "DREG",  "PC",     "DSAVE",  "COUNTER",
302     "LDCR",  "STCR",   "CEH",    "CEL",
303   };
304
305   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
306   return score_register_names[regnum];
307 }
308
309 static int
310 score_register_sim_regno (int regnum)
311 {
312   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
313   return regnum;
314 }
315
316 static int
317 score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
318 {
319   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
320     return print_insn_big_score (memaddr, info);
321   else
322     return print_insn_little_score (memaddr, info);
323 }
324
325 static const gdb_byte *
326 score_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
327 {
328   gdb_byte buf[SCORE_INSTLEN] = { 0 };
329   int ret;
330   unsigned int raw;
331
332   if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
333     {
334       error ("Error: target_read_memory in file:%s, line:%d!",
335              __FILE__, __LINE__);
336     }
337   raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
338
339   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
340     {
341       if (!(raw & 0x80008000))
342         {
343           /* 16bits instruction.  */
344           static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
345           *pcptr &= ~0x1;
346           *lenptr = sizeof (big_breakpoint16);
347           return big_breakpoint16;
348         }
349       else
350         {
351           /* 32bits instruction.  */
352           static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
353           *pcptr &= ~0x3;
354           *lenptr = sizeof (big_breakpoint32);
355           return big_breakpoint32;
356         }
357     }
358   else
359     {
360       if (!(raw & 0x80008000))
361         {
362           /* 16bits instruction.  */
363           static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
364           *pcptr &= ~0x1;
365           *lenptr = sizeof (little_breakpoint16);
366           return little_breakpoint16;
367         }
368       else
369         {
370           /* 32bits instruction.  */
371           static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
372           *pcptr &= ~0x3;
373           *lenptr = sizeof (little_breakpoint32);
374           return little_breakpoint32;
375         }
376     }
377 }
378
379 static CORE_ADDR
380 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
381 {
382   return align_down (addr, 16);
383 }
384
385 static void
386 score_xfer_register (struct regcache *regcache, int regnum, int length,
387                      enum bfd_endian endian, gdb_byte *readbuf,
388                      const gdb_byte *writebuf, int buf_offset)
389 {
390   int reg_offset = 0;
391   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
392
393   switch (endian)
394     {
395     case BFD_ENDIAN_BIG:
396       reg_offset = SCORE_REGSIZE - length;
397       break;
398     case BFD_ENDIAN_LITTLE:
399       reg_offset = 0;
400       break;
401     case BFD_ENDIAN_UNKNOWN:
402       reg_offset = 0;
403       break;
404     default:
405       error ("Error: score_xfer_register in file:%s, line:%d!",
406              __FILE__, __LINE__);
407     }
408
409   if (readbuf != NULL)
410     regcache_cooked_read_part (regcache, regnum, reg_offset, length,
411                                readbuf + buf_offset);
412   if (writebuf != NULL)
413     regcache_cooked_write_part (regcache, regnum, reg_offset, length,
414                                 writebuf + buf_offset);
415 }
416
417 static enum return_value_convention
418 score_return_value (struct gdbarch *gdbarch, struct type *type,
419                     struct regcache *regcache,
420                     gdb_byte * readbuf, const gdb_byte * writebuf)
421 {
422   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
423       || TYPE_CODE (type) == TYPE_CODE_UNION
424       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
425     return RETURN_VALUE_STRUCT_CONVENTION;
426   else
427     {
428       int offset;
429       int regnum;
430       for (offset = 0, regnum = SCORE_A0_REGNUM;
431            offset < TYPE_LENGTH (type);
432            offset += SCORE_REGSIZE, regnum++)
433         {
434           int xfer = SCORE_REGSIZE;
435           if (offset + xfer > TYPE_LENGTH (type))
436             xfer = TYPE_LENGTH (type) - offset;
437           score_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
438                                readbuf, writebuf, offset);
439         }
440       return RETURN_VALUE_REGISTER_CONVENTION;
441     }
442 }
443
444 static struct frame_id
445 score_unwind_dummy_id (struct gdbarch *gdbarch,
446                        struct frame_info *next_frame)
447 {
448   return frame_id_build (
449            frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
450            frame_pc_unwind (next_frame));
451 }
452
453 static int
454 score_type_needs_double_align (struct type *type)
455 {
456   enum type_code typecode = TYPE_CODE (type);
457
458   if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
459       || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
460     return 1;
461   else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
462     {
463       int i, n;
464
465       n = TYPE_NFIELDS (type);
466       for (i = 0; i < n; i++)
467         if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
468           return 1;
469       return 0;
470     }
471   return 0;
472 }
473
474 static CORE_ADDR
475 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
476                        struct regcache *regcache, CORE_ADDR bp_addr,
477                        int nargs, struct value **args, CORE_ADDR sp,
478                        int struct_return, CORE_ADDR struct_addr)
479 {
480   int argnum;
481   int argreg;
482   int arglen = 0;
483   CORE_ADDR stack_offset = 0;
484   CORE_ADDR addr = 0;
485
486   /* Step 1, Save RA.  */
487   regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
488
489   /* Step 2, Make space on the stack for the args.  */
490   struct_addr = align_down (struct_addr, 16);
491   sp = align_down (sp, 16);
492   for (argnum = 0; argnum < nargs; argnum++)
493     arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
494                         SCORE_REGSIZE);
495   sp -= align_up (arglen, 16);
496
497   argreg = SCORE_BEGIN_ARG_REGNUM;
498
499   /* Step 3, Check if struct return then save the struct address to
500      r4 and increase the stack_offset by 4.  */
501   if (struct_return)
502     {
503       regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
504       stack_offset += SCORE_REGSIZE;
505     }
506
507   /* Step 4, Load arguments:
508      If arg length is too long (> 4 bytes), then split the arg and
509      save every parts.  */
510   for (argnum = 0; argnum < nargs; argnum++)
511     {
512       struct value *arg = args[argnum];
513       struct type *arg_type = check_typedef (value_type (arg));
514       enum type_code typecode = TYPE_CODE (arg_type);
515       const gdb_byte *val = value_contents (arg);
516       int downward_offset = 0;
517       int odd_sized_struct_p;
518       int arg_last_part_p = 0;
519
520       arglen = TYPE_LENGTH (arg_type);
521       odd_sized_struct_p = (arglen > SCORE_REGSIZE
522                             && arglen % SCORE_REGSIZE != 0);
523
524       /* If a arg should be aligned to 8 bytes (long long or double),
525          the value should be put to even register numbers.  */
526       if (score_type_needs_double_align (arg_type))
527         {
528           if (argreg & 1)
529             argreg++;
530         }
531
532       /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
533          the default "downward"/"upward" method:
534
535          Example:
536
537          struct struc
538          {
539            char a; char b; char c;
540          } s = {'a', 'b', 'c'};
541
542          Big endian:    s = {X, 'a', 'b', 'c'}
543          Little endian: s = {'a', 'b', 'c', X}
544
545          Where X is a hole.  */
546
547       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
548           && (typecode == TYPE_CODE_STRUCT
549               || typecode == TYPE_CODE_UNION)
550           && argreg > SCORE_LAST_ARG_REGNUM
551           && arglen < SCORE_REGSIZE)
552         downward_offset += (SCORE_REGSIZE - arglen);
553
554       while (arglen > 0)
555         {
556           int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
557           ULONGEST regval = extract_unsigned_integer (val, partial_len);
558
559           /* The last part of a arg should shift left when
560              TARGET_BYTE_ORDER is BFD_ENDIAN_BIG.  */
561           if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
562               && arg_last_part_p == 1
563               && (typecode == TYPE_CODE_STRUCT
564                   || typecode == TYPE_CODE_UNION))
565             regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
566
567           /* Always increase the stack_offset and save args to stack.  */
568           addr = sp + stack_offset + downward_offset;
569           write_memory (addr, val, partial_len);
570
571           if (argreg <= SCORE_LAST_ARG_REGNUM)
572             {
573               regcache_cooked_write_unsigned (regcache, argreg++, regval);
574               if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
575                 arg_last_part_p = 1;
576             }
577
578           val += partial_len;
579           arglen -= partial_len;
580           stack_offset += align_up (partial_len, SCORE_REGSIZE);
581         }
582     }
583
584   /* Step 5, Save SP.  */
585   regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
586
587   return sp;
588 }
589
590 static char *
591 score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
592 {
593   int ret;
594   char *memblock = NULL;
595
596   if (size < 0)
597     {
598       error ("Error: malloc size < 0 in file:%s, line:%d!",
599              __FILE__, __LINE__);
600       return NULL;
601     }
602   else if (size == 0)
603     return NULL;
604
605   memblock = (char *) xmalloc (size);
606   memset (memblock, 0, size);
607   ret = target_read_memory (addr & ~0x3, memblock, size);
608   if (ret)
609     {
610       error ("Error: target_read_memory in file:%s, line:%d!",
611              __FILE__, __LINE__);
612       return NULL;
613     }
614   return memblock;
615 }
616
617 static void
618 score_free_memblock (char *memblock)
619 {
620   xfree (memblock);
621 }
622
623 static void
624 score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
625                            CORE_ADDR cur_pc)
626 {
627   if (prev_pc == -1)
628     {
629       /* First time call this function, do nothing.  */
630     }
631   else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
632     {
633       /* First 16-bit instruction, then 32-bit instruction.  */
634       *memblock += SCORE_INSTLEN;
635     }
636   else if (cur_pc - prev_pc == 4)
637     {
638       /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
639       *memblock += SCORE_INSTLEN;
640     }
641 }
642
643 static inst_t *
644 score_fetch_inst (CORE_ADDR addr, char *memblock)
645 {
646   static inst_t inst = { 0, 0 };
647   char buf[SCORE_INSTLEN] = { 0 };
648   int big;
649   int ret;
650
651   if (target_has_execution && memblock != NULL)
652     {
653       /* Fetch instruction from local MEMBLOCK.  */
654       memcpy (buf, memblock, SCORE_INSTLEN);
655     }
656   else
657     {
658       /* Fetch instruction from target.  */
659       ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
660       if (ret)
661         {
662           error ("Error: target_read_memory in file:%s, line:%d!",
663                   __FILE__, __LINE__);
664           return 0;
665         }
666     }
667
668   inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
669   inst.is15 = !(inst.raw & 0x80008000);
670   inst.v = RM_PBITS (inst.raw);
671   big = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
672   if (inst.is15)
673     {
674       if (big ^ ((addr & 0x2) == 2))
675         inst.v = G_FLD (inst.v, 29, 15);
676       else
677         inst.v = G_FLD (inst.v, 14, 0);
678     }
679   return &inst;
680 }
681
682 static CORE_ADDR
683 score_skip_prologue (CORE_ADDR pc)
684 {
685   CORE_ADDR cpc = pc;
686   int iscan = 32, stack_sub = 0;
687   while (iscan-- > 0)
688     {
689       inst_t *inst = score_fetch_inst (cpc, NULL);
690       if (!inst)
691         break;
692       if (!inst->is15 && !stack_sub
693           && (G_FLD (inst->v, 29, 25) == 0x1
694               && G_FLD (inst->v, 24, 20) == 0x0))
695         {
696           /* addi r0, offset */
697           pc = stack_sub = cpc + SCORE_INSTLEN;
698         }
699       else if (!inst->is15
700                && inst->v == RM_PBITS (0x8040bc56))
701         {
702           /* mv r2, r0  */
703           pc = cpc + SCORE_INSTLEN;
704           break;
705         }
706       else if (inst->is15
707                && inst->v == RM_PBITS (0x0203))
708         {
709           /* mv! r2, r0 */
710           pc = cpc + SCORE16_INSTLEN;
711           break;
712         }
713       else if (inst->is15
714                && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
715                    || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
716                    || (G_FLD (inst->v, 14, 12) == 0x0
717                        && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
718         break;
719       else if (!inst->is15
720                && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
721                    || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
722                    || (G_FLD (inst->v, 29, 25) == 0x0
723                        && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
724         break;
725
726       cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
727     }
728   return pc;
729 }
730
731 static int
732 score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
733 {
734   inst_t *inst = score_fetch_inst (cur_pc, NULL);
735
736   if (inst->v == 0x23)
737     return 1;   /* mv! r0, r2 */
738   else if (G_FLD (inst->v, 14, 12) == 0x2
739            && G_FLD (inst->v, 3, 0) == 0xa)
740     return 1;   /* pop! */
741   else if (G_FLD (inst->v, 14, 12) == 0x0
742            && G_FLD (inst->v, 7, 0) == 0x34)
743     return 1;   /* br! r3 */
744   else if (G_FLD (inst->v, 29, 15) == 0x2
745            && G_FLD (inst->v, 6, 1) == 0x2b)
746     return 1;   /* mv r0, r2 */
747   else if (G_FLD (inst->v, 29, 25) == 0x0
748            && G_FLD (inst->v, 6, 1) == 0x4
749            && G_FLD (inst->v, 19, 15) == 0x3)
750     return 1;   /* br r3 */
751   else
752     return 0;
753 }
754
755 static void
756 score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
757                         struct frame_info *next_frame,
758                         struct score_frame_cache *this_cache)
759 {
760   CORE_ADDR sp;
761   CORE_ADDR fp;
762   CORE_ADDR cur_pc = startaddr;
763
764   int sp_offset = 0;
765   int ra_offset = 0;
766   int fp_offset = 0;
767   int ra_offset_p = 0;
768   int fp_offset_p = 0;
769   int inst_len = 0;
770
771   char *memblock = NULL;
772   char *memblock_ptr = NULL;
773   CORE_ADDR prev_pc = -1;
774
775   /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
776   memblock_ptr = memblock =
777     score_malloc_and_get_memblock (startaddr, pc - startaddr);
778
779   sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
780   fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
781
782   for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
783     {
784       inst_t *inst = NULL;
785       if (memblock != NULL)
786         {
787           /* Reading memory block from target succefully and got all
788              the instructions(from STARTADDR to PC) needed.  */
789           score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
790           inst = score_fetch_inst (cur_pc, memblock);
791         }
792       else
793         {
794           /* Otherwise, we fetch 4 bytes from target, and GDB also
795              work correctly.  */
796           inst = score_fetch_inst (cur_pc, NULL);
797         }
798
799       if (inst->is15 == 1)
800         {
801           inst_len = SCORE16_INSTLEN;
802
803           if (G_FLD (inst->v, 14, 12) == 0x2
804               && G_FLD (inst->v, 3, 0) == 0xe)
805             {
806               /* push! */
807               sp_offset += 4;
808
809               if (G_FLD (inst->v, 11, 7) == 0x6
810                   && ra_offset_p == 0)
811                 {
812                   /* push! r3, [r0] */
813                   ra_offset = sp_offset;
814                   ra_offset_p = 1;
815                 }
816               else if (G_FLD (inst->v, 11, 7) == 0x4
817                        && fp_offset_p == 0)
818                 {
819                   /* push! r2, [r0] */
820                   fp_offset = sp_offset;
821                   fp_offset_p = 1;
822                 }
823             }
824           else if (G_FLD (inst->v, 14, 12) == 0x2
825                    && G_FLD (inst->v, 3, 0) == 0xa)
826             {
827               /* pop! */
828               sp_offset -= 4;
829             }
830           else if (G_FLD (inst->v, 14, 7) == 0xc1
831                    && G_FLD (inst->v, 2, 0) == 0x0)
832             {
833               /* subei! r0, n */
834               sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
835             }
836           else if (G_FLD (inst->v, 14, 7) == 0xc0
837                    && G_FLD (inst->v, 2, 0) == 0x0)
838             {
839               /* addei! r0, n */
840               sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
841             }
842         }
843       else
844         {
845           inst_len = SCORE_INSTLEN;
846
847           if (G_FLD (inst->v, 29, 15) == 0xc60
848               && G_FLD (inst->v, 2, 0) == 0x4)
849             {
850               /* sw r3, [r0, offset]+ */
851               sp_offset += SCORE_INSTLEN;
852               if (ra_offset_p == 0)
853                 {
854                   ra_offset = sp_offset;
855                   ra_offset_p = 1;
856                 }
857             }
858           if (G_FLD (inst->v, 29, 15) == 0xc40
859               && G_FLD (inst->v, 2, 0) == 0x4)
860             {
861               /* sw r2, [r0, offset]+ */
862               sp_offset += SCORE_INSTLEN;
863               if (fp_offset_p == 0)
864                 {
865                   fp_offset = sp_offset;
866                   fp_offset_p = 1;
867                 }
868             }
869           else if (G_FLD (inst->v, 29, 15) == 0x1c60
870                    && G_FLD (inst->v, 2, 0) == 0x0)
871             {
872               /* lw r3, [r0]+, 4 */
873               sp_offset -= SCORE_INSTLEN;
874               ra_offset_p = 1;
875             }
876           else if (G_FLD (inst->v, 29, 15) == 0x1c40
877                    && G_FLD (inst->v, 2, 0) == 0x0)
878             {
879               /* lw r2, [r0]+, 4 */
880               sp_offset -= SCORE_INSTLEN;
881               fp_offset_p = 1;
882             }
883
884           else if (G_FLD (inst->v, 29, 17) == 0x100
885                    && G_FLD (inst->v, 0, 0) == 0x0)
886             {
887               /* addi r0, -offset */
888               sp_offset += 65536 - G_FLD (inst->v, 16, 1);
889             }
890           else if (G_FLD (inst->v, 29, 17) == 0x110
891                    && G_FLD (inst->v, 0, 0) == 0x0)
892             {
893               /* addi r2, offset */
894               if (pc - cur_pc > 4)
895                 {
896                   unsigned int save_v = inst->v;
897                   inst_t *inst2 =
898                     score_fetch_inst (cur_pc + SCORE_INSTLEN, NULL);
899                   if (inst2->v == 0x23)
900                     {
901                       /* mv! r0, r2 */
902                       sp_offset -= G_FLD (save_v, 16, 1);
903                     }
904                 }
905             }
906         }
907     }
908
909   /* Save RA.  */
910   if (ra_offset_p == 1)
911     {
912       if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
913         this_cache->saved_regs[SCORE_PC_REGNUM].addr =
914           sp + sp_offset - ra_offset;
915     }
916   else
917     {
918       this_cache->saved_regs[SCORE_PC_REGNUM] =
919         this_cache->saved_regs[SCORE_RA_REGNUM];
920     }
921
922   /* Save FP.  */
923   if (fp_offset_p == 1)
924     {
925       if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
926         this_cache->saved_regs[SCORE_FP_REGNUM].addr =
927           sp + sp_offset - fp_offset;
928     }
929
930   /* Save SP and FP.  */
931   this_cache->base = sp + sp_offset;
932   this_cache->fp = fp;
933
934   /* Don't forget to free MEMBLOCK if we allocated it.  */
935   if (memblock_ptr != NULL)
936     score_free_memblock (memblock_ptr);
937 }
938
939 static struct score_frame_cache *
940 score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
941 {
942   struct score_frame_cache *cache;
943
944   if ((*this_cache) != NULL)
945     return (*this_cache);
946
947   cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
948   (*this_cache) = cache;
949   cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
950
951   /* Analyze the prologue.  */
952   {
953     const CORE_ADDR pc = frame_pc_unwind (next_frame);
954     CORE_ADDR start_addr;
955
956     find_pc_partial_function (pc, NULL, &start_addr, NULL);
957     if (start_addr == 0)
958       return cache;
959     score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
960   }
961
962   /* Save SP.  */
963   trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
964
965   return (*this_cache);
966 }
967
968 static void
969 score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
970                         struct frame_id *this_id)
971 {
972   struct score_frame_cache *info = score_make_prologue_cache (next_frame,
973                                                               this_cache);
974   (*this_id) = frame_id_build (info->base,
975                                frame_func_unwind (next_frame, NORMAL_FRAME));
976 }
977
978 static void
979 score_prologue_prev_register (struct frame_info *next_frame,
980                               void **this_cache,
981                               int regnum, int *optimizedp,
982                               enum lval_type *lvalp, CORE_ADDR * addrp,
983                               int *realnump, gdb_byte * valuep)
984 {
985   struct score_frame_cache *info = score_make_prologue_cache (next_frame,
986                                                               this_cache);
987   trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
988                                 optimizedp, lvalp, addrp, realnump, valuep);
989 }
990
991 static const struct frame_unwind score_prologue_unwind =
992 {
993   NORMAL_FRAME,
994   score_prologue_this_id,
995   score_prologue_prev_register
996 };
997
998 static const struct frame_unwind *
999 score_prologue_sniffer (struct frame_info *next_frame)
1000 {
1001   return &score_prologue_unwind;
1002 }
1003
1004 static CORE_ADDR
1005 score_prologue_frame_base_address (struct frame_info *next_frame,
1006                                    void **this_cache)
1007 {
1008   struct score_frame_cache *info =
1009     score_make_prologue_cache (next_frame, this_cache);
1010   return info->fp;
1011 }
1012
1013 static const struct frame_base score_prologue_frame_base =
1014 {
1015   &score_prologue_unwind,
1016   score_prologue_frame_base_address,
1017   score_prologue_frame_base_address,
1018   score_prologue_frame_base_address,
1019 };
1020
1021 static const struct frame_base *
1022 score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1023 {
1024   return &score_prologue_frame_base;
1025 }
1026
1027 static struct gdbarch *
1028 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1029 {
1030   struct gdbarch *gdbarch;
1031
1032   arches = gdbarch_list_lookup_by_info (arches, &info);
1033   if (arches != NULL)
1034     {
1035       return (arches->gdbarch);
1036     }
1037   gdbarch = gdbarch_alloc (&info, 0);
1038
1039   set_gdbarch_short_bit (gdbarch, 16);
1040   set_gdbarch_int_bit (gdbarch, 32);
1041   set_gdbarch_float_bit (gdbarch, 32);
1042   set_gdbarch_double_bit (gdbarch, 64);
1043   set_gdbarch_long_double_bit (gdbarch, 64);
1044   set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1045   set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1046   set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1047   set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1048   set_gdbarch_register_name (gdbarch, score_register_name);
1049   set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1050   set_gdbarch_register_type (gdbarch, score_register_type);
1051   set_gdbarch_frame_align (gdbarch, score_frame_align);
1052   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1053   set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1054   set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1055   set_gdbarch_print_insn (gdbarch, score_print_insn);
1056   set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1057   set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
1058
1059   /* Watchpoint hooks.  */
1060   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1061
1062   /* Dummy frame hooks.  */
1063   set_gdbarch_return_value (gdbarch, score_return_value);
1064   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1065   set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
1066   set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1067
1068   /* Normal frame hooks.  */
1069   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1070   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1071   frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
1072   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1073
1074   return gdbarch;
1075 }
1076
1077 extern initialize_file_ftype _initialize_score_tdep;
1078
1079 void
1080 _initialize_score_tdep (void)
1081 {
1082   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1083 }