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