2007-11-02 Markus Deuling <deuling@de.ibm.com>
[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 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 *next_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_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 (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 (gdbarch_byte_order (current_gdbarch) == 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 (CORE_ADDR *pcptr, int *lenptr)
325 {
326   gdb_byte buf[SCORE_INSTLEN] = { 0 };
327   int ret;
328   unsigned int raw;
329
330   if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
331     {
332       error ("Error: target_read_memory in file:%s, line:%d!",
333              __FILE__, __LINE__);
334     }
335   raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
336
337   if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
338     {
339       if (!(raw & 0x80008000))
340         {
341           /* 16bits instruction.  */
342           static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
343           *pcptr &= ~0x1;
344           *lenptr = sizeof (big_breakpoint16);
345           return big_breakpoint16;
346         }
347       else
348         {
349           /* 32bits instruction.  */
350           static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
351           *pcptr &= ~0x3;
352           *lenptr = sizeof (big_breakpoint32);
353           return big_breakpoint32;
354         }
355     }
356   else
357     {
358       if (!(raw & 0x80008000))
359         {
360           /* 16bits instruction.  */
361           static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
362           *pcptr &= ~0x1;
363           *lenptr = sizeof (little_breakpoint16);
364           return little_breakpoint16;
365         }
366       else
367         {
368           /* 32bits instruction.  */
369           static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
370           *pcptr &= ~0x3;
371           *lenptr = sizeof (little_breakpoint32);
372           return little_breakpoint32;
373         }
374     }
375 }
376
377 static CORE_ADDR
378 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
379 {
380   return align_down (addr, 16);
381 }
382
383 static void
384 score_xfer_register (struct regcache *regcache, int regnum, int length,
385                      enum bfd_endian endian, gdb_byte *readbuf,
386                      const gdb_byte *writebuf, int buf_offset)
387 {
388   int reg_offset = 0;
389   gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
390
391   switch (endian)
392     {
393     case BFD_ENDIAN_BIG:
394       reg_offset = SCORE_REGSIZE - length;
395       break;
396     case BFD_ENDIAN_LITTLE:
397       reg_offset = 0;
398       break;
399     case BFD_ENDIAN_UNKNOWN:
400       reg_offset = 0;
401       break;
402     default:
403       error ("Error: score_xfer_register in file:%s, line:%d!",
404              __FILE__, __LINE__);
405     }
406
407   if (readbuf != NULL)
408     regcache_cooked_read_part (regcache, regnum, reg_offset, length,
409                                readbuf + buf_offset);
410   if (writebuf != NULL)
411     regcache_cooked_write_part (regcache, regnum, reg_offset, length,
412                                 writebuf + buf_offset);
413 }
414
415 static enum return_value_convention
416 score_return_value (struct gdbarch *gdbarch, struct type *type,
417                     struct regcache *regcache,
418                     gdb_byte * readbuf, const gdb_byte * writebuf)
419 {
420   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
421       || TYPE_CODE (type) == TYPE_CODE_UNION
422       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
423     return RETURN_VALUE_STRUCT_CONVENTION;
424   else
425     {
426       int offset;
427       int regnum;
428       for (offset = 0, regnum = SCORE_A0_REGNUM;
429            offset < TYPE_LENGTH (type);
430            offset += SCORE_REGSIZE, regnum++)
431         {
432           int xfer = SCORE_REGSIZE;
433           if (offset + xfer > TYPE_LENGTH (type))
434             xfer = TYPE_LENGTH (type) - offset;
435           score_xfer_register (regcache, regnum, xfer,
436                                gdbarch_byte_order (gdbarch),
437                                readbuf, writebuf, offset);
438         }
439       return RETURN_VALUE_REGISTER_CONVENTION;
440     }
441 }
442
443 static struct frame_id
444 score_unwind_dummy_id (struct gdbarch *gdbarch,
445                        struct frame_info *next_frame)
446 {
447   return frame_id_build (
448            frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
449            frame_pc_unwind (next_frame));
450 }
451
452 static int
453 score_type_needs_double_align (struct type *type)
454 {
455   enum type_code typecode = TYPE_CODE (type);
456
457   if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
458       || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
459     return 1;
460   else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
461     {
462       int i, n;
463
464       n = TYPE_NFIELDS (type);
465       for (i = 0; i < n; i++)
466         if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
467           return 1;
468       return 0;
469     }
470   return 0;
471 }
472
473 static CORE_ADDR
474 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
475                        struct regcache *regcache, CORE_ADDR bp_addr,
476                        int nargs, struct value **args, CORE_ADDR sp,
477                        int struct_return, CORE_ADDR struct_addr)
478 {
479   int argnum;
480   int argreg;
481   int arglen = 0;
482   CORE_ADDR stack_offset = 0;
483   CORE_ADDR addr = 0;
484
485   /* Step 1, Save RA.  */
486   regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
487
488   /* Step 2, Make space on the stack for the args.  */
489   struct_addr = align_down (struct_addr, 16);
490   sp = align_down (sp, 16);
491   for (argnum = 0; argnum < nargs; argnum++)
492     arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
493                         SCORE_REGSIZE);
494   sp -= align_up (arglen, 16);
495
496   argreg = SCORE_BEGIN_ARG_REGNUM;
497
498   /* Step 3, Check if struct return then save the struct address to
499      r4 and increase the stack_offset by 4.  */
500   if (struct_return)
501     {
502       regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
503       stack_offset += SCORE_REGSIZE;
504     }
505
506   /* Step 4, Load arguments:
507      If arg length is too long (> 4 bytes), then split the arg and
508      save every parts.  */
509   for (argnum = 0; argnum < nargs; argnum++)
510     {
511       struct value *arg = args[argnum];
512       struct type *arg_type = check_typedef (value_type (arg));
513       enum type_code typecode = TYPE_CODE (arg_type);
514       const gdb_byte *val = value_contents (arg);
515       int downward_offset = 0;
516       int odd_sized_struct_p;
517       int arg_last_part_p = 0;
518
519       arglen = TYPE_LENGTH (arg_type);
520       odd_sized_struct_p = (arglen > SCORE_REGSIZE
521                             && arglen % SCORE_REGSIZE != 0);
522
523       /* If a arg should be aligned to 8 bytes (long long or double),
524          the value should be put to even register numbers.  */
525       if (score_type_needs_double_align (arg_type))
526         {
527           if (argreg & 1)
528             argreg++;
529         }
530
531       /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
532          the default "downward"/"upward" method:
533
534          Example:
535
536          struct struc
537          {
538            char a; char b; char c;
539          } s = {'a', 'b', 'c'};
540
541          Big endian:    s = {X, 'a', 'b', 'c'}
542          Little endian: s = {'a', 'b', 'c', X}
543
544          Where X is a hole.  */
545
546       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
547           && (typecode == TYPE_CODE_STRUCT
548               || typecode == TYPE_CODE_UNION)
549           && argreg > SCORE_LAST_ARG_REGNUM
550           && arglen < SCORE_REGSIZE)
551         downward_offset += (SCORE_REGSIZE - arglen);
552
553       while (arglen > 0)
554         {
555           int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
556           ULONGEST regval = extract_unsigned_integer (val, partial_len);
557
558           /* The last part of a arg should shift left when
559              gdbarch_byte_order is BFD_ENDIAN_BIG.  */
560           if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
561               && arg_last_part_p == 1
562               && (typecode == TYPE_CODE_STRUCT
563                   || typecode == TYPE_CODE_UNION))
564             regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
565
566           /* Always increase the stack_offset and save args to stack.  */
567           addr = sp + stack_offset + downward_offset;
568           write_memory (addr, val, partial_len);
569
570           if (argreg <= SCORE_LAST_ARG_REGNUM)
571             {
572               regcache_cooked_write_unsigned (regcache, argreg++, regval);
573               if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
574                 arg_last_part_p = 1;
575             }
576
577           val += partial_len;
578           arglen -= partial_len;
579           stack_offset += align_up (partial_len, SCORE_REGSIZE);
580         }
581     }
582
583   /* Step 5, Save SP.  */
584   regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
585
586   return sp;
587 }
588
589 static char *
590 score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
591 {
592   int ret;
593   char *memblock = NULL;
594
595   if (size < 0)
596     {
597       error ("Error: malloc size < 0 in file:%s, line:%d!",
598              __FILE__, __LINE__);
599       return NULL;
600     }
601   else if (size == 0)
602     return NULL;
603
604   memblock = (char *) xmalloc (size);
605   memset (memblock, 0, size);
606   ret = target_read_memory (addr & ~0x3, memblock, size);
607   if (ret)
608     {
609       error ("Error: target_read_memory in file:%s, line:%d!",
610              __FILE__, __LINE__);
611       return NULL;
612     }
613   return memblock;
614 }
615
616 static void
617 score_free_memblock (char *memblock)
618 {
619   xfree (memblock);
620 }
621
622 static void
623 score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
624                            CORE_ADDR cur_pc)
625 {
626   if (prev_pc == -1)
627     {
628       /* First time call this function, do nothing.  */
629     }
630   else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
631     {
632       /* First 16-bit instruction, then 32-bit instruction.  */
633       *memblock += SCORE_INSTLEN;
634     }
635   else if (cur_pc - prev_pc == 4)
636     {
637       /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
638       *memblock += SCORE_INSTLEN;
639     }
640 }
641
642 static inst_t *
643 score_fetch_inst (CORE_ADDR addr, char *memblock)
644 {
645   static inst_t inst = { 0, 0 };
646   char buf[SCORE_INSTLEN] = { 0 };
647   int big;
648   int ret;
649
650   if (target_has_execution && memblock != NULL)
651     {
652       /* Fetch instruction from local MEMBLOCK.  */
653       memcpy (buf, memblock, SCORE_INSTLEN);
654     }
655   else
656     {
657       /* Fetch instruction from target.  */
658       ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
659       if (ret)
660         {
661           error ("Error: target_read_memory in file:%s, line:%d!",
662                   __FILE__, __LINE__);
663           return 0;
664         }
665     }
666
667   inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
668   inst.is15 = !(inst.raw & 0x80008000);
669   inst.v = RM_PBITS (inst.raw);
670   big = (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG);
671   if (inst.is15)
672     {
673       if (big ^ ((addr & 0x2) == 2))
674         inst.v = G_FLD (inst.v, 29, 15);
675       else
676         inst.v = G_FLD (inst.v, 14, 0);
677     }
678   return &inst;
679 }
680
681 static CORE_ADDR
682 score_skip_prologue (CORE_ADDR pc)
683 {
684   CORE_ADDR cpc = pc;
685   int iscan = 32, stack_sub = 0;
686   while (iscan-- > 0)
687     {
688       inst_t *inst = score_fetch_inst (cpc, NULL);
689       if (!inst)
690         break;
691       if (!inst->is15 && !stack_sub
692           && (G_FLD (inst->v, 29, 25) == 0x1
693               && G_FLD (inst->v, 24, 20) == 0x0))
694         {
695           /* addi r0, offset */
696           pc = stack_sub = cpc + SCORE_INSTLEN;
697         }
698       else if (!inst->is15
699                && inst->v == RM_PBITS (0x8040bc56))
700         {
701           /* mv r2, r0  */
702           pc = cpc + SCORE_INSTLEN;
703           break;
704         }
705       else if (inst->is15
706                && inst->v == RM_PBITS (0x0203))
707         {
708           /* mv! r2, r0 */
709           pc = cpc + SCORE16_INSTLEN;
710           break;
711         }
712       else if (inst->is15
713                && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
714                    || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
715                    || (G_FLD (inst->v, 14, 12) == 0x0
716                        && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
717         break;
718       else if (!inst->is15
719                && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
720                    || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
721                    || (G_FLD (inst->v, 29, 25) == 0x0
722                        && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
723         break;
724
725       cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
726     }
727   return pc;
728 }
729
730 static int
731 score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
732 {
733   inst_t *inst = score_fetch_inst (cur_pc, NULL);
734
735   if (inst->v == 0x23)
736     return 1;   /* mv! r0, r2 */
737   else if (G_FLD (inst->v, 14, 12) == 0x2
738            && G_FLD (inst->v, 3, 0) == 0xa)
739     return 1;   /* pop! */
740   else if (G_FLD (inst->v, 14, 12) == 0x0
741            && G_FLD (inst->v, 7, 0) == 0x34)
742     return 1;   /* br! r3 */
743   else if (G_FLD (inst->v, 29, 15) == 0x2
744            && G_FLD (inst->v, 6, 1) == 0x2b)
745     return 1;   /* mv r0, r2 */
746   else if (G_FLD (inst->v, 29, 25) == 0x0
747            && G_FLD (inst->v, 6, 1) == 0x4
748            && G_FLD (inst->v, 19, 15) == 0x3)
749     return 1;   /* br r3 */
750   else
751     return 0;
752 }
753
754 static void
755 score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
756                         struct frame_info *next_frame,
757                         struct score_frame_cache *this_cache)
758 {
759   CORE_ADDR sp;
760   CORE_ADDR fp;
761   CORE_ADDR cur_pc = startaddr;
762
763   int sp_offset = 0;
764   int ra_offset = 0;
765   int fp_offset = 0;
766   int ra_offset_p = 0;
767   int fp_offset_p = 0;
768   int inst_len = 0;
769
770   char *memblock = NULL;
771   char *memblock_ptr = NULL;
772   CORE_ADDR prev_pc = -1;
773
774   /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
775   memblock_ptr = memblock =
776     score_malloc_and_get_memblock (startaddr, pc - startaddr);
777
778   sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
779   fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
780
781   for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
782     {
783       inst_t *inst = NULL;
784       if (memblock != NULL)
785         {
786           /* Reading memory block from target succefully and got all
787              the instructions(from STARTADDR to PC) needed.  */
788           score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
789           inst = score_fetch_inst (cur_pc, memblock);
790         }
791       else
792         {
793           /* Otherwise, we fetch 4 bytes from target, and GDB also
794              work correctly.  */
795           inst = score_fetch_inst (cur_pc, NULL);
796         }
797
798       if (inst->is15 == 1)
799         {
800           inst_len = SCORE16_INSTLEN;
801
802           if (G_FLD (inst->v, 14, 12) == 0x2
803               && G_FLD (inst->v, 3, 0) == 0xe)
804             {
805               /* push! */
806               sp_offset += 4;
807
808               if (G_FLD (inst->v, 11, 7) == 0x6
809                   && ra_offset_p == 0)
810                 {
811                   /* push! r3, [r0] */
812                   ra_offset = sp_offset;
813                   ra_offset_p = 1;
814                 }
815               else if (G_FLD (inst->v, 11, 7) == 0x4
816                        && fp_offset_p == 0)
817                 {
818                   /* push! r2, [r0] */
819                   fp_offset = sp_offset;
820                   fp_offset_p = 1;
821                 }
822             }
823           else if (G_FLD (inst->v, 14, 12) == 0x2
824                    && G_FLD (inst->v, 3, 0) == 0xa)
825             {
826               /* pop! */
827               sp_offset -= 4;
828             }
829           else if (G_FLD (inst->v, 14, 7) == 0xc1
830                    && G_FLD (inst->v, 2, 0) == 0x0)
831             {
832               /* subei! r0, n */
833               sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
834             }
835           else if (G_FLD (inst->v, 14, 7) == 0xc0
836                    && G_FLD (inst->v, 2, 0) == 0x0)
837             {
838               /* addei! r0, n */
839               sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
840             }
841         }
842       else
843         {
844           inst_len = SCORE_INSTLEN;
845
846           if (G_FLD (inst->v, 29, 15) == 0xc60
847               && G_FLD (inst->v, 2, 0) == 0x4)
848             {
849               /* sw r3, [r0, offset]+ */
850               sp_offset += SCORE_INSTLEN;
851               if (ra_offset_p == 0)
852                 {
853                   ra_offset = sp_offset;
854                   ra_offset_p = 1;
855                 }
856             }
857           if (G_FLD (inst->v, 29, 15) == 0xc40
858               && G_FLD (inst->v, 2, 0) == 0x4)
859             {
860               /* sw r2, [r0, offset]+ */
861               sp_offset += SCORE_INSTLEN;
862               if (fp_offset_p == 0)
863                 {
864                   fp_offset = sp_offset;
865                   fp_offset_p = 1;
866                 }
867             }
868           else if (G_FLD (inst->v, 29, 15) == 0x1c60
869                    && G_FLD (inst->v, 2, 0) == 0x0)
870             {
871               /* lw r3, [r0]+, 4 */
872               sp_offset -= SCORE_INSTLEN;
873               ra_offset_p = 1;
874             }
875           else if (G_FLD (inst->v, 29, 15) == 0x1c40
876                    && G_FLD (inst->v, 2, 0) == 0x0)
877             {
878               /* lw r2, [r0]+, 4 */
879               sp_offset -= SCORE_INSTLEN;
880               fp_offset_p = 1;
881             }
882
883           else if (G_FLD (inst->v, 29, 17) == 0x100
884                    && G_FLD (inst->v, 0, 0) == 0x0)
885             {
886               /* addi r0, -offset */
887               sp_offset += 65536 - G_FLD (inst->v, 16, 1);
888             }
889           else if (G_FLD (inst->v, 29, 17) == 0x110
890                    && G_FLD (inst->v, 0, 0) == 0x0)
891             {
892               /* addi r2, offset */
893               if (pc - cur_pc > 4)
894                 {
895                   unsigned int save_v = inst->v;
896                   inst_t *inst2 =
897                     score_fetch_inst (cur_pc + SCORE_INSTLEN, NULL);
898                   if (inst2->v == 0x23)
899                     {
900                       /* mv! r0, r2 */
901                       sp_offset -= G_FLD (save_v, 16, 1);
902                     }
903                 }
904             }
905         }
906     }
907
908   /* Save RA.  */
909   if (ra_offset_p == 1)
910     {
911       if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
912         this_cache->saved_regs[SCORE_PC_REGNUM].addr =
913           sp + sp_offset - ra_offset;
914     }
915   else
916     {
917       this_cache->saved_regs[SCORE_PC_REGNUM] =
918         this_cache->saved_regs[SCORE_RA_REGNUM];
919     }
920
921   /* Save FP.  */
922   if (fp_offset_p == 1)
923     {
924       if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
925         this_cache->saved_regs[SCORE_FP_REGNUM].addr =
926           sp + sp_offset - fp_offset;
927     }
928
929   /* Save SP and FP.  */
930   this_cache->base = sp + sp_offset;
931   this_cache->fp = fp;
932
933   /* Don't forget to free MEMBLOCK if we allocated it.  */
934   if (memblock_ptr != NULL)
935     score_free_memblock (memblock_ptr);
936 }
937
938 static struct score_frame_cache *
939 score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
940 {
941   struct score_frame_cache *cache;
942
943   if ((*this_cache) != NULL)
944     return (*this_cache);
945
946   cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
947   (*this_cache) = cache;
948   cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
949
950   /* Analyze the prologue.  */
951   {
952     const CORE_ADDR pc = frame_pc_unwind (next_frame);
953     CORE_ADDR start_addr;
954
955     find_pc_partial_function (pc, NULL, &start_addr, NULL);
956     if (start_addr == 0)
957       return cache;
958     score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
959   }
960
961   /* Save SP.  */
962   trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
963
964   return (*this_cache);
965 }
966
967 static void
968 score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
969                         struct frame_id *this_id)
970 {
971   struct score_frame_cache *info = score_make_prologue_cache (next_frame,
972                                                               this_cache);
973   (*this_id) = frame_id_build (info->base,
974                                frame_func_unwind (next_frame, NORMAL_FRAME));
975 }
976
977 static void
978 score_prologue_prev_register (struct frame_info *next_frame,
979                               void **this_cache,
980                               int regnum, int *optimizedp,
981                               enum lval_type *lvalp, CORE_ADDR * addrp,
982                               int *realnump, gdb_byte * valuep)
983 {
984   struct score_frame_cache *info = score_make_prologue_cache (next_frame,
985                                                               this_cache);
986   trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
987                                 optimizedp, lvalp, addrp, realnump, valuep);
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 };
996
997 static const struct frame_unwind *
998 score_prologue_sniffer (struct frame_info *next_frame)
999 {
1000   return &score_prologue_unwind;
1001 }
1002
1003 static CORE_ADDR
1004 score_prologue_frame_base_address (struct frame_info *next_frame,
1005                                    void **this_cache)
1006 {
1007   struct score_frame_cache *info =
1008     score_make_prologue_cache (next_frame, this_cache);
1009   return info->fp;
1010 }
1011
1012 static const struct frame_base score_prologue_frame_base =
1013 {
1014   &score_prologue_unwind,
1015   score_prologue_frame_base_address,
1016   score_prologue_frame_base_address,
1017   score_prologue_frame_base_address,
1018 };
1019
1020 static const struct frame_base *
1021 score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1022 {
1023   return &score_prologue_frame_base;
1024 }
1025
1026 static struct gdbarch *
1027 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1028 {
1029   struct gdbarch *gdbarch;
1030
1031   arches = gdbarch_list_lookup_by_info (arches, &info);
1032   if (arches != NULL)
1033     {
1034       return (arches->gdbarch);
1035     }
1036   gdbarch = gdbarch_alloc (&info, 0);
1037
1038   set_gdbarch_short_bit (gdbarch, 16);
1039   set_gdbarch_int_bit (gdbarch, 32);
1040   set_gdbarch_float_bit (gdbarch, 32);
1041   set_gdbarch_double_bit (gdbarch, 64);
1042   set_gdbarch_long_double_bit (gdbarch, 64);
1043   set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1044   set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1045   set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1046   set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1047   set_gdbarch_register_name (gdbarch, score_register_name);
1048   set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1049   set_gdbarch_register_type (gdbarch, score_register_type);
1050   set_gdbarch_frame_align (gdbarch, score_frame_align);
1051   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1052   set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1053   set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1054   set_gdbarch_print_insn (gdbarch, score_print_insn);
1055   set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1056   set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
1057
1058   /* Watchpoint hooks.  */
1059   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1060
1061   /* Dummy frame hooks.  */
1062   set_gdbarch_return_value (gdbarch, score_return_value);
1063   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1064   set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
1065   set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1066
1067   /* Normal frame hooks.  */
1068   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1069   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1070   frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
1071   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1072
1073   return gdbarch;
1074 }
1075
1076 extern initialize_file_ftype _initialize_score_tdep;
1077
1078 void
1079 _initialize_score_tdep (void)
1080 {
1081   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1082 }