* defs.h (extract_signed_integer, extract_unsigned_integer,
[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, 2008, 2009 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 3 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, see <http://www.gnu.org/licenses/>.  */
23
24 #include "defs.h"
25 #include "gdb_assert.h"
26 #include "inferior.h"
27 #include "symtab.h"
28 #include "objfiles.h"
29 #include "gdbcore.h"
30 #include "target.h"
31 #include "arch-utils.h"
32 #include "regcache.h"
33 #include "dis-asm.h"
34 #include "frame-unwind.h"
35 #include "frame-base.h"
36 #include "trad-frame.h"
37 #include "dwarf2-frame.h"
38 #include "score-tdep.h"
39
40 #define G_FLD(_i,_ms,_ls)   (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
41 #define RM_PBITS(_raw)      ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0))
42
43 typedef struct{
44     unsigned int v;
45     unsigned int raw;
46     char         is15;
47 }inst_t;
48
49 struct score_frame_cache
50 {
51   CORE_ADDR base;
52   CORE_ADDR fp;
53   struct trad_frame_saved_reg *saved_regs;
54 };
55
56 #if 0
57 /* If S+core GCC will generate these instructions in the prologue:
58
59    lw   rx, imm1
60    addi rx, -imm2
61    mv!  r2, rx
62
63    then .pdr section is used.  */
64
65 #define P_SIZE          8
66 #define PI_SYM          0
67 #define PI_R_MSK        1
68 #define PI_R_OFF        2
69 #define PI_R_LEF        4
70 #define PI_F_OFF        5
71 #define PI_F_REG        6
72 #define PI_RAREG        7
73
74 typedef struct frame_extra_info
75 {
76   CORE_ADDR p_frame;
77   unsigned int pdr[P_SIZE];
78 } extra_info_t;
79
80 struct obj_priv
81 {
82   bfd_size_type size;
83   char *contents;
84 };
85
86 static bfd *the_bfd;
87
88 static int
89 score_compare_pdr_entries (const void *a, const void *b)
90 {
91   CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a);
92   CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b);
93   if (lhs < rhs)
94     return -1;
95   else if (lhs == rhs)
96     return 0;
97   else
98     return 1;
99 }
100
101 static void
102 score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc,
103                            struct frame_info *this_frame,
104                            struct score_frame_cache *this_cache)
105 {
106   struct symbol *sym;
107   struct obj_section *sec;
108   extra_info_t *fci_ext;
109   CORE_ADDR leaf_ra_stack_addr = -1;
110
111   gdb_assert (startaddr <= pc);
112   gdb_assert (this_cache != NULL);
113
114   fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
115   if ((sec = find_pc_section (pc)) == NULL)
116     {
117       error ("Error: Can't find section in file:%s, line:%d!",
118              __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             CORE_ADDR pdr_pc;
153             mid = (low + high) / 2;
154             ptr = priv->contents + mid * 32;
155             pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
156             pdr_pc += ANOFFSET (sec->objfile->section_offsets,
157                                 SECT_OFF_TEXT (sec->objfile));
158             if (pdr_pc == startaddr)
159               break;
160             if (pdr_pc > startaddr)
161               high = mid;
162             else
163               low = mid + 1;
164           }
165         while (low != high);
166
167         if (low != high)
168           {
169             gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr);
170 #define EXT_PDR(_pi)    bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2))
171             fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM);
172             fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK);
173             fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF);
174             fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF);
175             fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF);
176             fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG);
177             fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG);
178 #undef EXT_PDR
179           }
180       }
181   }
182 }
183 #endif
184
185 #if 0
186 /* Open these functions if build with simulator.  */
187
188 int
189 score_target_can_use_watch (int type, int cnt, int othertype)
190 {
191   if (strcmp (current_target.to_shortname, "sim") == 0)
192     {      
193       return soc_gh_can_use_watch (type, cnt);
194     }
195   else
196     {
197       return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
198     }
199 }
200
201 int
202 score_stopped_by_watch (void)
203 {
204   if (strcmp (current_target.to_shortname, "sim") == 0)
205     {      
206       return soc_gh_stopped_by_watch ();
207     }
208   else
209     {
210       return (*current_target.to_stopped_by_watchpoint) ();
211     }
212 }
213
214 int
215 score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
216 {
217   if (strcmp (current_target.to_shortname, "sim") == 0)
218     {      
219       return soc_gh_add_watch (addr, len, type);
220     }
221   else
222     {
223       return (*current_target.to_insert_watchpoint) (addr, len, type); 
224     }
225 }
226
227 int
228 score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
229 {
230   if (strcmp (current_target.to_shortname, "sim") == 0)
231     {      
232       return soc_gh_del_watch (addr, len, type);
233     }
234   else
235     {
236       return (*current_target.to_remove_watchpoint) (addr, len, type); 
237     }
238 }
239
240 int
241 score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt)
242 {
243   if (strcmp (current_target.to_shortname, "sim") == 0)
244     {      
245       return soc_gh_add_hardbp (bp_tgt->placed_address);
246     }
247   else
248     {
249       return (*current_target.to_insert_hw_breakpoint) (bp_tgt); 
250     }
251 }
252
253 int
254 score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt)
255 {
256   if (strcmp (current_target.to_shortname, "sim") == 0)
257     {      
258       return soc_gh_del_hardbp (bp_tgt->placed_address);
259     }
260   else
261     {
262       return (*current_target.to_remove_hw_breakpoint) (bp_tgt); 
263     }
264 }
265 #endif
266
267 static struct type *
268 score_register_type (struct gdbarch *gdbarch, int regnum)
269 {
270   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
271   return builtin_type (gdbarch)->builtin_uint32;
272 }
273
274 static CORE_ADDR
275 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
276 {
277   return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
278 }
279
280 static CORE_ADDR
281 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
282 {
283   return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
284 }
285
286 static const char *
287 score_register_name (struct gdbarch *gdbarch, int regnum)
288 {
289   const char *score_register_names[] = {
290     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
291     "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
292     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
293     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
294
295     "PSR",   "COND",   "ECR",    "EXCPVEC",
296     "CCR",   "EPC",    "EMA",    "TLBLOCK",
297     "TLBPT", "PEADDR", "TLBRPT", "PEVN",
298     "PECTX", "LIMPFN", "LDMPFN", "PREV",
299     "DREG",  "PC",     "DSAVE",  "COUNTER",
300     "LDCR",  "STCR",   "CEH",    "CEL",
301   };
302
303   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
304   return score_register_names[regnum];
305 }
306
307 static int
308 score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
309 {
310   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
311   return regnum;
312 }
313
314 static int
315 score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
316 {
317   if (info->endian == BFD_ENDIAN_BIG)
318     return print_insn_big_score (memaddr, info);
319   else
320     return print_insn_little_score (memaddr, info);
321 }
322
323 static const gdb_byte *
324 score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
325                           int *lenptr)
326 {
327   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
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, byte_order);
338
339   if (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 *func_type,
419                     struct type *type, 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,
438                                gdbarch_byte_order (gdbarch),
439                                readbuf, writebuf, offset);
440         }
441       return RETURN_VALUE_REGISTER_CONVENTION;
442     }
443 }
444
445 static struct frame_id
446 score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
447 {
448   return frame_id_build (
449            get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM),
450            get_frame_pc (this_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   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
481   int argnum;
482   int argreg;
483   int arglen = 0;
484   CORE_ADDR stack_offset = 0;
485   CORE_ADDR addr = 0;
486
487   /* Step 1, Save RA.  */
488   regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
489
490   /* Step 2, Make space on the stack for the args.  */
491   struct_addr = align_down (struct_addr, 16);
492   sp = align_down (sp, 16);
493   for (argnum = 0; argnum < nargs; argnum++)
494     arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
495                         SCORE_REGSIZE);
496   sp -= align_up (arglen, 16);
497
498   argreg = SCORE_BEGIN_ARG_REGNUM;
499
500   /* Step 3, Check if struct return then save the struct address to
501      r4 and increase the stack_offset by 4.  */
502   if (struct_return)
503     {
504       regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
505       stack_offset += SCORE_REGSIZE;
506     }
507
508   /* Step 4, Load arguments:
509      If arg length is too long (> 4 bytes), then split the arg and
510      save every parts.  */
511   for (argnum = 0; argnum < nargs; argnum++)
512     {
513       struct value *arg = args[argnum];
514       struct type *arg_type = check_typedef (value_type (arg));
515       enum type_code typecode = TYPE_CODE (arg_type);
516       const gdb_byte *val = value_contents (arg);
517       int downward_offset = 0;
518       int odd_sized_struct_p;
519       int arg_last_part_p = 0;
520
521       arglen = TYPE_LENGTH (arg_type);
522       odd_sized_struct_p = (arglen > SCORE_REGSIZE
523                             && arglen % SCORE_REGSIZE != 0);
524
525       /* If a arg should be aligned to 8 bytes (long long or double),
526          the value should be put to even register numbers.  */
527       if (score_type_needs_double_align (arg_type))
528         {
529           if (argreg & 1)
530             argreg++;
531         }
532
533       /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
534          the default "downward"/"upward" method:
535
536          Example:
537
538          struct struc
539          {
540            char a; char b; char c;
541          } s = {'a', 'b', 'c'};
542
543          Big endian:    s = {X, 'a', 'b', 'c'}
544          Little endian: s = {'a', 'b', 'c', X}
545
546          Where X is a hole.  */
547
548       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
549           && (typecode == TYPE_CODE_STRUCT
550               || typecode == TYPE_CODE_UNION)
551           && argreg > SCORE_LAST_ARG_REGNUM
552           && arglen < SCORE_REGSIZE)
553         downward_offset += (SCORE_REGSIZE - arglen);
554
555       while (arglen > 0)
556         {
557           int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
558           ULONGEST regval = extract_unsigned_integer (val, partial_len,
559                                                       byte_order);
560
561           /* The last part of a arg should shift left when
562              gdbarch_byte_order is BFD_ENDIAN_BIG.  */
563           if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
564               && arg_last_part_p == 1
565               && (typecode == TYPE_CODE_STRUCT
566                   || typecode == TYPE_CODE_UNION))
567             regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
568
569           /* Always increase the stack_offset and save args to stack.  */
570           addr = sp + stack_offset + downward_offset;
571           write_memory (addr, val, partial_len);
572
573           if (argreg <= SCORE_LAST_ARG_REGNUM)
574             {
575               regcache_cooked_write_unsigned (regcache, argreg++, regval);
576               if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
577                 arg_last_part_p = 1;
578             }
579
580           val += partial_len;
581           arglen -= partial_len;
582           stack_offset += align_up (partial_len, SCORE_REGSIZE);
583         }
584     }
585
586   /* Step 5, Save SP.  */
587   regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
588
589   return sp;
590 }
591
592 static char *
593 score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
594 {
595   int ret;
596   char *memblock = NULL;
597
598   if (size < 0)
599     {
600       error ("Error: malloc size < 0 in file:%s, line:%d!",
601              __FILE__, __LINE__);
602       return NULL;
603     }
604   else if (size == 0)
605     return NULL;
606
607   memblock = (char *) xmalloc (size);
608   memset (memblock, 0, size);
609   ret = target_read_memory (addr & ~0x3, memblock, size);
610   if (ret)
611     {
612       error ("Error: target_read_memory in file:%s, line:%d!",
613              __FILE__, __LINE__);
614       return NULL;
615     }
616   return memblock;
617 }
618
619 static void
620 score_free_memblock (char *memblock)
621 {
622   xfree (memblock);
623 }
624
625 static void
626 score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
627                            CORE_ADDR cur_pc)
628 {
629   if (prev_pc == -1)
630     {
631       /* First time call this function, do nothing.  */
632     }
633   else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
634     {
635       /* First 16-bit instruction, then 32-bit instruction.  */
636       *memblock += SCORE_INSTLEN;
637     }
638   else if (cur_pc - prev_pc == 4)
639     {
640       /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
641       *memblock += SCORE_INSTLEN;
642     }
643 }
644
645 static inst_t *
646 score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
647 {
648   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
649   static inst_t inst = { 0, 0 };
650   char buf[SCORE_INSTLEN] = { 0 };
651   int big;
652   int ret;
653
654   if (target_has_execution && memblock != NULL)
655     {
656       /* Fetch instruction from local MEMBLOCK.  */
657       memcpy (buf, memblock, SCORE_INSTLEN);
658     }
659   else
660     {
661       /* Fetch instruction from target.  */
662       ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
663       if (ret)
664         {
665           error ("Error: target_read_memory in file:%s, line:%d!",
666                   __FILE__, __LINE__);
667           return 0;
668         }
669     }
670
671   inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
672   inst.is15 = !(inst.raw & 0x80008000);
673   inst.v = RM_PBITS (inst.raw);
674   big = (byte_order == BFD_ENDIAN_BIG);
675   if (inst.is15)
676     {
677       if (big ^ ((addr & 0x2) == 2))
678         inst.v = G_FLD (inst.v, 29, 15);
679       else
680         inst.v = G_FLD (inst.v, 14, 0);
681     }
682   return &inst;
683 }
684
685 static CORE_ADDR
686 score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
687 {
688   CORE_ADDR cpc = pc;
689   int iscan = 32, stack_sub = 0;
690   while (iscan-- > 0)
691     {
692       inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL);
693       if (!inst)
694         break;
695       if (!inst->is15 && !stack_sub
696           && (G_FLD (inst->v, 29, 25) == 0x1
697               && G_FLD (inst->v, 24, 20) == 0x0))
698         {
699           /* addi r0, offset */
700           pc = stack_sub = cpc + SCORE_INSTLEN;
701         }
702       else if (!inst->is15
703                && inst->v == RM_PBITS (0x8040bc56))
704         {
705           /* mv r2, r0  */
706           pc = cpc + SCORE_INSTLEN;
707           break;
708         }
709       else if (inst->is15
710                && inst->v == RM_PBITS (0x0203))
711         {
712           /* mv! r2, r0 */
713           pc = cpc + SCORE16_INSTLEN;
714           break;
715         }
716       else if (inst->is15
717                && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
718                    || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
719                    || (G_FLD (inst->v, 14, 12) == 0x0
720                        && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
721         break;
722       else if (!inst->is15
723                && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
724                    || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
725                    || (G_FLD (inst->v, 29, 25) == 0x0
726                        && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
727         break;
728
729       cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
730     }
731   return pc;
732 }
733
734 static int
735 score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
736 {
737   inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL);
738
739   if (inst->v == 0x23)
740     return 1;   /* mv! r0, r2 */
741   else if (G_FLD (inst->v, 14, 12) == 0x2
742            && G_FLD (inst->v, 3, 0) == 0xa)
743     return 1;   /* pop! */
744   else if (G_FLD (inst->v, 14, 12) == 0x0
745            && G_FLD (inst->v, 7, 0) == 0x34)
746     return 1;   /* br! r3 */
747   else if (G_FLD (inst->v, 29, 15) == 0x2
748            && G_FLD (inst->v, 6, 1) == 0x2b)
749     return 1;   /* mv r0, r2 */
750   else if (G_FLD (inst->v, 29, 25) == 0x0
751            && G_FLD (inst->v, 6, 1) == 0x4
752            && G_FLD (inst->v, 19, 15) == 0x3)
753     return 1;   /* br r3 */
754   else
755     return 0;
756 }
757
758 static void
759 score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
760                         struct frame_info *this_frame,
761                         struct score_frame_cache *this_cache)
762 {
763   struct gdbarch *gdbarch = get_frame_arch (this_frame);
764   CORE_ADDR sp;
765   CORE_ADDR fp;
766   CORE_ADDR cur_pc = startaddr;
767
768   int sp_offset = 0;
769   int ra_offset = 0;
770   int fp_offset = 0;
771   int ra_offset_p = 0;
772   int fp_offset_p = 0;
773   int inst_len = 0;
774
775   char *memblock = NULL;
776   char *memblock_ptr = NULL;
777   CORE_ADDR prev_pc = -1;
778
779   /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
780   memblock_ptr = memblock =
781     score_malloc_and_get_memblock (startaddr, pc - startaddr);
782
783   sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
784   fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
785
786   for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
787     {
788       inst_t *inst = NULL;
789       if (memblock != NULL)
790         {
791           /* Reading memory block from target succefully and got all
792              the instructions(from STARTADDR to PC) needed.  */
793           score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
794           inst = score_fetch_inst (gdbarch, cur_pc, memblock);
795         }
796       else
797         {
798           /* Otherwise, we fetch 4 bytes from target, and GDB also
799              work correctly.  */
800           inst = score_fetch_inst (gdbarch, cur_pc, NULL);
801         }
802
803       if (inst->is15 == 1)
804         {
805           inst_len = SCORE16_INSTLEN;
806
807           if (G_FLD (inst->v, 14, 12) == 0x2
808               && G_FLD (inst->v, 3, 0) == 0xe)
809             {
810               /* push! */
811               sp_offset += 4;
812
813               if (G_FLD (inst->v, 11, 7) == 0x6
814                   && ra_offset_p == 0)
815                 {
816                   /* push! r3, [r0] */
817                   ra_offset = sp_offset;
818                   ra_offset_p = 1;
819                 }
820               else if (G_FLD (inst->v, 11, 7) == 0x4
821                        && fp_offset_p == 0)
822                 {
823                   /* push! r2, [r0] */
824                   fp_offset = sp_offset;
825                   fp_offset_p = 1;
826                 }
827             }
828           else if (G_FLD (inst->v, 14, 12) == 0x2
829                    && G_FLD (inst->v, 3, 0) == 0xa)
830             {
831               /* pop! */
832               sp_offset -= 4;
833             }
834           else if (G_FLD (inst->v, 14, 7) == 0xc1
835                    && G_FLD (inst->v, 2, 0) == 0x0)
836             {
837               /* subei! r0, n */
838               sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
839             }
840           else if (G_FLD (inst->v, 14, 7) == 0xc0
841                    && G_FLD (inst->v, 2, 0) == 0x0)
842             {
843               /* addei! r0, n */
844               sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
845             }
846         }
847       else
848         {
849           inst_len = SCORE_INSTLEN;
850
851           if (G_FLD (inst->v, 29, 15) == 0xc60
852               && G_FLD (inst->v, 2, 0) == 0x4)
853             {
854               /* sw r3, [r0, offset]+ */
855               sp_offset += SCORE_INSTLEN;
856               if (ra_offset_p == 0)
857                 {
858                   ra_offset = sp_offset;
859                   ra_offset_p = 1;
860                 }
861             }
862           if (G_FLD (inst->v, 29, 15) == 0xc40
863               && G_FLD (inst->v, 2, 0) == 0x4)
864             {
865               /* sw r2, [r0, offset]+ */
866               sp_offset += SCORE_INSTLEN;
867               if (fp_offset_p == 0)
868                 {
869                   fp_offset = sp_offset;
870                   fp_offset_p = 1;
871                 }
872             }
873           else if (G_FLD (inst->v, 29, 15) == 0x1c60
874                    && G_FLD (inst->v, 2, 0) == 0x0)
875             {
876               /* lw r3, [r0]+, 4 */
877               sp_offset -= SCORE_INSTLEN;
878               ra_offset_p = 1;
879             }
880           else if (G_FLD (inst->v, 29, 15) == 0x1c40
881                    && G_FLD (inst->v, 2, 0) == 0x0)
882             {
883               /* lw r2, [r0]+, 4 */
884               sp_offset -= SCORE_INSTLEN;
885               fp_offset_p = 1;
886             }
887
888           else if (G_FLD (inst->v, 29, 17) == 0x100
889                    && G_FLD (inst->v, 0, 0) == 0x0)
890             {
891               /* addi r0, -offset */
892               sp_offset += 65536 - G_FLD (inst->v, 16, 1);
893             }
894           else if (G_FLD (inst->v, 29, 17) == 0x110
895                    && G_FLD (inst->v, 0, 0) == 0x0)
896             {
897               /* addi r2, offset */
898               if (pc - cur_pc > 4)
899                 {
900                   unsigned int save_v = inst->v;
901                   inst_t *inst2 =
902                     score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
903                   if (inst2->v == 0x23)
904                     {
905                       /* mv! r0, r2 */
906                       sp_offset -= G_FLD (save_v, 16, 1);
907                     }
908                 }
909             }
910         }
911     }
912
913   /* Save RA.  */
914   if (ra_offset_p == 1)
915     {
916       if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
917         this_cache->saved_regs[SCORE_PC_REGNUM].addr =
918           sp + sp_offset - ra_offset;
919     }
920   else
921     {
922       this_cache->saved_regs[SCORE_PC_REGNUM] =
923         this_cache->saved_regs[SCORE_RA_REGNUM];
924     }
925
926   /* Save FP.  */
927   if (fp_offset_p == 1)
928     {
929       if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
930         this_cache->saved_regs[SCORE_FP_REGNUM].addr =
931           sp + sp_offset - fp_offset;
932     }
933
934   /* Save SP and FP.  */
935   this_cache->base = sp + sp_offset;
936   this_cache->fp = fp;
937
938   /* Don't forget to free MEMBLOCK if we allocated it.  */
939   if (memblock_ptr != NULL)
940     score_free_memblock (memblock_ptr);
941 }
942
943 static struct score_frame_cache *
944 score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
945 {
946   struct score_frame_cache *cache;
947
948   if ((*this_cache) != NULL)
949     return (*this_cache);
950
951   cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
952   (*this_cache) = cache;
953   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
954
955   /* Analyze the prologue.  */
956   {
957     const CORE_ADDR pc = get_frame_pc (this_frame);
958     CORE_ADDR start_addr;
959
960     find_pc_partial_function (pc, NULL, &start_addr, NULL);
961     if (start_addr == 0)
962       return cache;
963     score_analyze_prologue (start_addr, pc, this_frame, *this_cache);
964   }
965
966   /* Save SP.  */
967   trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
968
969   return (*this_cache);
970 }
971
972 static void
973 score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
974                         struct frame_id *this_id)
975 {
976   struct score_frame_cache *info = score_make_prologue_cache (this_frame,
977                                                               this_cache);
978   (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
979 }
980
981 static struct value *
982 score_prologue_prev_register (struct frame_info *this_frame,
983                               void **this_cache, int regnum)
984 {
985   struct score_frame_cache *info = score_make_prologue_cache (this_frame,
986                                                               this_cache);
987   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
988 }
989
990 static const struct frame_unwind score_prologue_unwind =
991 {
992   NORMAL_FRAME,
993   score_prologue_this_id,
994   score_prologue_prev_register,
995   NULL,
996   default_frame_sniffer
997 };
998
999 static CORE_ADDR
1000 score_prologue_frame_base_address (struct frame_info *this_frame,
1001                                    void **this_cache)
1002 {
1003   struct score_frame_cache *info =
1004     score_make_prologue_cache (this_frame, this_cache);
1005   return info->fp;
1006 }
1007
1008 static const struct frame_base score_prologue_frame_base =
1009 {
1010   &score_prologue_unwind,
1011   score_prologue_frame_base_address,
1012   score_prologue_frame_base_address,
1013   score_prologue_frame_base_address,
1014 };
1015
1016 static const struct frame_base *
1017 score_prologue_frame_base_sniffer (struct frame_info *this_frame)
1018 {
1019   return &score_prologue_frame_base;
1020 }
1021
1022 static struct gdbarch *
1023 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1024 {
1025   struct gdbarch *gdbarch;
1026
1027   arches = gdbarch_list_lookup_by_info (arches, &info);
1028   if (arches != NULL)
1029     {
1030       return (arches->gdbarch);
1031     }
1032   gdbarch = gdbarch_alloc (&info, 0);
1033
1034   set_gdbarch_short_bit (gdbarch, 16);
1035   set_gdbarch_int_bit (gdbarch, 32);
1036   set_gdbarch_float_bit (gdbarch, 32);
1037   set_gdbarch_double_bit (gdbarch, 64);
1038   set_gdbarch_long_double_bit (gdbarch, 64);
1039   set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1040   set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1041   set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1042   set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1043   set_gdbarch_register_name (gdbarch, score_register_name);
1044   set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1045   set_gdbarch_register_type (gdbarch, score_register_type);
1046   set_gdbarch_frame_align (gdbarch, score_frame_align);
1047   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1048   set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1049   set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1050   set_gdbarch_print_insn (gdbarch, score_print_insn);
1051   set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1052   set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
1053
1054   /* Watchpoint hooks.  */
1055   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1056
1057   /* Dummy frame hooks.  */
1058   set_gdbarch_return_value (gdbarch, score_return_value);
1059   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1060   set_gdbarch_dummy_id (gdbarch, score_dummy_id);
1061   set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1062
1063   /* Normal frame hooks.  */
1064   dwarf2_append_unwinders (gdbarch);
1065   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1066   frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
1067   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1068
1069   return gdbarch;
1070 }
1071
1072 extern initialize_file_ftype _initialize_score_tdep;
1073
1074 void
1075 _initialize_score_tdep (void)
1076 {
1077   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1078 }