OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [score-tdep.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* 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
 
192
                    table 2 (column 1, 2, 3)
193
    *  0  0  *  *   # 0, 4
194
 
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.