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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 227 jeremybenn
/* Target-dependent code for Moxie.
2
 
3
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "frame.h"
22
#include "frame-unwind.h"
23
#include "frame-base.h"
24
#include "symtab.h"
25
#include "gdbtypes.h"
26
#include "gdbcmd.h"
27
#include "gdbcore.h"
28
#include "gdb_string.h"
29
#include "value.h"
30
#include "inferior.h"
31
#include "symfile.h"
32
#include "objfiles.h"
33
#include "osabi.h"
34
#include "language.h"
35
#include "arch-utils.h"
36
#include "regcache.h"
37
#include "trad-frame.h"
38
#include "dis-asm.h"
39
#include "record.h"
40
 
41
#include "gdb_assert.h"
42
 
43
#include "moxie-tdep.h"
44
 
45
/* Local functions.  */
46
 
47
extern void _initialize_moxie_tdep (void);
48
 
49
/* Use an invalid address value as 'not available' marker.  */
50
enum { REG_UNAVAIL = (CORE_ADDR) -1 };
51
 
52
struct moxie_frame_cache
53
{
54
  /* Base address.  */
55
  CORE_ADDR base;
56
  CORE_ADDR pc;
57
  LONGEST framesize;
58
  CORE_ADDR saved_regs[MOXIE_NUM_REGS];
59
  CORE_ADDR saved_sp;
60
};
61
 
62
/* Implement the "frame_align" gdbarch method.  */
63
 
64
static CORE_ADDR
65
moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
66
{
67
  /* Align to the size of an instruction (so that they can safely be
68
     pushed onto the stack.  */
69
  return sp & ~1;
70
}
71
 
72
/* Implement the "breakpoint_from_pc" gdbarch method.  */
73
 
74
const static unsigned char *
75
moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
76
                          CORE_ADDR *pcptr, int *lenptr)
77
{
78
  static unsigned char breakpoint[] = { 0x35, 0x00 };
79
 
80
  *lenptr = sizeof (breakpoint);
81
  return breakpoint;
82
}
83
 
84
/* Moxie register names.  */
85
 
86
char *moxie_register_names[] = {
87
  "$fp",  "$sp",  "$r0",  "$r1",  "$r2",
88
  "$r3",  "$r4",  "$r5", "$r6", "$r7",
89
  "$r8", "$r9", "$r10", "$r11", "$r12",
90
  "$r13", "$pc", "$cc" };
91
 
92
/* Implement the "register_name" gdbarch method.  */
93
 
94
static const char *
95
moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
96
{
97
  if (reg_nr < 0)
98
    return NULL;
99
  if (reg_nr >= MOXIE_NUM_REGS)
100
    return NULL;
101
  return moxie_register_names[reg_nr];
102
}
103
 
104
/* Implement the "register_type" gdbarch method.  */
105
 
106
static struct type *
107
moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
108
{
109
  if (reg_nr == MOXIE_PC_REGNUM)
110
    return  builtin_type (gdbarch)->builtin_func_ptr;
111
  else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
112
    return builtin_type (gdbarch)->builtin_data_ptr;
113
  else
114
    return builtin_type (gdbarch)->builtin_int32;
115
}
116
 
117
/* Write into appropriate registers a function return value
118
   of type TYPE, given in virtual format.  */
119
 
120
static void
121
moxie_store_return_value (struct type *type, struct regcache *regcache,
122
                         const void *valbuf)
123
{
124
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
125
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
126
  CORE_ADDR regval;
127
  int len = TYPE_LENGTH (type);
128
 
129
  /* Things always get returned in RET1_REGNUM, RET2_REGNUM.  */
130
  regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
131
  regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
132
  if (len > 4)
133
    {
134
      regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
135
                                         len - 4, byte_order);
136
      regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
137
    }
138
}
139
 
140
/* Decode the instructions within the given address range.  Decide
141
   when we must have reached the end of the function prologue.  If a
142
   frame_info pointer is provided, fill in its saved_regs etc.
143
 
144
   Returns the address of the first instruction after the prologue.  */
145
 
146
static CORE_ADDR
147
moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
148
                        struct moxie_frame_cache *cache,
149
                        struct gdbarch *gdbarch)
150
{
151
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
152
  CORE_ADDR next_addr;
153
  ULONGEST inst, inst2;
154
  LONGEST offset;
155
  int regnum;
156
 
157
  /* Record where the jsra instruction saves the PC and FP.  */
158
  cache->saved_regs[MOXIE_PC_REGNUM] = -4;
159
  cache->saved_regs[MOXIE_FP_REGNUM] = 0;
160
  cache->framesize = 0;
161
 
162
  if (start_addr >= end_addr)
163
    return end_addr;
164
 
165
  for (next_addr = start_addr; next_addr < end_addr; )
166
    {
167
      inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
168
 
169
      /* Match "push $rN" where N is between 2 and 13 inclusive.  */
170
      if (inst >= 0x0614 && inst <= 0x061f)
171
        {
172
          regnum = inst & 0x000f;
173
          cache->framesize += 4;
174
          cache->saved_regs[regnum] = cache->framesize;
175
          next_addr += 2;
176
        }
177
      else
178
        break;
179
    }
180
 
181
  inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
182
 
183
  /* Optional stack allocation for args and local vars <= 4
184
     byte.  */
185
  if (inst == 0x0170)           /* ldi.l $r5, X */
186
    {
187
      offset = read_memory_integer (next_addr + 2, 4, byte_order);
188
      inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
189
 
190
      if (inst2 == 0x0517)           /* add.l $sp, $r5 */
191
        {
192
          cache->framesize += offset;
193
        }
194
 
195
      return (next_addr + 8);
196
    }
197
  else if ((inst & 0xff00) == 0x91)   /* dec $sp, X */
198
    {
199
      cache->framesize += (inst & 0x00ff);
200
      next_addr += 2;
201
 
202
      while (next_addr < end_addr)
203
        {
204
          inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
205
          if ((inst & 0xff00) != 0x91) /* no more dec $sp, X */
206
            break;
207
          cache->framesize += (inst & 0x00ff);
208
          next_addr += 2;
209
        }
210
    }
211
 
212
  return next_addr;
213
}
214
 
215
/* Find the end of function prologue.  */
216
 
217
static CORE_ADDR
218
moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
219
{
220
  CORE_ADDR func_addr = 0, func_end = 0;
221
  char *func_name;
222
 
223
  /* See if we can determine the end of the prologue via the symbol table.
224
     If so, then return either PC, or the PC after the prologue, whichever
225
     is greater.  */
226
  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
227
    {
228
      CORE_ADDR post_prologue_pc
229
        = skip_prologue_using_sal (gdbarch, func_addr);
230
      if (post_prologue_pc != 0)
231
        return max (pc, post_prologue_pc);
232
      else
233
        {
234
          /* Can't determine prologue from the symbol table, need to examine
235
             instructions.  */
236
          struct symtab_and_line sal;
237
          struct symbol *sym;
238
          struct moxie_frame_cache cache;
239
          CORE_ADDR plg_end;
240
 
241
          memset (&cache, 0, sizeof cache);
242
 
243
          plg_end = moxie_analyze_prologue (func_addr,
244
                                            func_end, &cache, gdbarch);
245
          /* Found a function.  */
246
          sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
247
          /* Don't use line number debug info for assembly source
248
             files. */
249
          if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
250
            {
251
              sal = find_pc_line (func_addr, 0);
252
              if (sal.end && sal.end < func_end)
253
                {
254
                  /* Found a line number, use it as end of
255
                     prologue.  */
256
                  return sal.end;
257
                }
258
            }
259
          /* No useable line symbol.  Use result of prologue parsing
260
             method.  */
261
          return plg_end;
262
        }
263
    }
264
 
265
  /* No function symbol -- just return the PC.  */
266
  return (CORE_ADDR) pc;
267
}
268
 
269
struct moxie_unwind_cache
270
{
271
  /* The previous frame's inner most stack address.  Used as this
272
     frame ID's stack_addr.  */
273
  CORE_ADDR prev_sp;
274
  /* The frame's base, optionally used by the high-level debug info.  */
275
  CORE_ADDR base;
276
  int size;
277
  /* How far the SP and r13 (FP) have been offset from the start of
278
     the stack frame (as defined by the previous frame's stack
279
     pointer).  */
280
  LONGEST sp_offset;
281
  LONGEST r13_offset;
282
  int uses_frame;
283
  /* Table indicating the location of each and every register.  */
284
  struct trad_frame_saved_reg *saved_regs;
285
};
286
 
287
/* Implement the "read_pc" gdbarch method.  */
288
 
289
static CORE_ADDR
290
moxie_read_pc (struct regcache *regcache)
291
{
292
  ULONGEST pc;
293
 
294
  regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
295
  return pc;
296
}
297
 
298
/* Implement the "write_pc" gdbarch method.  */
299
 
300
static void
301
moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
302
{
303
  regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
304
}
305
 
306
/* Implement the "unwind_sp" gdbarch method.  */
307
 
308
static CORE_ADDR
309
moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
310
{
311
  return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
312
}
313
 
314
/* Given a return value in `regbuf' with a type `valtype',
315
   extract and copy its value into `valbuf'.  */
316
 
317
static void
318
moxie_extract_return_value (struct type *type, struct regcache *regcache,
319
                           void *dst)
320
{
321
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
322
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
323
  bfd_byte *valbuf = dst;
324
  int len = TYPE_LENGTH (type);
325
  ULONGEST tmp;
326
 
327
  /* By using store_unsigned_integer we avoid having to do
328
     anything special for small big-endian values.  */
329
  regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
330
  store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
331
 
332
  /* Ignore return values more than 8 bytes in size because the moxie
333
     returns anything more than 8 bytes in the stack.  */
334
  if (len > 4)
335
    {
336
      regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
337
      store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
338
    }
339
}
340
 
341
/* Implement the "return_value" gdbarch method.  */
342
 
343
static enum return_value_convention
344
moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
345
                   struct type *valtype, struct regcache *regcache,
346
                   gdb_byte *readbuf, const gdb_byte *writebuf)
347
{
348
  if (TYPE_LENGTH (valtype) > 8)
349
    return RETURN_VALUE_STRUCT_CONVENTION;
350
  else
351
    {
352
      if (readbuf != NULL)
353
        moxie_extract_return_value (valtype, regcache, readbuf);
354
      if (writebuf != NULL)
355
        moxie_store_return_value (valtype, regcache, writebuf);
356
      return RETURN_VALUE_REGISTER_CONVENTION;
357
    }
358
}
359
 
360
/* Allocate and initialize a moxie_frame_cache object.  */
361
 
362
static struct moxie_frame_cache *
363
moxie_alloc_frame_cache (void)
364
{
365
  struct moxie_frame_cache *cache;
366
  int i;
367
 
368
  cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
369
 
370
  cache->base = 0;
371
  cache->saved_sp = 0;
372
  cache->pc = 0;
373
  cache->framesize = 0;
374
  for (i = 0; i < MOXIE_NUM_REGS; ++i)
375
    cache->saved_regs[i] = REG_UNAVAIL;
376
 
377
  return cache;
378
}
379
 
380
/* Populate a moxie_frame_cache object for this_frame.  */
381
 
382
static struct moxie_frame_cache *
383
moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
384
{
385
  struct moxie_frame_cache *cache;
386
  CORE_ADDR current_pc;
387
  int i;
388
 
389
  if (*this_cache)
390
    return *this_cache;
391
 
392
  cache = moxie_alloc_frame_cache ();
393
  *this_cache = cache;
394
 
395
  cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
396
  if (cache->base == 0)
397
    return cache;
398
 
399
  cache->pc = get_frame_func (this_frame);
400
  current_pc = get_frame_pc (this_frame);
401
  if (cache->pc)
402
    {
403
      struct gdbarch *gdbarch = get_frame_arch (this_frame);
404
      moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
405
    }
406
 
407
  cache->saved_sp = cache->base - cache->framesize;
408
 
409
  for (i = 0; i < MOXIE_NUM_REGS; ++i)
410
    if (cache->saved_regs[i] != REG_UNAVAIL)
411
      cache->saved_regs[i] = cache->base - cache->saved_regs[i];
412
 
413
  return cache;
414
}
415
 
416
/* Implement the "unwind_pc" gdbarch method.  */
417
 
418
static CORE_ADDR
419
moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
420
{
421
  return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
422
}
423
 
424
/* Given a GDB frame, determine the address of the calling function's
425
   frame.  This will be used to create a new GDB frame struct.  */
426
 
427
static void
428
moxie_frame_this_id (struct frame_info *this_frame,
429
                    void **this_prologue_cache, struct frame_id *this_id)
430
{
431
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
432
                                                   this_prologue_cache);
433
 
434
  /* This marks the outermost frame.  */
435
  if (cache->base == 0)
436
    return;
437
 
438
  *this_id = frame_id_build (cache->saved_sp, cache->pc);
439
}
440
 
441
/* Get the value of register regnum in the previous stack frame.  */
442
 
443
static struct value *
444
moxie_frame_prev_register (struct frame_info *this_frame,
445
                          void **this_prologue_cache, int regnum)
446
{
447
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
448
                                                   this_prologue_cache);
449
 
450
  gdb_assert (regnum >= 0);
451
 
452
  if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
453
    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
454
 
455
  if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
456
    return frame_unwind_got_memory (this_frame, regnum,
457
                                    cache->saved_regs[regnum]);
458
 
459
  return frame_unwind_got_register (this_frame, regnum, regnum);
460
}
461
 
462
static const struct frame_unwind moxie_frame_unwind = {
463
  NORMAL_FRAME,
464
  moxie_frame_this_id,
465
  moxie_frame_prev_register,
466
  NULL,
467
  default_frame_sniffer
468
};
469
 
470
/* Return the base address of this_frame.  */
471
 
472
static CORE_ADDR
473
moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
474
{
475
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
476
                                                       this_cache);
477
 
478
  return cache->base;
479
}
480
 
481
static const struct frame_base moxie_frame_base = {
482
  &moxie_frame_unwind,
483
  moxie_frame_base_address,
484
  moxie_frame_base_address,
485
  moxie_frame_base_address
486
};
487
 
488
static struct frame_id
489
moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
490
{
491
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
492
 
493
  return frame_id_build (sp, get_frame_pc (this_frame));
494
}
495
 
496
/* Read an unsigned integer from the inferior, and adjust
497
   endianess.  */
498
static ULONGEST
499
moxie_process_readu (CORE_ADDR addr, char *buf,
500
                     int length, enum bfd_endian byte_order)
501
{
502
  if (target_read_memory (addr, buf, length))
503
    {
504
      if (record_debug)
505
        printf_unfiltered (_("Process record: error reading memory at "
506
                             "addr 0x%s len = %d.\n"),
507
                           paddress (target_gdbarch, addr), length);
508
      return -1;
509
    }
510
 
511
  return extract_unsigned_integer (buf, length, byte_order);
512
}
513
 
514
/* Parse the current instruction and record the values of the registers and
515
   memory that will be changed in current instruction to "record_arch_list".
516
   Return -1 if something wrong. */
517
 
518
int
519
moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
520
                      CORE_ADDR addr)
521
{
522
  gdb_byte buf[4];
523
  uint16_t inst;
524
  uint32_t tmpu32;
525
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
526
 
527
  if (record_debug > 1)
528
    fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
529
                                    "addr = 0x%s\n",
530
                        paddress (target_gdbarch, addr));
531
 
532
  inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
533
 
534
  /* Decode instruction.  */
535
  if (inst & (1 << 15))
536
    {
537
      if (inst & (1 << 14))
538
        {
539
          /* This is a Form 3 instruction.  */
540
          int opcode = (inst >> 10 & 0xf);
541
 
542
          switch (opcode)
543
            {
544
            case 0x00: /* beq */
545
            case 0x01: /* bne */
546
            case 0x02: /* blt */
547
            case 0x03: /* bgt */
548
            case 0x04: /* bltu */
549
            case 0x05: /* bgtu */
550
            case 0x06: /* bge */
551
            case 0x07: /* ble */
552
            case 0x08: /* bgeu */
553
            case 0x09: /* bleu */
554
              /* Do nothing.  */
555
              break;
556
            default:
557
              {
558
                /* Do nothing.  */
559
                break;
560
              }
561
            }
562
        }
563
      else
564
        {
565
          /* This is a Form 2 instruction.  */
566
          int opcode = (inst >> 12 & 0x3);
567
          switch (opcode)
568
            {
569
            case 0x00: /* inc */
570
            case 0x01: /* dec */
571
            case 0x02: /* gsr */
572
              {
573
                int reg = (inst >> 8) & 0xf;
574
                if (record_arch_list_add_reg (regcache, reg))
575
                  return -1;
576
              }
577
              break;
578
            case 0x03: /* ssr */
579
              {
580
                /* Do nothing until GDB learns about moxie's special
581
                   registers.  */
582
              }
583
              break;
584
            default:
585
              /* Do nothing.  */
586
              break;
587
            }
588
        }
589
    }
590
  else
591
    {
592
      /* This is a Form 1 instruction.  */
593
      int opcode = inst >> 8;
594
 
595
      switch (opcode)
596
        {
597
        case 0x00: /* nop */
598
          /* Do nothing.  */
599
          break;
600
        case 0x01: /* ldi.l (immediate) */
601
        case 0x02: /* mov (register-to-register) */
602
          {
603
            int reg = (inst >> 4) & 0xf;
604
            if (record_arch_list_add_reg (regcache, reg))
605
              return -1;
606
          }
607
          break;
608
        case 0x03: /* jsra */
609
          {
610
            regcache_raw_read (regcache,
611
                               MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
612
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
613
                                               4, byte_order);
614
            if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
615
                || (record_arch_list_add_reg (regcache,
616
                                              MOXIE_SP_REGNUM))
617
                || record_arch_list_add_mem (tmpu32 - 12, 12))
618
              return -1;
619
          }
620
          break;
621
        case 0x04: /* ret */
622
          {
623
            if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
624
                || (record_arch_list_add_reg (regcache,
625
                                              MOXIE_SP_REGNUM)))
626
              return -1;
627
          }
628
          break;
629
        case 0x05: /* add.l */
630
          {
631
            int reg = (inst >> 4) & 0xf;
632
            if (record_arch_list_add_reg (regcache, reg))
633
              return -1;
634
          }
635
          break;
636
        case 0x06: /* push */
637
          {
638
            int reg = (inst >> 4) & 0xf;
639
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
640
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
641
                                               4, byte_order);
642
            if (record_arch_list_add_reg (regcache, reg)
643
                || record_arch_list_add_mem (tmpu32 - 4, 4))
644
              return -1;
645
          }
646
          break;
647
        case 0x07: /* pop */
648
          {
649
            int a = (inst >> 4) & 0xf;
650
            int b = inst & 0xf;
651
            if (record_arch_list_add_reg (regcache, a)
652
                || record_arch_list_add_reg (regcache, b))
653
              return -1;
654
          }
655
          break;
656
        case 0x08: /* lda.l */
657
          {
658
            int reg = (inst >> 4) & 0xf;
659
            if (record_arch_list_add_reg (regcache, reg))
660
              return -1;
661
          }
662
          break;
663
        case 0x09: /* sta.l */
664
          {
665
            tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
666
                                                     4, byte_order);
667
            if (record_arch_list_add_mem (tmpu32, 4))
668
              return -1;
669
          }
670
          break;
671
        case 0x0a: /* ld.l (register indirect) */
672
          {
673
            int reg = (inst >> 4) & 0xf;
674
            if (record_arch_list_add_reg (regcache, reg))
675
              return -1;
676
          }
677
          break;
678
        case 0x0b: /* st.l */
679
          {
680
            int reg = (inst >> 4) & 0xf;
681
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
682
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
683
                                               4, byte_order);
684
            if (record_arch_list_add_mem (tmpu32, 4))
685
              return -1;
686
          }
687
          break;
688
        case 0x0c: /* ldo.l */
689
          {
690
            int reg = (inst >> 4) & 0xf;
691
            if (record_arch_list_add_reg (regcache, reg))
692
              return -1;
693
          }
694
          break;
695
        case 0x0d: /* sto.l */
696
          {
697
            int reg = (inst >> 4) & 0xf;
698
            uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
699
                                                              byte_order);
700
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
701
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
702
                                               4, byte_order);
703
            tmpu32 += offset;
704
            if (record_arch_list_add_mem (tmpu32, 4))
705
              return -1;
706
          }
707
          break;
708
        case 0x0e: /* cmp */
709
          {
710
            if (record_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
711
              return -1;
712
          }
713
          break;
714
        case 0x0f:
715
        case 0x10:
716
        case 0x11:
717
        case 0x12:
718
        case 0x13:
719
        case 0x14:
720
        case 0x15:
721
        case 0x16:
722
        case 0x17:
723
        case 0x18:
724
          {
725
            /* Do nothing.  */
726
            break;
727
          }
728
        case 0x19: /* jsr */
729
          {
730
            regcache_raw_read (regcache,
731
                               MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
732
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
733
                                               4, byte_order);
734
            if (record_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
735
                || (record_arch_list_add_reg (regcache,
736
                                              MOXIE_SP_REGNUM))
737
                || record_arch_list_add_mem (tmpu32 - 12, 12))
738
              return -1;
739
          }
740
          break;
741
        case 0x1a: /* jmpa */
742
          {
743
            /* Do nothing.  */
744
          }
745
          break;
746
        case 0x1b: /* ldi.b (immediate) */
747
        case 0x1c: /* ld.b (register indirect) */
748
        case 0x1d: /* lda.b */
749
          {
750
            int reg = (inst >> 4) & 0xf;
751
            if (record_arch_list_add_reg (regcache, reg))
752
              return -1;
753
          }
754
          break;
755
        case 0x1e: /* st.b */
756
          {
757
            int reg = (inst >> 4) & 0xf;
758
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
759
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
760
                                               4, byte_order);
761
            if (record_arch_list_add_mem (tmpu32, 1))
762
              return -1;
763
          }
764
          break;
765
        case 0x1f: /* sta.b */
766
          {
767
            tmpu32 = moxie_process_readu (addr+2, (char *) buf,
768
                                          4, byte_order);
769
            if (record_arch_list_add_mem (tmpu32, 1))
770
              return -1;
771
          }
772
          break;
773
        case 0x20: /* ldi.s (immediate) */
774
        case 0x21: /* ld.s (register indirect) */
775
        case 0x22: /* lda.s */
776
          {
777
            int reg = (inst >> 4) & 0xf;
778
            if (record_arch_list_add_reg (regcache, reg))
779
              return -1;
780
          }
781
          break;
782
        case 0x23: /* st.s */
783
          {
784
            int reg = (inst >> 4) & 0xf;
785
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
786
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
787
                                               4, byte_order);
788
            if (record_arch_list_add_mem (tmpu32, 2))
789
              return -1;
790
          }
791
          break;
792
        case 0x24: /* sta.s */
793
          {
794
            tmpu32 = moxie_process_readu (addr+2, (char *) buf,
795
                                          4, byte_order);
796
            if (record_arch_list_add_mem (tmpu32, 2))
797
              return -1;
798
          }
799
          break;
800
        case 0x25: /* jmp */
801
          {
802
            /* Do nothing.  */
803
          }
804
          break;
805
        case 0x26: /* and */
806
        case 0x27: /* lshr */
807
        case 0x28: /* ashl */
808
        case 0x29: /* sub.l */
809
        case 0x2a: /* neg */
810
        case 0x2b: /* or */
811
        case 0x2c: /* not */
812
        case 0x2d: /* ashr */
813
        case 0x2e: /* xor */
814
        case 0x2f: /* mul.l */
815
          {
816
            int reg = (inst >> 4) & 0xf;
817
            if (record_arch_list_add_reg (regcache, reg))
818
              return -1;
819
          }
820
          break;
821
        case 0x30: /* swi */
822
          {
823
            /* We currently implement support for libgloss'
824
               system calls.  */
825
 
826
            int inum = moxie_process_readu (addr+2, (char *) buf,
827
                                            4, byte_order);
828
 
829
            switch (inum)
830
              {
831
              case 0x1: /* SYS_exit */
832
                {
833
                  /* Do nothing.  */
834
                }
835
                break;
836
              case 0x2: /* SYS_open */
837
                {
838
                  if (record_arch_list_add_reg (regcache, RET1_REGNUM))
839
                    return -1;
840
                }
841
                break;
842
              case 0x4: /* SYS_read */
843
                {
844
                  uint32_t length, ptr;
845
 
846
                  /* Read buffer pointer is in $r1.  */
847
                  regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
848
                  ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
849
                                                  4, byte_order);
850
 
851
                  /* String length is at 0x12($fp) */
852
                  regcache_raw_read (regcache,
853
                                     MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
854
                  tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
855
                                                     4, byte_order);
856
                  length = moxie_process_readu (tmpu32+20, (char *) buf,
857
                                                4, byte_order);
858
 
859
                  if (record_arch_list_add_mem (ptr, length))
860
                    return -1;
861
                }
862
                break;
863
              case 0x5: /* SYS_write */
864
                {
865
                  if (record_arch_list_add_reg (regcache, RET1_REGNUM))
866
                    return -1;
867
                }
868
                break;
869
              default:
870
                break;
871
              }
872
          }
873
          break;
874
        case 0x31: /* div.l */
875
        case 0x32: /* udiv.l */
876
        case 0x33: /* mod.l */
877
        case 0x34: /* umod.l */
878
          {
879
            int reg = (inst >> 4) & 0xf;
880
            if (record_arch_list_add_reg (regcache, reg))
881
              return -1;
882
          }
883
          break;
884
        case 0x35: /* brk */
885
          /* Do nothing.  */
886
          break;
887
        case 0x36: /* ldo.b */
888
          {
889
            int reg = (inst >> 4) & 0xf;
890
            if (record_arch_list_add_reg (regcache, reg))
891
              return -1;
892
          }
893
          break;
894
        case 0x37: /* sto.b */
895
          {
896
            int reg = (inst >> 4) & 0xf;
897
            uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
898
                                                              byte_order);
899
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
900
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
901
                                               4, byte_order);
902
            tmpu32 += offset;
903
            if (record_arch_list_add_mem (tmpu32, 1))
904
              return -1;
905
          }
906
          break;
907
        case 0x38: /* ldo.s */
908
          {
909
            int reg = (inst >> 4) & 0xf;
910
            if (record_arch_list_add_reg (regcache, reg))
911
              return -1;
912
          }
913
          break;
914
        case 0x39: /* sto.s */
915
          {
916
            int reg = (inst >> 4) & 0xf;
917
            uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
918
                                                              byte_order);
919
            regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
920
            tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
921
                                               4, byte_order);
922
            tmpu32 += offset;
923
            if (record_arch_list_add_mem (tmpu32, 2))
924
              return -1;
925
          }
926
          break;
927
        default:
928
          /* Do nothing.  */
929
          break;
930
        }
931
    }
932
 
933
  if (record_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
934
    return -1;
935
  if (record_arch_list_add_end ())
936
    return -1;
937
  return 0;
938
}
939
 
940
/* Allocate and initialize the moxie gdbarch object.  */
941
 
942
static struct gdbarch *
943
moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
944
{
945
  struct gdbarch *gdbarch;
946
  struct gdbarch_tdep *tdep;
947
 
948
  /* If there is already a candidate, use it.  */
949
  arches = gdbarch_list_lookup_by_info (arches, &info);
950
  if (arches != NULL)
951
    return arches->gdbarch;
952
 
953
  /* Allocate space for the new architecture.  */
954
  tdep = XMALLOC (struct gdbarch_tdep);
955
  gdbarch = gdbarch_alloc (&info, tdep);
956
 
957
  set_gdbarch_read_pc (gdbarch, moxie_read_pc);
958
  set_gdbarch_write_pc (gdbarch, moxie_write_pc);
959
  set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
960
 
961
  set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
962
  set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
963
  set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
964
  set_gdbarch_register_name (gdbarch, moxie_register_name);
965
  set_gdbarch_register_type (gdbarch, moxie_register_type);
966
 
967
  set_gdbarch_return_value (gdbarch, moxie_return_value);
968
 
969
  set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
970
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
971
  set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
972
  set_gdbarch_frame_align (gdbarch, moxie_frame_align);
973
 
974
  frame_base_set_default (gdbarch, &moxie_frame_base);
975
 
976
  /* Methods for saving / extracting a dummy frame's ID.  The ID's
977
     stack address must match the SP value returned by
978
     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
979
  set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
980
 
981
  set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
982
 
983
  set_gdbarch_print_insn (gdbarch, print_insn_moxie);
984
 
985
  /* Hook in ABI-specific overrides, if they have been registered.  */
986
  gdbarch_init_osabi (info, gdbarch);
987
 
988
  /* Hook in the default unwinders.  */
989
  frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
990
 
991
  /* Support simple overlay manager.  */
992
  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
993
 
994
  /* Support reverse debugging.  */
995
  set_gdbarch_process_record (gdbarch, moxie_process_record);
996
 
997
  return gdbarch;
998
}
999
 
1000
/* Register this machine's init routine.  */
1001
 
1002
void
1003
_initialize_moxie_tdep (void)
1004
{
1005
  register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
1006
}

powered by: WebSVN 2.1.0

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