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