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
43typedef struct{
44    unsigned int v;
45    unsigned int raw;
46    char         is15;
47}inst_t;
48
49struct 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
74typedef struct frame_extra_info
75{
76  CORE_ADDR p_frame;
77  unsigned int pdr[P_SIZE];
78} extra_info_t;
79
80struct obj_priv
81{
82  bfd_size_type size;
83  char *contents;
84};
85
86static bfd *the_bfd;
87
88static int
89score_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
101static void
102score_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
188int
189score_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
201int
202score_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
214int
215score_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
227int
228score_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
240int
241score_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
253int
254score_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
267static struct type *
268score_register_type (struct gdbarch *gdbarch, int regnum)
269{
270  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
271  return builtin_type_uint32;
272}
273
274static CORE_ADDR
275score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
276{
277  return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
278}
279
280static CORE_ADDR
281score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
282{
283  return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
284}
285
286static const char *
287score_register_name (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
307static int
308score_register_sim_regno (int regnum)
309{
310  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
311  return regnum;
312}
313
314static int
315score_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
323static const gdb_byte *
324score_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
377static CORE_ADDR
378score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
379{
380  return align_down (addr, 16);
381}
382
383static void
384score_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
415static enum return_value_convention
416score_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 (current_gdbarch),
437                               readbuf, writebuf, offset);
438        }
439      return RETURN_VALUE_REGISTER_CONVENTION;
440    }
441}
442
443static struct frame_id
444score_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
452static int
453score_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
473static CORE_ADDR
474score_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 (current_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 (current_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
589static char *
590score_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
616static void
617score_free_memblock (char *memblock)
618{
619  xfree (memblock);
620}
621
622static void
623score_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
642static inst_t *
643score_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
681static CORE_ADDR
682score_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
730static int
731score_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
754static void
755score_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
938static struct score_frame_cache *
939score_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
967static void
968score_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
977static void
978score_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
990static const struct frame_unwind score_prologue_unwind =
991{
992  NORMAL_FRAME,
993  score_prologue_this_id,
994  score_prologue_prev_register
995};
996
997static const struct frame_unwind *
998score_prologue_sniffer (struct frame_info *next_frame)
999{
1000  return &score_prologue_unwind;
1001}
1002
1003static CORE_ADDR
1004score_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
1012static 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
1020static const struct frame_base *
1021score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1022{
1023  return &score_prologue_frame_base;
1024}
1025
1026static struct gdbarch *
1027score_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
1076extern initialize_file_ftype _initialize_score_tdep;
1077
1078void
1079_initialize_score_tdep (void)
1080{
1081  gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1082}
1083