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