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

Subversion Repositories openrisc_me

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Target-dependent code for the S+core architecture, for GDB,
2
   the GNU Debugger.
3
 
4
   Copyright (C) 2006, 2007, 2008 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 "dis-asm.h"
34
#include "frame-unwind.h"
35
#include "frame-base.h"
36
#include "trad-frame.h"
37
#include "dwarf2-frame.h"
38
#include "score-tdep.h"
39
 
40
#define G_FLD(_i,_ms,_ls)   (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
41
#define RM_PBITS(_raw)      ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0))
42
 
43
typedef struct{
44
    unsigned int v;
45
    unsigned int raw;
46
    char         is15;
47
}inst_t;
48
 
49
struct score_frame_cache
50
{
51
  CORE_ADDR base;
52
  CORE_ADDR fp;
53
  struct trad_frame_saved_reg *saved_regs;
54
};
55
 
56
#if 0
57
/* If S+core GCC will generate these instructions in the prologue:
58
 
59
   lw   rx, imm1
60
   addi rx, -imm2
61
   mv!  r2, rx
62
 
63
   then .pdr section is used.  */
64
 
65
#define P_SIZE          8
66
#define PI_SYM          0
67
#define PI_R_MSK        1
68
#define PI_R_OFF        2
69
#define PI_R_LEF        4
70
#define PI_F_OFF        5
71
#define PI_F_REG        6
72
#define PI_RAREG        7
73
 
74
typedef struct frame_extra_info
75
{
76
  CORE_ADDR p_frame;
77
  unsigned int pdr[P_SIZE];
78
} extra_info_t;
79
 
80
struct obj_priv
81
{
82
  bfd_size_type size;
83
  char *contents;
84
};
85
 
86
static bfd *the_bfd;
87
 
88
static int
89
score_compare_pdr_entries (const void *a, const void *b)
90
{
91
  CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a);
92
  CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b);
93
  if (lhs < rhs)
94
    return -1;
95
  else if (lhs == rhs)
96
    return 0;
97
  else
98
    return 1;
99
}
100
 
101
static void
102
score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc,
103
                           struct frame_info *next_frame,
104
                           struct score_frame_cache *this_cache)
105
{
106
  struct symbol *sym;
107
  struct obj_section *sec;
108
  extra_info_t *fci_ext;
109
  CORE_ADDR leaf_ra_stack_addr = -1;
110
 
111
  gdb_assert (startaddr <= pc);
112
  gdb_assert (this_cache != NULL);
113
 
114
  fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
115
  if ((sec = find_pc_section (pc)) == NULL)
116
    {
117
      error ("Error: Can't find section in file:%s, line:%d!",
118
             __FILE__, __LINE__);
119
      return;
120
    }
121
 
122
  /* Anylyze .pdr section and get coresponding fields.  */
123
  {
124
    static struct obj_priv *priv = NULL;
125
 
126
    if (priv == NULL)
127
      {
128
        asection *bfdsec;
129
        priv = obstack_alloc (&sec->objfile->objfile_obstack,
130
                              sizeof (struct obj_priv));
131
        if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr")))
132
          {
133
            priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
134
            priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
135
                                            priv->size);
136
            bfd_get_section_contents (sec->objfile->obfd, bfdsec,
137
                                      priv->contents, 0, priv->size);
138
            the_bfd = sec->objfile->obfd;
139
            qsort (priv->contents, priv->size / 32, 32,
140
                   score_compare_pdr_entries);
141
            the_bfd = NULL;
142
          }
143
        else
144
          priv->size = 0;
145
      }
146
    if (priv->size != 0)
147
      {
148
        int low = 0, mid, high = priv->size / 32;
149
        char *ptr;
150
        do
151
          {
152
            CORE_ADDR pdr_pc;
153
            mid = (low + high) / 2;
154
            ptr = priv->contents + mid * 32;
155
            pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
156
            pdr_pc += ANOFFSET (sec->objfile->section_offsets,
157
                                SECT_OFF_TEXT (sec->objfile));
158
            if (pdr_pc == startaddr)
159
              break;
160
            if (pdr_pc > startaddr)
161
              high = mid;
162
            else
163
              low = mid + 1;
164
          }
165
        while (low != high);
166
 
167
        if (low != high)
168
          {
169
            gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr);
170
#define EXT_PDR(_pi)    bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2))
171
            fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM);
172
            fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK);
173
            fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF);
174
            fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF);
175
            fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF);
176
            fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG);
177
            fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG);
178
#undef EXT_PDR
179
          }
180
      }
181
  }
182
}
183
#endif
184
 
185
#if 0
186
/* Open these functions if build with simulator.  */
187
 
188
int
189
score_target_can_use_watch (int type, int cnt, int othertype)
190
{
191
  if (strcmp (current_target.to_shortname, "sim") == 0)
192
    {
193
      return soc_gh_can_use_watch (type, cnt);
194
    }
195
  else
196
    {
197
      return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype);
198
    }
199
}
200
 
201
int
202
score_stopped_by_watch (void)
203
{
204
  if (strcmp (current_target.to_shortname, "sim") == 0)
205
    {
206
      return soc_gh_stopped_by_watch ();
207
    }
208
  else
209
    {
210
      return (*current_target.to_stopped_by_watchpoint) ();
211
    }
212
}
213
 
214
int
215
score_target_insert_watchpoint (CORE_ADDR addr, int len, int type)
216
{
217
  if (strcmp (current_target.to_shortname, "sim") == 0)
218
    {
219
      return soc_gh_add_watch (addr, len, type);
220
    }
221
  else
222
    {
223
      return (*current_target.to_insert_watchpoint) (addr, len, type);
224
    }
225
}
226
 
227
int
228
score_target_remove_watchpoint (CORE_ADDR addr, int len, int type)
229
{
230
  if (strcmp (current_target.to_shortname, "sim") == 0)
231
    {
232
      return soc_gh_del_watch (addr, len, type);
233
    }
234
  else
235
    {
236
      return (*current_target.to_remove_watchpoint) (addr, len, type);
237
    }
238
}
239
 
240
int
241
score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt)
242
{
243
  if (strcmp (current_target.to_shortname, "sim") == 0)
244
    {
245
      return soc_gh_add_hardbp (bp_tgt->placed_address);
246
    }
247
  else
248
    {
249
      return (*current_target.to_insert_hw_breakpoint) (bp_tgt);
250
    }
251
}
252
 
253
int
254
score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt)
255
{
256
  if (strcmp (current_target.to_shortname, "sim") == 0)
257
    {
258
      return soc_gh_del_hardbp (bp_tgt->placed_address);
259
    }
260
  else
261
    {
262
      return (*current_target.to_remove_hw_breakpoint) (bp_tgt);
263
    }
264
}
265
#endif
266
 
267
static struct type *
268
score_register_type (struct gdbarch *gdbarch, int regnum)
269
{
270
  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
271
  return builtin_type_uint32;
272
}
273
 
274
static CORE_ADDR
275
score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
276
{
277
  return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
278
}
279
 
280
static CORE_ADDR
281
score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
282
{
283
  return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
284
}
285
 
286
static const char *
287
score_register_name (struct gdbarch *gdbarch, int regnum)
288
{
289
  const char *score_register_names[] = {
290
    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
291
    "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
292
    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
293
    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
294
 
295
    "PSR",   "COND",   "ECR",    "EXCPVEC",
296
    "CCR",   "EPC",    "EMA",    "TLBLOCK",
297
    "TLBPT", "PEADDR", "TLBRPT", "PEVN",
298
    "PECTX", "LIMPFN", "LDMPFN", "PREV",
299
    "DREG",  "PC",     "DSAVE",  "COUNTER",
300
    "LDCR",  "STCR",   "CEH",    "CEL",
301
  };
302
 
303
  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
304
  return score_register_names[regnum];
305
}
306
 
307
static int
308
score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
309
{
310
  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
311
  return regnum;
312
}
313
 
314
static int
315
score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
316
{
317
  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
318
    return print_insn_big_score (memaddr, info);
319
  else
320
    return print_insn_little_score (memaddr, info);
321
}
322
 
323
static const gdb_byte *
324
score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
325
                          int *lenptr)
326
{
327
  gdb_byte buf[SCORE_INSTLEN] = { 0 };
328
  int ret;
329
  unsigned int raw;
330
 
331
  if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
332
    {
333
      error ("Error: target_read_memory in file:%s, line:%d!",
334
             __FILE__, __LINE__);
335
    }
336
  raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
337
 
338
  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
339
    {
340
      if (!(raw & 0x80008000))
341
        {
342
          /* 16bits instruction.  */
343
          static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
344
          *pcptr &= ~0x1;
345
          *lenptr = sizeof (big_breakpoint16);
346
          return big_breakpoint16;
347
        }
348
      else
349
        {
350
          /* 32bits instruction.  */
351
          static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
352
          *pcptr &= ~0x3;
353
          *lenptr = sizeof (big_breakpoint32);
354
          return big_breakpoint32;
355
        }
356
    }
357
  else
358
    {
359
      if (!(raw & 0x80008000))
360
        {
361
          /* 16bits instruction.  */
362
          static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
363
          *pcptr &= ~0x1;
364
          *lenptr = sizeof (little_breakpoint16);
365
          return little_breakpoint16;
366
        }
367
      else
368
        {
369
          /* 32bits instruction.  */
370
          static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
371
          *pcptr &= ~0x3;
372
          *lenptr = sizeof (little_breakpoint32);
373
          return little_breakpoint32;
374
        }
375
    }
376
}
377
 
378
static CORE_ADDR
379
score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
380
{
381
  return align_down (addr, 16);
382
}
383
 
384
static void
385
score_xfer_register (struct regcache *regcache, int regnum, int length,
386
                     enum bfd_endian endian, gdb_byte *readbuf,
387
                     const gdb_byte *writebuf, int buf_offset)
388
{
389
  int reg_offset = 0;
390
  gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
391
 
392
  switch (endian)
393
    {
394
    case BFD_ENDIAN_BIG:
395
      reg_offset = SCORE_REGSIZE - length;
396
      break;
397
    case BFD_ENDIAN_LITTLE:
398
      reg_offset = 0;
399
      break;
400
    case BFD_ENDIAN_UNKNOWN:
401
      reg_offset = 0;
402
      break;
403
    default:
404
      error ("Error: score_xfer_register in file:%s, line:%d!",
405
             __FILE__, __LINE__);
406
    }
407
 
408
  if (readbuf != NULL)
409
    regcache_cooked_read_part (regcache, regnum, reg_offset, length,
410
                               readbuf + buf_offset);
411
  if (writebuf != NULL)
412
    regcache_cooked_write_part (regcache, regnum, reg_offset, length,
413
                                writebuf + buf_offset);
414
}
415
 
416
static enum return_value_convention
417
score_return_value (struct gdbarch *gdbarch, struct type *type,
418
                    struct regcache *regcache,
419
                    gdb_byte * readbuf, const gdb_byte * writebuf)
420
{
421
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
422
      || TYPE_CODE (type) == TYPE_CODE_UNION
423
      || TYPE_CODE (type) == TYPE_CODE_ARRAY)
424
    return RETURN_VALUE_STRUCT_CONVENTION;
425
  else
426
    {
427
      int offset;
428
      int regnum;
429
      for (offset = 0, regnum = SCORE_A0_REGNUM;
430
           offset < TYPE_LENGTH (type);
431
           offset += SCORE_REGSIZE, regnum++)
432
        {
433
          int xfer = SCORE_REGSIZE;
434
          if (offset + xfer > TYPE_LENGTH (type))
435
            xfer = TYPE_LENGTH (type) - offset;
436
          score_xfer_register (regcache, regnum, xfer,
437
                               gdbarch_byte_order (gdbarch),
438
                               readbuf, writebuf, offset);
439
        }
440
      return RETURN_VALUE_REGISTER_CONVENTION;
441
    }
442
}
443
 
444
static struct frame_id
445
score_unwind_dummy_id (struct gdbarch *gdbarch,
446
                       struct frame_info *next_frame)
447
{
448
  return frame_id_build (
449
           frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM),
450
           frame_pc_unwind (next_frame));
451
}
452
 
453
static int
454
score_type_needs_double_align (struct type *type)
455
{
456
  enum type_code typecode = TYPE_CODE (type);
457
 
458
  if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
459
      || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
460
    return 1;
461
  else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
462
    {
463
      int i, n;
464
 
465
      n = TYPE_NFIELDS (type);
466
      for (i = 0; i < n; i++)
467
        if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
468
          return 1;
469
      return 0;
470
    }
471
  return 0;
472
}
473
 
474
static CORE_ADDR
475
score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
476
                       struct regcache *regcache, CORE_ADDR bp_addr,
477
                       int nargs, struct value **args, CORE_ADDR sp,
478
                       int struct_return, CORE_ADDR struct_addr)
479
{
480
  int argnum;
481
  int argreg;
482
  int arglen = 0;
483
  CORE_ADDR stack_offset = 0;
484
  CORE_ADDR addr = 0;
485
 
486
  /* Step 1, Save RA.  */
487
  regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);
488
 
489
  /* Step 2, Make space on the stack for the args.  */
490
  struct_addr = align_down (struct_addr, 16);
491
  sp = align_down (sp, 16);
492
  for (argnum = 0; argnum < nargs; argnum++)
493
    arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
494
                        SCORE_REGSIZE);
495
  sp -= align_up (arglen, 16);
496
 
497
  argreg = SCORE_BEGIN_ARG_REGNUM;
498
 
499
  /* Step 3, Check if struct return then save the struct address to
500
     r4 and increase the stack_offset by 4.  */
501
  if (struct_return)
502
    {
503
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
504
      stack_offset += SCORE_REGSIZE;
505
    }
506
 
507
  /* Step 4, Load arguments:
508
     If arg length is too long (> 4 bytes), then split the arg and
509
     save every parts.  */
510
  for (argnum = 0; argnum < nargs; argnum++)
511
    {
512
      struct value *arg = args[argnum];
513
      struct type *arg_type = check_typedef (value_type (arg));
514
      enum type_code typecode = TYPE_CODE (arg_type);
515
      const gdb_byte *val = value_contents (arg);
516
      int downward_offset = 0;
517
      int odd_sized_struct_p;
518
      int arg_last_part_p = 0;
519
 
520
      arglen = TYPE_LENGTH (arg_type);
521
      odd_sized_struct_p = (arglen > SCORE_REGSIZE
522
                            && arglen % SCORE_REGSIZE != 0);
523
 
524
      /* If a arg should be aligned to 8 bytes (long long or double),
525
         the value should be put to even register numbers.  */
526
      if (score_type_needs_double_align (arg_type))
527
        {
528
          if (argreg & 1)
529
            argreg++;
530
        }
531
 
532
      /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
533
         the default "downward"/"upward" method:
534
 
535
         Example:
536
 
537
         struct struc
538
         {
539
           char a; char b; char c;
540
         } s = {'a', 'b', 'c'};
541
 
542
         Big endian:    s = {X, 'a', 'b', 'c'}
543
         Little endian: s = {'a', 'b', 'c', X}
544
 
545
         Where X is a hole.  */
546
 
547
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
548
          && (typecode == TYPE_CODE_STRUCT
549
              || typecode == TYPE_CODE_UNION)
550
          && argreg > SCORE_LAST_ARG_REGNUM
551
          && arglen < SCORE_REGSIZE)
552
        downward_offset += (SCORE_REGSIZE - arglen);
553
 
554
      while (arglen > 0)
555
        {
556
          int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
557
          ULONGEST regval = extract_unsigned_integer (val, partial_len);
558
 
559
          /* The last part of a arg should shift left when
560
             gdbarch_byte_order is BFD_ENDIAN_BIG.  */
561
          if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
562
              && arg_last_part_p == 1
563
              && (typecode == TYPE_CODE_STRUCT
564
                  || typecode == TYPE_CODE_UNION))
565
            regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);
566
 
567
          /* Always increase the stack_offset and save args to stack.  */
568
          addr = sp + stack_offset + downward_offset;
569
          write_memory (addr, val, partial_len);
570
 
571
          if (argreg <= SCORE_LAST_ARG_REGNUM)
572
            {
573
              regcache_cooked_write_unsigned (regcache, argreg++, regval);
574
              if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
575
                arg_last_part_p = 1;
576
            }
577
 
578
          val += partial_len;
579
          arglen -= partial_len;
580
          stack_offset += align_up (partial_len, SCORE_REGSIZE);
581
        }
582
    }
583
 
584
  /* Step 5, Save SP.  */
585
  regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);
586
 
587
  return sp;
588
}
589
 
590
static char *
591
score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
592
{
593
  int ret;
594
  char *memblock = NULL;
595
 
596
  if (size < 0)
597
    {
598
      error ("Error: malloc size < 0 in file:%s, line:%d!",
599
             __FILE__, __LINE__);
600
      return NULL;
601
    }
602
  else if (size == 0)
603
    return NULL;
604
 
605
  memblock = (char *) xmalloc (size);
606
  memset (memblock, 0, size);
607
  ret = target_read_memory (addr & ~0x3, memblock, size);
608
  if (ret)
609
    {
610
      error ("Error: target_read_memory in file:%s, line:%d!",
611
             __FILE__, __LINE__);
612
      return NULL;
613
    }
614
  return memblock;
615
}
616
 
617
static void
618
score_free_memblock (char *memblock)
619
{
620
  xfree (memblock);
621
}
622
 
623
static void
624
score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
625
                           CORE_ADDR cur_pc)
626
{
627
  if (prev_pc == -1)
628
    {
629
      /* First time call this function, do nothing.  */
630
    }
631
  else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
632
    {
633
      /* First 16-bit instruction, then 32-bit instruction.  */
634
      *memblock += SCORE_INSTLEN;
635
    }
636
  else if (cur_pc - prev_pc == 4)
637
    {
638
      /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
639
      *memblock += SCORE_INSTLEN;
640
    }
641
}
642
 
643
static inst_t *
644
score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
645
{
646
  static inst_t inst = { 0, 0 };
647
  char buf[SCORE_INSTLEN] = { 0 };
648
  int big;
649
  int ret;
650
 
651
  if (target_has_execution && memblock != NULL)
652
    {
653
      /* Fetch instruction from local MEMBLOCK.  */
654
      memcpy (buf, memblock, SCORE_INSTLEN);
655
    }
656
  else
657
    {
658
      /* Fetch instruction from target.  */
659
      ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
660
      if (ret)
661
        {
662
          error ("Error: target_read_memory in file:%s, line:%d!",
663
                  __FILE__, __LINE__);
664
          return 0;
665
        }
666
    }
667
 
668
  inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
669
  inst.is15 = !(inst.raw & 0x80008000);
670
  inst.v = RM_PBITS (inst.raw);
671
  big = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG);
672
  if (inst.is15)
673
    {
674
      if (big ^ ((addr & 0x2) == 2))
675
        inst.v = G_FLD (inst.v, 29, 15);
676
      else
677
        inst.v = G_FLD (inst.v, 14, 0);
678
    }
679
  return &inst;
680
}
681
 
682
static CORE_ADDR
683
score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
684
{
685
  CORE_ADDR cpc = pc;
686
  int iscan = 32, stack_sub = 0;
687
  while (iscan-- > 0)
688
    {
689
      inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL);
690
      if (!inst)
691
        break;
692
      if (!inst->is15 && !stack_sub
693
          && (G_FLD (inst->v, 29, 25) == 0x1
694
              && G_FLD (inst->v, 24, 20) == 0x0))
695
        {
696
          /* addi r0, offset */
697
          pc = stack_sub = cpc + SCORE_INSTLEN;
698
        }
699
      else if (!inst->is15
700
               && inst->v == RM_PBITS (0x8040bc56))
701
        {
702
          /* mv r2, r0  */
703
          pc = cpc + SCORE_INSTLEN;
704
          break;
705
        }
706
      else if (inst->is15
707
               && inst->v == RM_PBITS (0x0203))
708
        {
709
          /* mv! r2, r0 */
710
          pc = cpc + SCORE16_INSTLEN;
711
          break;
712
        }
713
      else if (inst->is15
714
               && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
715
                   || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
716
                   || (G_FLD (inst->v, 14, 12) == 0x0
717
                       && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
718
        break;
719
      else if (!inst->is15
720
               && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
721
                   || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
722
                   || (G_FLD (inst->v, 29, 25) == 0x0
723
                       && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
724
        break;
725
 
726
      cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
727
    }
728
  return pc;
729
}
730
 
731
static int
732
score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
733
{
734
  inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL);
735
 
736
  if (inst->v == 0x23)
737
    return 1;   /* mv! r0, r2 */
738
  else if (G_FLD (inst->v, 14, 12) == 0x2
739
           && G_FLD (inst->v, 3, 0) == 0xa)
740
    return 1;   /* pop! */
741
  else if (G_FLD (inst->v, 14, 12) == 0x0
742
           && G_FLD (inst->v, 7, 0) == 0x34)
743
    return 1;   /* br! r3 */
744
  else if (G_FLD (inst->v, 29, 15) == 0x2
745
           && G_FLD (inst->v, 6, 1) == 0x2b)
746
    return 1;   /* mv r0, r2 */
747
  else if (G_FLD (inst->v, 29, 25) == 0x0
748
           && G_FLD (inst->v, 6, 1) == 0x4
749
           && G_FLD (inst->v, 19, 15) == 0x3)
750
    return 1;   /* br r3 */
751
  else
752
    return 0;
753
}
754
 
755
static void
756
score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
757
                        struct frame_info *next_frame,
758
                        struct score_frame_cache *this_cache)
759
{
760
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
761
  CORE_ADDR sp;
762
  CORE_ADDR fp;
763
  CORE_ADDR cur_pc = startaddr;
764
 
765
  int sp_offset = 0;
766
  int ra_offset = 0;
767
  int fp_offset = 0;
768
  int ra_offset_p = 0;
769
  int fp_offset_p = 0;
770
  int inst_len = 0;
771
 
772
  char *memblock = NULL;
773
  char *memblock_ptr = NULL;
774
  CORE_ADDR prev_pc = -1;
775
 
776
  /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
777
  memblock_ptr = memblock =
778
    score_malloc_and_get_memblock (startaddr, pc - startaddr);
779
 
780
  sp = frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
781
  fp = frame_unwind_register_unsigned (next_frame, SCORE_FP_REGNUM);
782
 
783
  for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
784
    {
785
      inst_t *inst = NULL;
786
      if (memblock != NULL)
787
        {
788
          /* Reading memory block from target succefully and got all
789
             the instructions(from STARTADDR to PC) needed.  */
790
          score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
791
          inst = score_fetch_inst (gdbarch, cur_pc, memblock);
792
        }
793
      else
794
        {
795
          /* Otherwise, we fetch 4 bytes from target, and GDB also
796
             work correctly.  */
797
          inst = score_fetch_inst (gdbarch, cur_pc, NULL);
798
        }
799
 
800
      if (inst->is15 == 1)
801
        {
802
          inst_len = SCORE16_INSTLEN;
803
 
804
          if (G_FLD (inst->v, 14, 12) == 0x2
805
              && G_FLD (inst->v, 3, 0) == 0xe)
806
            {
807
              /* push! */
808
              sp_offset += 4;
809
 
810
              if (G_FLD (inst->v, 11, 7) == 0x6
811
                  && ra_offset_p == 0)
812
                {
813
                  /* push! r3, [r0] */
814
                  ra_offset = sp_offset;
815
                  ra_offset_p = 1;
816
                }
817
              else if (G_FLD (inst->v, 11, 7) == 0x4
818
                       && fp_offset_p == 0)
819
                {
820
                  /* push! r2, [r0] */
821
                  fp_offset = sp_offset;
822
                  fp_offset_p = 1;
823
                }
824
            }
825
          else if (G_FLD (inst->v, 14, 12) == 0x2
826
                   && G_FLD (inst->v, 3, 0) == 0xa)
827
            {
828
              /* pop! */
829
              sp_offset -= 4;
830
            }
831
          else if (G_FLD (inst->v, 14, 7) == 0xc1
832
                   && G_FLD (inst->v, 2, 0) == 0x0)
833
            {
834
              /* subei! r0, n */
835
              sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
836
            }
837
          else if (G_FLD (inst->v, 14, 7) == 0xc0
838
                   && G_FLD (inst->v, 2, 0) == 0x0)
839
            {
840
              /* addei! r0, n */
841
              sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
842
            }
843
        }
844
      else
845
        {
846
          inst_len = SCORE_INSTLEN;
847
 
848
          if (G_FLD (inst->v, 29, 15) == 0xc60
849
              && G_FLD (inst->v, 2, 0) == 0x4)
850
            {
851
              /* sw r3, [r0, offset]+ */
852
              sp_offset += SCORE_INSTLEN;
853
              if (ra_offset_p == 0)
854
                {
855
                  ra_offset = sp_offset;
856
                  ra_offset_p = 1;
857
                }
858
            }
859
          if (G_FLD (inst->v, 29, 15) == 0xc40
860
              && G_FLD (inst->v, 2, 0) == 0x4)
861
            {
862
              /* sw r2, [r0, offset]+ */
863
              sp_offset += SCORE_INSTLEN;
864
              if (fp_offset_p == 0)
865
                {
866
                  fp_offset = sp_offset;
867
                  fp_offset_p = 1;
868
                }
869
            }
870
          else if (G_FLD (inst->v, 29, 15) == 0x1c60
871
                   && G_FLD (inst->v, 2, 0) == 0x0)
872
            {
873
              /* lw r3, [r0]+, 4 */
874
              sp_offset -= SCORE_INSTLEN;
875
              ra_offset_p = 1;
876
            }
877
          else if (G_FLD (inst->v, 29, 15) == 0x1c40
878
                   && G_FLD (inst->v, 2, 0) == 0x0)
879
            {
880
              /* lw r2, [r0]+, 4 */
881
              sp_offset -= SCORE_INSTLEN;
882
              fp_offset_p = 1;
883
            }
884
 
885
          else if (G_FLD (inst->v, 29, 17) == 0x100
886
                   && G_FLD (inst->v, 0, 0) == 0x0)
887
            {
888
              /* addi r0, -offset */
889
              sp_offset += 65536 - G_FLD (inst->v, 16, 1);
890
            }
891
          else if (G_FLD (inst->v, 29, 17) == 0x110
892
                   && G_FLD (inst->v, 0, 0) == 0x0)
893
            {
894
              /* addi r2, offset */
895
              if (pc - cur_pc > 4)
896
                {
897
                  unsigned int save_v = inst->v;
898
                  inst_t *inst2 =
899
                    score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
900
                  if (inst2->v == 0x23)
901
                    {
902
                      /* mv! r0, r2 */
903
                      sp_offset -= G_FLD (save_v, 16, 1);
904
                    }
905
                }
906
            }
907
        }
908
    }
909
 
910
  /* Save RA.  */
911
  if (ra_offset_p == 1)
912
    {
913
      if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
914
        this_cache->saved_regs[SCORE_PC_REGNUM].addr =
915
          sp + sp_offset - ra_offset;
916
    }
917
  else
918
    {
919
      this_cache->saved_regs[SCORE_PC_REGNUM] =
920
        this_cache->saved_regs[SCORE_RA_REGNUM];
921
    }
922
 
923
  /* Save FP.  */
924
  if (fp_offset_p == 1)
925
    {
926
      if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
927
        this_cache->saved_regs[SCORE_FP_REGNUM].addr =
928
          sp + sp_offset - fp_offset;
929
    }
930
 
931
  /* Save SP and FP.  */
932
  this_cache->base = sp + sp_offset;
933
  this_cache->fp = fp;
934
 
935
  /* Don't forget to free MEMBLOCK if we allocated it.  */
936
  if (memblock_ptr != NULL)
937
    score_free_memblock (memblock_ptr);
938
}
939
 
940
static struct score_frame_cache *
941
score_make_prologue_cache (struct frame_info *next_frame, void **this_cache)
942
{
943
  struct score_frame_cache *cache;
944
 
945
  if ((*this_cache) != NULL)
946
    return (*this_cache);
947
 
948
  cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache);
949
  (*this_cache) = cache;
950
  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
951
 
952
  /* Analyze the prologue.  */
953
  {
954
    const CORE_ADDR pc = frame_pc_unwind (next_frame);
955
    CORE_ADDR start_addr;
956
 
957
    find_pc_partial_function (pc, NULL, &start_addr, NULL);
958
    if (start_addr == 0)
959
      return cache;
960
    score_analyze_prologue (start_addr, pc, next_frame, *this_cache);
961
  }
962
 
963
  /* Save SP.  */
964
  trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);
965
 
966
  return (*this_cache);
967
}
968
 
969
static void
970
score_prologue_this_id (struct frame_info *next_frame, void **this_cache,
971
                        struct frame_id *this_id)
972
{
973
  struct score_frame_cache *info = score_make_prologue_cache (next_frame,
974
                                                              this_cache);
975
  (*this_id) = frame_id_build (info->base,
976
                               frame_func_unwind (next_frame, NORMAL_FRAME));
977
}
978
 
979
static void
980
score_prologue_prev_register (struct frame_info *next_frame,
981
                              void **this_cache,
982
                              int regnum, int *optimizedp,
983
                              enum lval_type *lvalp, CORE_ADDR * addrp,
984
                              int *realnump, gdb_byte * valuep)
985
{
986
  struct score_frame_cache *info = score_make_prologue_cache (next_frame,
987
                                                              this_cache);
988
  trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
989
                                optimizedp, lvalp, addrp, realnump, valuep);
990
}
991
 
992
static const struct frame_unwind score_prologue_unwind =
993
{
994
  NORMAL_FRAME,
995
  score_prologue_this_id,
996
  score_prologue_prev_register
997
};
998
 
999
static const struct frame_unwind *
1000
score_prologue_sniffer (struct frame_info *next_frame)
1001
{
1002
  return &score_prologue_unwind;
1003
}
1004
 
1005
static CORE_ADDR
1006
score_prologue_frame_base_address (struct frame_info *next_frame,
1007
                                   void **this_cache)
1008
{
1009
  struct score_frame_cache *info =
1010
    score_make_prologue_cache (next_frame, this_cache);
1011
  return info->fp;
1012
}
1013
 
1014
static const struct frame_base score_prologue_frame_base =
1015
{
1016
  &score_prologue_unwind,
1017
  score_prologue_frame_base_address,
1018
  score_prologue_frame_base_address,
1019
  score_prologue_frame_base_address,
1020
};
1021
 
1022
static const struct frame_base *
1023
score_prologue_frame_base_sniffer (struct frame_info *next_frame)
1024
{
1025
  return &score_prologue_frame_base;
1026
}
1027
 
1028
static struct gdbarch *
1029
score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1030
{
1031
  struct gdbarch *gdbarch;
1032
 
1033
  arches = gdbarch_list_lookup_by_info (arches, &info);
1034
  if (arches != NULL)
1035
    {
1036
      return (arches->gdbarch);
1037
    }
1038
  gdbarch = gdbarch_alloc (&info, 0);
1039
 
1040
  set_gdbarch_short_bit (gdbarch, 16);
1041
  set_gdbarch_int_bit (gdbarch, 32);
1042
  set_gdbarch_float_bit (gdbarch, 32);
1043
  set_gdbarch_double_bit (gdbarch, 64);
1044
  set_gdbarch_long_double_bit (gdbarch, 64);
1045
  set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
1046
  set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
1047
  set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
1048
  set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
1049
  set_gdbarch_register_name (gdbarch, score_register_name);
1050
  set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
1051
  set_gdbarch_register_type (gdbarch, score_register_type);
1052
  set_gdbarch_frame_align (gdbarch, score_frame_align);
1053
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1054
  set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1055
  set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
1056
  set_gdbarch_print_insn (gdbarch, score_print_insn);
1057
  set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
1058
  set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
1059
 
1060
  /* Watchpoint hooks.  */
1061
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
1062
 
1063
  /* Dummy frame hooks.  */
1064
  set_gdbarch_return_value (gdbarch, score_return_value);
1065
  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1066
  set_gdbarch_unwind_dummy_id (gdbarch, score_unwind_dummy_id);
1067
  set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);
1068
 
1069
  /* Normal frame hooks.  */
1070
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1071
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
1072
  frame_unwind_append_sniffer (gdbarch, score_prologue_sniffer);
1073
  frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);
1074
 
1075
  return gdbarch;
1076
}
1077
 
1078
extern initialize_file_ftype _initialize_score_tdep;
1079
 
1080
void
1081
_initialize_score_tdep (void)
1082
{
1083
  gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
1084
}

powered by: WebSVN 2.1.0

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