New gdbarch methods breakpoint_kind_from_pc and sw_breakpoint_from_kind
[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-2016 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 "inferior.h"
26 #include "symtab.h"
27 #include "objfiles.h"
28 #include "gdbcore.h"
29 #include "target.h"
30 #include "arch-utils.h"
31 #include "regcache.h"
32 #include "regset.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) \
41     ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
42
43 typedef struct{
44   unsigned long long v;
45   unsigned long long raw;
46   unsigned int len;
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 static int target_mach = bfd_mach_score7;
57
58 static struct type *
59 score_register_type (struct gdbarch *gdbarch, int regnum)
60 {
61   gdb_assert (regnum >= 0 
62               && regnum < ((target_mach == bfd_mach_score7)
63                            ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
64   return builtin_type (gdbarch)->builtin_uint32;
65 }
66
67 static CORE_ADDR
68 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
69 {
70   return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
71 }
72
73 static CORE_ADDR
74 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
75 {
76   return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
77 }
78
79 static const char *
80 score7_register_name (struct gdbarch *gdbarch, int regnum)
81 {
82   const char *score_register_names[] = {
83     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
84     "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
85     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
86     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
87
88     "PSR",     "COND",  "ECR",     "EXCPVEC", "CCR",
89     "EPC",     "EMA",   "TLBLOCK", "TLBPT",   "PEADDR",
90     "TLBRPT",  "PEVN",  "PECTX",   "LIMPFN",  "LDMPFN", 
91     "PREV",    "DREG",  "PC",      "DSAVE",   "COUNTER",
92     "LDCR",    "STCR",  "CEH",     "CEL",
93   };
94
95   gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
96   return score_register_names[regnum];
97 }
98
99 static const char *
100 score3_register_name (struct gdbarch *gdbarch, int regnum)
101 {
102   const char *score_register_names[] = {
103     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
104     "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
105     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
106     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
107
108     "PSR",      "COND",   "ECR",   "EXCPVEC",  "CCR",
109     "EPC",      "EMA",    "PREV",  "DREG",     "DSAVE",
110     "COUNTER",  "LDCR",   "STCR",  "CEH",      "CEL",
111     "",         "",       "PC",
112   };
113
114   gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
115   return score_register_names[regnum];
116 }
117
118 #if WITH_SIM
119 static int
120 score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
121 {
122   gdb_assert (regnum >= 0 
123               && regnum < ((target_mach == bfd_mach_score7)
124                            ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
125   return regnum;
126 }
127 #endif
128
129 static int
130 score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
131 {
132   if (info->endian == BFD_ENDIAN_BIG)
133     return print_insn_big_score (memaddr, info);
134   else
135     return print_insn_little_score (memaddr, info);
136 }
137
138 static inst_t *
139 score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock)
140 {
141   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
142   static inst_t inst = { 0, 0, 0 };
143   gdb_byte buf[SCORE_INSTLEN] = { 0 };
144   int big;
145   int ret;
146
147   if (target_has_execution && memblock != NULL)
148     {
149       /* Fetch instruction from local MEMBLOCK.  */
150       memcpy (buf, memblock, SCORE_INSTLEN);
151     }
152   else
153     {
154       /* Fetch instruction from target.  */
155       ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
156       if (ret)
157         {
158           error (_("Error: target_read_memory in file:%s, line:%d!"),
159                   __FILE__, __LINE__);
160           return 0;
161         }
162     }
163
164   inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
165   inst.len = (inst.raw & 0x80008000) ? 4 : 2;
166   inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); 
167   big = (byte_order == BFD_ENDIAN_BIG);
168   if (inst.len == 2)
169     {
170       if (big ^ ((addr & 0x2) == 2))
171         inst.v = G_FLD (inst.v, 29, 15);
172       else
173         inst.v = G_FLD (inst.v, 14, 0);
174     }
175   return &inst;
176 }
177
178 static inst_t *
179 score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
180                                  enum bfd_endian byte_order)
181 {
182   static inst_t inst = { 0, 0, 0 };
183
184   struct breakplace
185   {
186     int break_offset;
187     int inst_len;
188   };
189   /*     raw        table 1 (column 2, 3, 4)
190     *  0  1  0  *   # 2
191     *  0  1  1  0   # 3
192     0  1  1  0  *   # 6
193                     table 2 (column 1, 2, 3)
194     *  0  0  *  *   # 0, 4
195     0  1  0  *  *   # 2
196     1  1  0  *  *   # 6
197    */
198
199   static const struct breakplace bk_table[16] =
200     {
201       /* table 1 */
202       {0, 0},
203       {0, 0},
204       {0, 4},
205       {0, 6},
206       {0, 0},
207       {0, 0},
208       {-2, 6},
209       {0, 0},
210       /* table 2 */
211       {0, 2},
212       {0, 0},
213       {-2, 4},
214       {0, 0},
215       {0, 2},
216       {0, 0},
217       {-4, 6},
218       {0, 0}
219     };
220
221 #define EXTRACT_LEN 2
222   CORE_ADDR adjust_pc = *pcptr & ~0x1;
223   gdb_byte buf[5][EXTRACT_LEN] =
224     {
225       {'\0', '\0'},
226       {'\0', '\0'},
227       {'\0', '\0'},
228       {'\0', '\0'},
229       {'\0', '\0'}
230     };
231   int ret;
232   unsigned int raw;
233   unsigned int cbits = 0;
234   int bk_index;
235   int i, count;
236
237   inst.v = 0;
238   inst.raw = 0;
239   inst.len = 0;
240
241   adjust_pc -= 4;
242   for (i = 0; i < 5; i++)
243     {
244       ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
245       if (ret != 0)
246         {
247           buf[i][0] = '\0';
248           buf[i][1] = '\0';
249           if (i == 2)
250             error (_("Error: target_read_memory in file:%s, line:%d!"),
251                    __FILE__, __LINE__);
252         }
253
254       raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
255       cbits = (cbits << 1) | (raw >> 15); 
256     }
257   adjust_pc += 4;
258
259   if (cbits & 0x4)
260     {
261       /* table 1 */
262       cbits = (cbits >> 1) & 0x7;
263       bk_index = cbits;
264     }
265   else
266     {
267       /* table 2 */
268       cbits = (cbits >> 2) & 0x7;
269       bk_index = cbits + 8; 
270     }
271
272   gdb_assert (!((bk_table[bk_index].break_offset == 0)
273                 && (bk_table[bk_index].inst_len == 0)));
274
275   inst.len = bk_table[bk_index].inst_len;
276
277   i = (bk_table[bk_index].break_offset + 4) / 2;
278   count = inst.len / 2;
279   for (; count > 0; i++, count--)
280     {
281       inst.raw = (inst.raw << 16)
282                  | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
283     }
284
285   switch (inst.len)
286     {
287     case 2:
288       inst.v = inst.raw & 0x7FFF;
289       break;
290     case 4:
291       inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
292       break;
293     case 6:
294       inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
295                | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
296       break;
297     }
298
299   if (pcptr)
300     *pcptr = adjust_pc + bk_table[bk_index].break_offset;
301   if (lenptr)
302     *lenptr = bk_table[bk_index].inst_len;
303
304 #undef EXTRACT_LEN
305
306   return &inst;
307 }
308
309 /* Implement the breakpoint_kind_from_pc gdbarch method.  */
310
311 static int
312 score7_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
313 {
314   int ret;
315   unsigned int raw;
316   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
317   gdb_byte buf[SCORE_INSTLEN] = { 0 };
318
319   if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
320     {
321       error (_("Error: target_read_memory in file:%s, line:%d!"),
322              __FILE__, __LINE__);
323     }
324   raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
325
326   if (!(raw & 0x80008000))
327     {
328       /* 16bits instruction.  */
329       *pcptr &= ~0x1;
330       return 2;
331     }
332   else
333     {
334       /* 32bits instruction.  */
335       *pcptr &= ~0x3;
336       return 4;
337     }
338 }
339
340 /* Implement the sw_breakpoint_from_kind gdbarch method.  */
341
342 static const gdb_byte *
343 score7_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
344 {
345   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
346
347   *size = kind;
348
349   if (kind == 4)
350     {
351       static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
352       static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
353
354       if (byte_order == BFD_ENDIAN_BIG)
355         return big_breakpoint32;
356       else
357         return little_breakpoint32;
358     }
359   else
360     {
361       static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
362       static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
363
364       if (byte_order == BFD_ENDIAN_BIG)
365         return big_breakpoint16;
366       else
367         return little_breakpoint16;
368     }
369 }
370
371 GDBARCH_BREAKPOINT_FROM_PC (score7)
372
373 /* Implement the breakpoint_kind_from_pc gdbarch method.  */
374
375 static int
376 score3_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
377 {
378   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
379   int len;
380
381   score3_adjust_pc_and_fetch_inst (pcptr, &len, byte_order);
382
383   return len;
384 }
385
386 /* Implement the sw_breakpoint_from_kind gdbarch method.  */
387
388 static const gdb_byte *
389 score3_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
390 {
391   int index = 0;
392   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
393   static gdb_byte score_break_insns[6][6] = {
394     /* The following three instructions are big endian.  */
395     { 0x00, 0x20 },
396     { 0x80, 0x00, 0x00, 0x06 },
397     { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
398     /* The following three instructions are little endian.  */
399     { 0x20, 0x00 },
400     { 0x00, 0x80, 0x06, 0x00 },
401     { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
402
403   *size = kind;
404
405   index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (kind / 2 - 1);
406   return score_break_insns[index];
407 }
408
409 GDBARCH_BREAKPOINT_FROM_PC (score3)
410
411 static CORE_ADDR
412 score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
413 {
414   CORE_ADDR adjust_pc = bpaddr; 
415
416   if (target_mach == bfd_mach_score3)
417     score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
418                                      gdbarch_byte_order (gdbarch));
419   else
420     adjust_pc = align_down (adjust_pc, 2);
421   
422   return adjust_pc;
423 }
424
425 static CORE_ADDR
426 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
427 {
428   return align_down (addr, 16);
429 }
430
431 static void
432 score_xfer_register (struct regcache *regcache, int regnum, int length,
433                      enum bfd_endian endian, gdb_byte *readbuf,
434                      const gdb_byte *writebuf, int buf_offset)
435 {
436   int reg_offset = 0;
437   gdb_assert (regnum >= 0 
438               && regnum < ((target_mach == bfd_mach_score7)
439                            ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
440
441   switch (endian)
442     {
443     case BFD_ENDIAN_BIG:
444       reg_offset = SCORE_REGSIZE - length;
445       break;
446     case BFD_ENDIAN_LITTLE:
447       reg_offset = 0;
448       break;
449     case BFD_ENDIAN_UNKNOWN:
450       reg_offset = 0;
451       break;
452     default:
453       error (_("Error: score_xfer_register in file:%s, line:%d!"),
454              __FILE__, __LINE__);
455     }
456
457   if (readbuf != NULL)
458     regcache_cooked_read_part (regcache, regnum, reg_offset, length,
459                                readbuf + buf_offset);
460   if (writebuf != NULL)
461     regcache_cooked_write_part (regcache, regnum, reg_offset, length,
462                                 writebuf + buf_offset);
463 }
464
465 static enum return_value_convention
466 score_return_value (struct gdbarch *gdbarch, struct value *function,
467                     struct type *type, struct regcache *regcache,
468                     gdb_byte * readbuf, const gdb_byte * writebuf)
469 {
470   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
471       || TYPE_CODE (type) == TYPE_CODE_UNION
472       || TYPE_CODE (type) == TYPE_CODE_ARRAY)
473     return RETURN_VALUE_STRUCT_CONVENTION;
474   else
475     {
476       int offset;
477       int regnum;
478       for (offset = 0, regnum = SCORE_A0_REGNUM;
479            offset < TYPE_LENGTH (type);
480            offset += SCORE_REGSIZE, regnum++)
481         {
482           int xfer = SCORE_REGSIZE;
483
484           if (offset + xfer > TYPE_LENGTH (type))
485             xfer = TYPE_LENGTH (type) - offset;
486           score_xfer_register (regcache, regnum, xfer,
487                                gdbarch_byte_order(gdbarch),
488                                readbuf, writebuf, offset);
489         }
490       return RETURN_VALUE_REGISTER_CONVENTION;
491     }
492 }
493
494 static struct frame_id
495 score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
496 {
497   return frame_id_build (get_frame_register_unsigned (this_frame,
498                                                       SCORE_SP_REGNUM),
499                          get_frame_pc (this_frame));
500 }
501
502 static int
503 score_type_needs_double_align (struct type *type)
504 {
505   enum type_code typecode = TYPE_CODE (type);
506
507   if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
508       || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
509     return 1;
510   else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
511     {
512       int i, n;
513
514       n = TYPE_NFIELDS (type);
515       for (i = 0; i < n; i++)
516         if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
517           return 1;
518       return 0;
519     }
520   return 0;
521 }
522
523 static CORE_ADDR
524 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
525                        struct regcache *regcache, CORE_ADDR bp_addr,
526                        int nargs, struct value **args, CORE_ADDR sp,
527                        int struct_return, CORE_ADDR struct_addr)
528 {
529   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
530   int argnum;
531   int argreg;
532   int arglen = 0;
533   CORE_ADDR stack_offset = 0;
534   CORE_ADDR addr = 0;
535
536   /* Step 1, Save RA.  */
537   regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
538
539   /* Step 2, Make space on the stack for the args.  */
540   struct_addr = align_down (struct_addr, 16);
541   sp = align_down (sp, 16);
542   for (argnum = 0; argnum < nargs; argnum++)
543     arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
544                         SCORE_REGSIZE);
545   sp -= align_up (arglen, 16);
546
547   argreg = SCORE_BEGIN_ARG_REGNUM;
548
549   /* Step 3, Check if struct return then save the struct address to
550      r4 and increase the stack_offset by 4.  */
551   if (struct_return)
552     {
553       regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
554       stack_offset += SCORE_REGSIZE;
555     }
556
557   /* Step 4, Load arguments:
558      If arg length is too long (> 4 bytes), then split the arg and
559      save every parts.  */
560   for (argnum = 0; argnum < nargs; argnum++)
561     {
562       struct value *arg = args[argnum];
563       struct type *arg_type = check_typedef (value_type (arg));
564       enum type_code typecode = TYPE_CODE (arg_type);
565       const gdb_byte *val = value_contents (arg);
566       int downward_offset = 0;
567       int arg_last_part_p = 0;
568
569       arglen = TYPE_LENGTH (arg_type);
570
571       /* If a arg should be aligned to 8 bytes (long long or double),
572          the value should be put to even register numbers.  */
573       if (score_type_needs_double_align (arg_type))
574         {
575           if (argreg & 1)
576             argreg++;
577         }
578
579       /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
580          the default "downward"/"upward" method:
581
582          Example:
583
584          struct struc
585          {
586            char a; char b; char c;
587          } s = {'a', 'b', 'c'};
588
589          Big endian:    s = {X, 'a', 'b', 'c'}
590          Little endian: s = {'a', 'b', 'c', X}
591
592          Where X is a hole.  */
593
594       if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
595           && (typecode == TYPE_CODE_STRUCT
596               || typecode == TYPE_CODE_UNION)
597           && argreg > SCORE_LAST_ARG_REGNUM
598           && arglen < SCORE_REGSIZE)
599         downward_offset += (SCORE_REGSIZE - arglen);
600
601       while (arglen > 0)
602         {
603           int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
604           ULONGEST regval = extract_unsigned_integer (val, partial_len,
605                                                       byte_order);
606
607           /* The last part of a arg should shift left when
608              gdbarch_byte_order is BFD_ENDIAN_BIG.  */
609           if (byte_order == BFD_ENDIAN_BIG
610               && arg_last_part_p == 1
611               && (typecode == TYPE_CODE_STRUCT
612                   || typecode == TYPE_CODE_UNION))
613             regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
614
615           /* Always increase the stack_offset and save args to stack.  */
616           addr = sp + stack_offset + downward_offset;
617           write_memory (addr, val, partial_len);
618
619           if (argreg <= SCORE_LAST_ARG_REGNUM)
620             {
621               regcache_cooked_write_unsigned (regcache, argreg++, regval);
622               if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
623                 arg_last_part_p = 1;
624             }
625
626           val += partial_len;
627           arglen -= partial_len;
628           stack_offset += align_up (partial_len, SCORE_REGSIZE);
629         }
630     }
631
632   /* Step 5, Save SP.  */
633   regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
634
635   return sp;
636 }
637
638 static CORE_ADDR
639 score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
640 {
641   CORE_ADDR cpc = pc;
642   int iscan = 32, stack_sub = 0;
643   while (iscan-- > 0)
644     {
645       inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
646       if (!inst)
647         break;
648       if ((inst->len == 4) && !stack_sub
649           && (G_FLD (inst->v, 29, 25) == 0x1
650               && G_FLD (inst->v, 24, 20) == 0x0))
651         {
652           /* addi r0, offset */
653           stack_sub = cpc + SCORE_INSTLEN;
654           pc = cpc + SCORE_INSTLEN;
655         }
656       else if ((inst->len == 4)
657                && (G_FLD (inst->v, 29, 25) == 0x0)
658                && (G_FLD (inst->v, 24, 20) == 0x2)
659                && (G_FLD (inst->v, 19, 15) == 0x0)
660                && (G_FLD (inst->v, 14, 10) == 0xF)
661                && (G_FLD (inst->v, 9, 0) == 0x56))
662         {
663           /* mv r2, r0  */
664           pc = cpc + SCORE_INSTLEN;
665           break;
666         }
667       else if ((inst->len == 2)
668                && (G_FLD (inst->v, 14, 12) == 0x0)
669                && (G_FLD (inst->v, 11, 8) == 0x2)
670                && (G_FLD (inst->v, 7, 4) == 0x0)
671                && (G_FLD (inst->v, 3, 0) == 0x3))
672         {
673           /* mv! r2, r0 */
674           pc = cpc + SCORE16_INSTLEN;
675           break;
676         }
677       else if ((inst->len == 2)
678                && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
679                    || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
680                    || (G_FLD (inst->v, 14, 12) == 0x0
681                        && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
682         break;
683       else if ((inst->len == 4)
684                && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
685                    || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
686                    || (G_FLD (inst->v, 29, 25) == 0x0
687                        && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
688         break;
689
690       cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
691     }
692   return pc;
693 }
694
695 static CORE_ADDR
696 score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
697 {
698   CORE_ADDR cpc = pc;
699   int iscan = 32, stack_sub = 0;
700   while (iscan-- > 0)
701     {
702       inst_t *inst
703         = score3_adjust_pc_and_fetch_inst (&cpc, NULL,
704                                            gdbarch_byte_order (gdbarch));
705
706       if (!inst)
707         break;
708       if (inst->len == 4 && !stack_sub
709           && (G_FLD (inst->v, 29, 25) == 0x1)
710           && (G_FLD (inst->v, 19, 17) == 0x0)
711           && (G_FLD (inst->v, 24, 20) == 0x0))
712         {
713           /* addi r0, offset */
714           stack_sub = cpc + inst->len;
715           pc = cpc + inst->len;
716         }
717       else if (inst->len == 4
718                && (G_FLD (inst->v, 29, 25) == 0x0)
719                && (G_FLD (inst->v, 24, 20) == 0x2)
720                && (G_FLD (inst->v, 19, 15) == 0x0)
721                && (G_FLD (inst->v, 14, 10) == 0xF)
722                && (G_FLD (inst->v, 9, 0) == 0x56))
723         {
724           /* mv r2, r0  */
725           pc = cpc + inst->len;
726           break;
727         }
728       else if ((inst->len == 2)
729                && (G_FLD (inst->v, 14, 10) == 0x10)
730                && (G_FLD (inst->v, 9, 5) == 0x2)
731                && (G_FLD (inst->v, 4, 0) == 0x0))
732         {
733           /* mv! r2, r0 */
734           pc = cpc + inst->len;
735           break;
736         }
737       else if (inst->len == 2
738                && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
739                    || (G_FLD (inst->v, 14, 12) == 0x0
740                        && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
741         break;
742       else if (inst->len == 4
743                && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
744                    || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
745         break;
746
747       cpc += inst->len;
748     }
749   return pc;
750 }
751
752 /* Implement the stack_frame_destroyed_p gdbarch method. */
753
754 static int
755 score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
756 {
757   inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
758
759   if (inst->v == 0x23)
760     return 1;   /* mv! r0, r2 */
761   else if (G_FLD (inst->v, 14, 12) == 0x2
762            && G_FLD (inst->v, 3, 0) == 0xa)
763     return 1;   /* pop! */
764   else if (G_FLD (inst->v, 14, 12) == 0x0
765            && G_FLD (inst->v, 7, 0) == 0x34)
766     return 1;   /* br! r3 */
767   else if (G_FLD (inst->v, 29, 15) == 0x2
768            && G_FLD (inst->v, 6, 1) == 0x2b)
769     return 1;   /* mv r0, r2 */
770   else if (G_FLD (inst->v, 29, 25) == 0x0
771            && G_FLD (inst->v, 6, 1) == 0x4
772            && G_FLD (inst->v, 19, 15) == 0x3)
773     return 1;   /* br r3 */
774   else
775     return 0;
776 }
777
778 /* Implement the stack_frame_destroyed_p gdbarch method. */
779
780 static int
781 score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
782 {
783   CORE_ADDR pc = cur_pc;
784   inst_t *inst
785     = score3_adjust_pc_and_fetch_inst (&pc, NULL,
786                                        gdbarch_byte_order (gdbarch));
787
788   if (inst->len == 2
789       && (G_FLD (inst->v, 14, 10) == 0x10)
790       && (G_FLD (inst->v, 9, 5) == 0x0)
791       && (G_FLD (inst->v, 4, 0) == 0x2))
792     return 1;   /* mv! r0, r2 */
793   else if (inst->len == 4
794            && (G_FLD (inst->v, 29, 25) == 0x0)
795            && (G_FLD (inst->v, 24, 20) == 0x2)
796            && (G_FLD (inst->v, 19, 15) == 0x0)
797            && (G_FLD (inst->v, 14, 10) == 0xF)
798            && (G_FLD (inst->v, 9, 0) == 0x56))
799     return 1;   /* mv r0, r2 */
800   else if (inst->len == 2
801            && (G_FLD (inst->v, 14, 12) == 0x0)
802            && (G_FLD (inst->v, 11, 5) == 0x2))
803     return 1;   /* pop! */
804   else if (inst->len == 2
805            && (G_FLD (inst->v, 14, 12) == 0x0)
806            && (G_FLD (inst->v, 11, 7) == 0x0)
807            && (G_FLD (inst->v, 6, 5) == 0x2))
808     return 1;   /* rpop! */
809   else if (inst->len == 2
810            && (G_FLD (inst->v, 14, 12) == 0x0)
811            && (G_FLD (inst->v, 11, 5) == 0x4)
812            && (G_FLD (inst->v, 4, 0) == 0x3))
813     return 1;   /* br! r3 */
814   else if (inst->len == 4
815            && (G_FLD (inst->v, 29, 25) == 0x0)
816            && (G_FLD (inst->v, 24, 20) == 0x0)
817            && (G_FLD (inst->v, 19, 15) == 0x3)
818            && (G_FLD (inst->v, 14, 10) == 0xF)
819            && (G_FLD (inst->v, 9, 0) == 0x8))
820     return 1;   /* br r3 */
821   else
822     return 0;
823 }
824
825 static gdb_byte *
826 score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
827 {
828   int ret;
829   gdb_byte *memblock = NULL;
830
831   if (size == 0)
832     return NULL;
833
834   memblock = (gdb_byte *) xmalloc (size);
835   memset (memblock, 0, size);
836   ret = target_read_memory (addr & ~0x3, memblock, size);
837   if (ret)
838     {
839       error (_("Error: target_read_memory in file:%s, line:%d!"),
840              __FILE__, __LINE__);
841       return NULL;
842     }
843   return memblock;
844 }
845
846 static void
847 score7_free_memblock (gdb_byte *memblock)
848 {
849   xfree (memblock);
850 }
851
852 static void
853 score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
854                            CORE_ADDR cur_pc)
855 {
856   if (prev_pc == -1)
857     {
858       /* First time call this function, do nothing.  */
859     }
860   else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
861     {
862       /* First 16-bit instruction, then 32-bit instruction.  */
863       *memblock += SCORE_INSTLEN;
864     }
865   else if (cur_pc - prev_pc == 4)
866     {
867       /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
868       *memblock += SCORE_INSTLEN;
869     }
870 }
871
872 static void
873 score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
874                         struct frame_info *this_frame,
875                         struct score_frame_cache *this_cache)
876 {
877   struct gdbarch *gdbarch = get_frame_arch (this_frame);
878   CORE_ADDR sp;
879   CORE_ADDR fp;
880   CORE_ADDR cur_pc = startaddr;
881
882   int sp_offset = 0;
883   int ra_offset = 0;
884   int fp_offset = 0;
885   int ra_offset_p = 0;
886   int fp_offset_p = 0;
887   int inst_len = 0;
888
889   gdb_byte *memblock = NULL;
890   gdb_byte *memblock_ptr = NULL;
891   CORE_ADDR prev_pc = -1;
892
893   /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
894   memblock_ptr = memblock =
895     score7_malloc_and_get_memblock (startaddr, pc - startaddr);
896
897   sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
898   fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
899
900   for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
901     {
902       inst_t *inst = NULL;
903       if (memblock != NULL)
904         {
905           /* Reading memory block from target succefully and got all
906              the instructions(from STARTADDR to PC) needed.  */
907           score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
908           inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
909         }
910       else
911         {
912           /* Otherwise, we fetch 4 bytes from target, and GDB also
913              work correctly.  */
914           inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
915         }
916
917       /* FIXME: make a full-power prologue analyzer.  */
918       if (inst->len == 2)
919         {
920           inst_len = SCORE16_INSTLEN;
921
922           if (G_FLD (inst->v, 14, 12) == 0x2
923               && G_FLD (inst->v, 3, 0) == 0xe)
924             {
925               /* push! */
926               sp_offset += 4;
927
928               if (G_FLD (inst->v, 11, 7) == 0x6
929                   && ra_offset_p == 0)
930                 {
931                   /* push! r3, [r0] */
932                   ra_offset = sp_offset;
933                   ra_offset_p = 1;
934                 }
935               else if (G_FLD (inst->v, 11, 7) == 0x4
936                        && fp_offset_p == 0)
937                 {
938                   /* push! r2, [r0] */
939                   fp_offset = sp_offset;
940                   fp_offset_p = 1;
941                 }
942             }
943           else if (G_FLD (inst->v, 14, 12) == 0x2
944                    && G_FLD (inst->v, 3, 0) == 0xa)
945             {
946               /* pop! */
947               sp_offset -= 4;
948             }
949           else if (G_FLD (inst->v, 14, 7) == 0xc1
950                    && G_FLD (inst->v, 2, 0) == 0x0)
951             {
952               /* subei! r0, n */
953               sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
954             }
955           else if (G_FLD (inst->v, 14, 7) == 0xc0
956                    && G_FLD (inst->v, 2, 0) == 0x0)
957             {
958               /* addei! r0, n */
959               sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
960             }
961         }
962       else
963         {
964           inst_len = SCORE_INSTLEN;
965
966           if (G_FLD(inst->v, 29, 25) == 0x3
967               && G_FLD(inst->v, 2, 0) == 0x4
968               && G_FLD(inst->v, 19, 15) == 0)
969             {
970                 /* sw rD, [r0, offset]+ */
971                 sp_offset += SCORE_INSTLEN;
972
973                 if (G_FLD(inst->v, 24, 20) == 0x3)
974                   {
975                       /* rD = r3 */
976                       if (ra_offset_p == 0)
977                         {
978                             ra_offset = sp_offset;
979                             ra_offset_p = 1;
980                         }
981                   }
982                 else if (G_FLD(inst->v, 24, 20) == 0x2)
983                   {
984                       /* rD = r2 */
985                       if (fp_offset_p == 0)
986                         {
987                             fp_offset = sp_offset;
988                             fp_offset_p = 1;
989                         }
990                   }
991             }
992           else if (G_FLD(inst->v, 29, 25) == 0x14
993                    && G_FLD(inst->v, 19,15) == 0)
994             {
995                 /* sw rD, [r0, offset] */
996                 if (G_FLD(inst->v, 24, 20) == 0x3)
997                   {
998                       /* rD = r3 */
999                       ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
1000                       ra_offset_p = 1;
1001                   }
1002                 else if (G_FLD(inst->v, 24, 20) == 0x2)
1003                   {
1004                       /* rD = r2 */
1005                       fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
1006                       fp_offset_p = 1;
1007                   }
1008             }
1009           else if (G_FLD (inst->v, 29, 15) == 0x1c60
1010                    && G_FLD (inst->v, 2, 0) == 0x0)
1011             {
1012               /* lw r3, [r0]+, 4 */
1013               sp_offset -= SCORE_INSTLEN;
1014               ra_offset_p = 1;
1015             }
1016           else if (G_FLD (inst->v, 29, 15) == 0x1c40
1017                    && G_FLD (inst->v, 2, 0) == 0x0)
1018             {
1019               /* lw r2, [r0]+, 4 */
1020               sp_offset -= SCORE_INSTLEN;
1021               fp_offset_p = 1;
1022             }
1023
1024           else if (G_FLD (inst->v, 29, 17) == 0x100
1025                    && G_FLD (inst->v, 0, 0) == 0x0)
1026             {
1027               /* addi r0, -offset */
1028               sp_offset += 65536 - G_FLD (inst->v, 16, 1);
1029             }
1030           else if (G_FLD (inst->v, 29, 17) == 0x110
1031                    && G_FLD (inst->v, 0, 0) == 0x0)
1032             {
1033               /* addi r2, offset */
1034               if (pc - cur_pc > 4)
1035                 {
1036                   unsigned int save_v = inst->v;
1037                   inst_t *inst2 =
1038                     score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
1039                   if (inst2->v == 0x23)
1040                     {
1041                       /* mv! r0, r2 */
1042                       sp_offset -= G_FLD (save_v, 16, 1);
1043                     }
1044                 }
1045             }
1046         }
1047     }
1048
1049   /* Save RA.  */
1050   if (ra_offset_p == 1)
1051     {
1052       if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1053         this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1054           sp + sp_offset - ra_offset;
1055     }
1056   else
1057     {
1058       this_cache->saved_regs[SCORE_PC_REGNUM] =
1059         this_cache->saved_regs[SCORE_RA_REGNUM];
1060     }
1061
1062   /* Save FP.  */
1063   if (fp_offset_p == 1)
1064     {
1065       if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1066         this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1067           sp + sp_offset - fp_offset;
1068     }
1069
1070   /* Save SP and FP.  */
1071   this_cache->base = sp + sp_offset;
1072   this_cache->fp = fp;
1073
1074   /* Don't forget to free MEMBLOCK if we allocated it.  */
1075   if (memblock_ptr != NULL)
1076     score7_free_memblock (memblock_ptr);
1077 }
1078
1079 static void
1080 score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
1081                         struct frame_info *this_frame,
1082                         struct score_frame_cache *this_cache)
1083 {
1084   CORE_ADDR sp;
1085   CORE_ADDR fp;
1086   CORE_ADDR cur_pc = startaddr;
1087   enum bfd_endian byte_order
1088     = gdbarch_byte_order (get_frame_arch (this_frame));
1089
1090   int sp_offset = 0;
1091   int ra_offset = 0;
1092   int fp_offset = 0;
1093   int ra_offset_p = 0;
1094   int fp_offset_p = 0;
1095   int inst_len = 0;
1096
1097   sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
1098   fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
1099
1100   for (; cur_pc < pc; cur_pc += inst_len)
1101     {
1102       inst_t *inst = NULL;
1103
1104       inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);
1105
1106       /* FIXME: make a full-power prologue analyzer.  */
1107       if (inst->len == 2)
1108         {
1109           if (G_FLD (inst->v, 14, 12) == 0x0
1110               && G_FLD (inst->v, 11, 7) == 0x0
1111               && G_FLD (inst->v, 6, 5) == 0x3)
1112             {
1113               /* push! */
1114               sp_offset += 4;
1115
1116               if (G_FLD (inst->v, 4, 0) == 0x3
1117                   && ra_offset_p == 0)
1118                 {
1119                   /* push! r3, [r0] */
1120                   ra_offset = sp_offset;
1121                   ra_offset_p = 1;
1122                 }
1123               else if (G_FLD (inst->v, 4, 0) == 0x2
1124                        && fp_offset_p == 0)
1125                 {
1126                   /* push! r2, [r0] */
1127                   fp_offset = sp_offset;
1128                   fp_offset_p = 1;
1129                 }
1130             }
1131           else if (G_FLD (inst->v, 14, 12) == 0x6
1132                    && G_FLD (inst->v, 11, 10) == 0x3)
1133             {
1134               /* rpush! */
1135               int start_r = G_FLD (inst->v, 9, 5);
1136               int cnt = G_FLD (inst->v, 4, 0);
1137      
1138               if ((ra_offset_p == 0)
1139                   && (start_r <= SCORE_RA_REGNUM)
1140                   && (SCORE_RA_REGNUM < start_r + cnt))
1141                 {
1142                   /* rpush! contains r3 */
1143                   ra_offset_p = 1;
1144                   ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
1145                 }
1146
1147               if ((fp_offset_p == 0)
1148                   && (start_r <= SCORE_FP_REGNUM)
1149                   && (SCORE_FP_REGNUM < start_r + cnt))
1150                 {
1151                   /* rpush! contains r2 */
1152                   fp_offset_p = 1;
1153                   fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
1154                 }
1155
1156               sp_offset += 4 * cnt;
1157             }
1158           else if (G_FLD (inst->v, 14, 12) == 0x0
1159                    && G_FLD (inst->v, 11, 7) == 0x0
1160                    && G_FLD (inst->v, 6, 5) == 0x2)
1161             {
1162               /* pop! */
1163               sp_offset -= 4;
1164             }
1165           else if (G_FLD (inst->v, 14, 12) == 0x6
1166                    && G_FLD (inst->v, 11, 10) == 0x2)
1167             {
1168               /* rpop! */
1169               sp_offset -= 4 * G_FLD (inst->v, 4, 0);
1170             }
1171           else if (G_FLD (inst->v, 14, 12) == 0x5
1172                    && G_FLD (inst->v, 11, 10) == 0x3
1173                    && G_FLD (inst->v, 9, 6) == 0x0)
1174             {
1175               /* addi! r0, -offset */
1176               int imm = G_FLD (inst->v, 5, 0);
1177               if (imm >> 5)
1178                 imm = -(0x3F - imm + 1);
1179               sp_offset -= imm;
1180             }
1181           else if (G_FLD (inst->v, 14, 12) == 0x5
1182                    && G_FLD (inst->v, 11, 10) == 0x3
1183                    && G_FLD (inst->v, 9, 6) == 0x2)
1184             {
1185               /* addi! r2, offset */
1186               if (pc - cur_pc >= 2)
1187                 {
1188                   inst_t *inst2;
1189                   
1190                   cur_pc += inst->len;
1191                   inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1192                                                            byte_order);
1193
1194                   if (inst2->len == 2
1195                       && G_FLD (inst2->v, 14, 10) == 0x10
1196                       && G_FLD (inst2->v, 9, 5) == 0x0
1197                       && G_FLD (inst2->v, 4, 0) == 0x2)
1198                     {
1199                       /* mv! r0, r2 */
1200                       int imm = G_FLD (inst->v, 5, 0);
1201                       if (imm >> 5)
1202                         imm = -(0x3F - imm + 1);
1203                       sp_offset -= imm;
1204                     }
1205                 }
1206             }
1207         }
1208       else if (inst->len == 4)
1209         {
1210           if (G_FLD (inst->v, 29, 25) == 0x3
1211               && G_FLD (inst->v, 2, 0) == 0x4
1212               && G_FLD (inst->v, 24, 20) == 0x3
1213               && G_FLD (inst->v, 19, 15) == 0x0)
1214             {
1215               /* sw r3, [r0, offset]+ */
1216               sp_offset += inst->len;
1217               if (ra_offset_p == 0)
1218                 {
1219                   ra_offset = sp_offset;
1220                   ra_offset_p = 1;
1221                 }
1222             }
1223           else if (G_FLD (inst->v, 29, 25) == 0x3
1224                    && G_FLD (inst->v, 2, 0) == 0x4
1225                    && G_FLD (inst->v, 24, 20) == 0x2
1226                    && G_FLD (inst->v, 19, 15) == 0x0)
1227             {
1228               /* sw r2, [r0, offset]+ */
1229               sp_offset += inst->len;
1230               if (fp_offset_p == 0)
1231                 {
1232                   fp_offset = sp_offset;
1233                   fp_offset_p = 1;
1234                 }
1235             }
1236           else if (G_FLD (inst->v, 29, 25) == 0x7
1237                    && G_FLD (inst->v, 2, 0) == 0x0
1238                    && G_FLD (inst->v, 24, 20) == 0x3
1239                    && G_FLD (inst->v, 19, 15) == 0x0)
1240             {
1241               /* lw r3, [r0]+, 4 */
1242               sp_offset -= inst->len;
1243               ra_offset_p = 1;
1244             }
1245           else if (G_FLD (inst->v, 29, 25) == 0x7
1246                    && G_FLD (inst->v, 2, 0) == 0x0
1247                    && G_FLD (inst->v, 24, 20) == 0x2
1248                    && G_FLD (inst->v, 19, 15) == 0x0)
1249             {
1250               /* lw r2, [r0]+, 4 */
1251               sp_offset -= inst->len;
1252               fp_offset_p = 1;
1253             }
1254           else if (G_FLD (inst->v, 29, 25) == 0x1
1255                    && G_FLD (inst->v, 19, 17) == 0x0
1256                    && G_FLD (inst->v, 24, 20) == 0x0
1257                    && G_FLD (inst->v, 0, 0) == 0x0)
1258             {
1259               /* addi r0, -offset */
1260               int imm = G_FLD (inst->v, 16, 1);
1261               if (imm >> 15)
1262                 imm = -(0xFFFF - imm + 1);
1263               sp_offset -= imm;
1264             }
1265           else if (G_FLD (inst->v, 29, 25) == 0x1
1266                    && G_FLD (inst->v, 19, 17) == 0x0
1267                    && G_FLD (inst->v, 24, 20) == 0x2
1268                    && G_FLD (inst->v, 0, 0) == 0x0)
1269             {
1270               /* addi r2, offset */
1271               if (pc - cur_pc >= 2)
1272                 {
1273                   inst_t *inst2;
1274                   
1275                   cur_pc += inst->len;
1276                   inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
1277                                                            byte_order);
1278
1279                   if (inst2->len == 2
1280                       && G_FLD (inst2->v, 14, 10) == 0x10
1281                       && G_FLD (inst2->v, 9, 5) == 0x0
1282                       && G_FLD (inst2->v, 4, 0) == 0x2)
1283                     {
1284                       /* mv! r0, r2 */
1285                       int imm = G_FLD (inst->v, 16, 1);
1286                       if (imm >> 15)
1287                         imm = -(0xFFFF - imm + 1);
1288                       sp_offset -= imm;
1289                     }
1290                 }
1291             }
1292         }
1293     }
1294
1295   /* Save RA.  */
1296   if (ra_offset_p == 1)
1297     {
1298       if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
1299         this_cache->saved_regs[SCORE_PC_REGNUM].addr =
1300           sp + sp_offset - ra_offset;
1301     }
1302   else
1303     {
1304       this_cache->saved_regs[SCORE_PC_REGNUM] =
1305         this_cache->saved_regs[SCORE_RA_REGNUM];
1306     }
1307
1308   /* Save FP.  */
1309   if (fp_offset_p == 1)
1310     {
1311       if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
1312         this_cache->saved_regs[SCORE_FP_REGNUM].addr =
1313           sp + sp_offset - fp_offset;
1314     }
1315
1316   /* Save SP and FP.  */
1317   this_cache->base = sp + sp_offset;
1318   this_cache->fp = fp;
1319 }
1320
1321 static struct score_frame_cache *
1322 score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
1323 {
1324   struct score_frame_cache *cache;
1325
1326   if ((*this_cache) != NULL)
1327     return (struct score_frame_cache *) (*this_cache);
1328
1329   cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
1330   (*this_cache) = cache;
1331   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
1332
1333   /* Analyze the prologue.  */
1334   {
1335     const CORE_ADDR pc = get_frame_pc (this_frame);
1336     CORE_ADDR start_addr;
1337
1338     find_pc_partial_function (pc, NULL, &start_addr, NULL);
1339     if (start_addr == 0)
1340       return cache;
1341
1342     if (target_mach == bfd_mach_score3)
1343       score3_analyze_prologue (start_addr, pc, this_frame,
1344                                (struct score_frame_cache *) *this_cache);
1345     else
1346       score7_analyze_prologue (start_addr, pc, this_frame,
1347                                (struct score_frame_cache *) *this_cache);
1348   }
1349
1350   /* Save SP.  */
1351   trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
1352
1353   return (struct score_frame_cache *) (*this_cache);
1354 }
1355
1356 static void
1357 score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
1358                         struct frame_id *this_id)
1359 {
1360   struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1361                                                               this_cache);
1362   (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
1363 }
1364
1365 static struct value *
1366 score_prologue_prev_register (struct frame_info *this_frame,
1367                               void **this_cache, int regnum)
1368 {
1369   struct score_frame_cache *info = score_make_prologue_cache (this_frame,
1370                                                               this_cache);
1371   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
1372 }
1373
1374 static const struct frame_unwind score_prologue_unwind =
1375 {
1376   NORMAL_FRAME,
1377   default_frame_unwind_stop_reason,
1378   score_prologue_this_id,
1379   score_prologue_prev_register,
1380   NULL,
1381   default_frame_sniffer,
1382   NULL
1383 };
1384
1385 static CORE_ADDR
1386 score_prologue_frame_base_address (struct frame_info *this_frame,
1387                                    void **this_cache)
1388 {
1389   struct score_frame_cache *info =
1390     score_make_prologue_cache (this_frame, this_cache);
1391   return info->fp;
1392 }
1393
1394 static const struct frame_base score_prologue_frame_base =
1395 {
1396   &score_prologue_unwind,
1397   score_prologue_frame_base_address,
1398   score_prologue_frame_base_address,
1399   score_prologue_frame_base_address,
1400 };
1401
1402 static const struct frame_base *
1403 score_prologue_frame_base_sniffer (struct frame_info *this_frame)
1404 {
1405   return &score_prologue_frame_base;
1406 }
1407
1408 /* Core file support.  */
1409
1410 static const struct regcache_map_entry score7_linux_gregmap[] =
1411   {
1412     /* FIXME: According to the current Linux kernel, r0 is preceded by
1413        9 rather than 7 words.  */
1414     { 7, REGCACHE_MAP_SKIP, 4 },
1415     { 32, 0, 4 },               /* r0 ... r31 */
1416     { 1, 55, 4 },               /* CEL */
1417     { 1, 54, 4 },               /* CEH */
1418     { 1, 53, 4 },               /* sr0, i.e. cnt or COUNTER */
1419     { 1, 52, 4 },               /* sr1, i.e. lcr or LDCR */
1420     { 1, 51, 4 },               /* sr2, i.e. scr or STCR */
1421     { 1, 49, 4 },               /* PC (same slot as EPC) */
1422     { 1, 38, 4 },               /* EMA */
1423     { 1, 32, 4 },               /* PSR */
1424     { 1, 34, 4 },               /* ECR */
1425     { 1, 33, 4 },               /* COND */
1426     { 0 }
1427   };
1428
1429 #define SCORE7_LINUX_EPC_OFFSET (44 * 4)
1430 #define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)
1431
1432 static void
1433 score7_linux_supply_gregset(const struct regset *regset,
1434                             struct regcache *regcache,
1435                             int regnum, const void *buf,
1436                             size_t size)
1437 {
1438   regcache_supply_regset (regset, regcache, regnum, buf, size);
1439
1440   /* Supply the EPC from the same slot as the PC.  Note that the
1441      collect function will store the PC in that slot.  */
1442   if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
1443       && size >= SCORE7_LINUX_EPC_OFFSET + 4)
1444     regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
1445                          (const gdb_byte *) buf
1446                          + SCORE7_LINUX_EPC_OFFSET);
1447 }
1448
1449 static const struct regset score7_linux_gregset =
1450   {
1451     score7_linux_gregmap,
1452     score7_linux_supply_gregset,
1453     regcache_collect_regset
1454   };
1455
1456 /* Iterate over core file register note sections.  */
1457
1458 static void
1459 score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
1460                                            iterate_over_regset_sections_cb *cb,
1461                                            void *cb_data,
1462                                            const struct regcache *regcache)
1463 {
1464   cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
1465       NULL, cb_data);
1466 }
1467
1468 static struct gdbarch *
1469 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1470 {
1471   struct gdbarch *gdbarch;
1472   target_mach = info.bfd_arch_info->mach;
1473
1474   arches = gdbarch_list_lookup_by_info (arches, &info);
1475   if (arches != NULL)
1476     {
1477       return (arches->gdbarch);
1478     }
1479   gdbarch = gdbarch_alloc (&info, NULL);
1480
1481   set_gdbarch_short_bit (gdbarch, 16);
1482   set_gdbarch_int_bit (gdbarch, 32);
1483   set_gdbarch_float_bit (gdbarch, 32);
1484   set_gdbarch_double_bit (gdbarch, 64);
1485   set_gdbarch_long_double_bit (gdbarch, 64);
1486 #if WITH_SIM
1487   set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1488 #endif
1489   set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1490   set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1491   set_gdbarch_adjust_breakpoint_address (gdbarch,
1492                                          score_adjust_breakpoint_address);
1493   set_gdbarch_register_type (gdbarch, score_register_type);
1494   set_gdbarch_frame_align (gdbarch, score_frame_align);
1495   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1496   set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1497   set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1498   set_gdbarch_print_insn (gdbarch, score_print_insn);
1499
1500   switch (target_mach)
1501     {
1502     case bfd_mach_score7:
1503       SET_GDBARCH_BREAKPOINT_MANIPULATION (score7);
1504       set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
1505       set_gdbarch_stack_frame_destroyed_p (gdbarch,
1506                                            score7_stack_frame_destroyed_p);
1507       set_gdbarch_register_name (gdbarch, score7_register_name);
1508       set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
1509       /* Core file support.  */
1510       set_gdbarch_iterate_over_regset_sections
1511         (gdbarch, score7_linux_iterate_over_regset_sections);
1512       break;
1513
1514     case bfd_mach_score3:
1515       SET_GDBARCH_BREAKPOINT_MANIPULATION (score3);
1516       set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
1517       set_gdbarch_stack_frame_destroyed_p (gdbarch,
1518                                            score3_stack_frame_destroyed_p);
1519       set_gdbarch_register_name (gdbarch, score3_register_name);
1520       set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
1521       break;
1522     }
1523
1524   /* Watchpoint hooks.  */
1525   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1526
1527   /* Dummy frame hooks.  */
1528   set_gdbarch_return_value (gdbarch, score_return_value);
1529   set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1530   set_gdbarch_dummy_id (gdbarch, score_dummy_id);
1531   set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1532
1533   /* Normal frame hooks.  */
1534   dwarf2_append_unwinders (gdbarch);
1535   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1536   frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
1537   frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1538
1539   return gdbarch;
1540 }
1541
1542 extern initialize_file_ftype _initialize_score_tdep;
1543
1544 void
1545 _initialize_score_tdep (void)
1546 {
1547   gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1548 }