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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [microblaze-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 Xilinx MicroBlaze.
2
 
3
   Copyright 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 "arch-utils.h"
22
#include "dis-asm.h"
23
#include "frame.h"
24
#include "trad-frame.h"
25
#include "symtab.h"
26
#include "value.h"
27
#include "gdbcmd.h"
28
#include "breakpoint.h"
29
#include "inferior.h"
30
#include "regcache.h"
31
#include "target.h"
32
#include "frame.h"
33
#include "frame-base.h"
34
#include "frame-unwind.h"
35
#include "dwarf2-frame.h"
36
#include "osabi.h"
37
 
38
#include "gdb_assert.h"
39
#include "gdb_string.h"
40
#include "target-descriptions.h"
41
#include "opcodes/microblaze-opcm.h"
42
#include "opcodes/microblaze-dis.h"
43
#include "microblaze-tdep.h"
44
 
45
/* Instruction macros used for analyzing the prologue.  */
46
/* This set of instruction macros need to be changed whenever the
47
   prologue generated by the compiler could have more instructions or
48
   different type of instructions.
49
   This set also needs to be verified if it is complete.  */
50
#define IS_RETURN(op) (op == rtsd || op == rtid)
51
#define IS_UPDATE_SP(op, rd, ra) \
52
        ((op == addik || op == addi) && rd == REG_SP && ra == REG_SP)
53
#define IS_SPILL_SP(op, rd, ra) \
54
        ((op == swi || op == sw) && rd == REG_SP && ra == REG_SP)
55
#define IS_SPILL_REG(op, rd, ra) \
56
        ((op == swi || op == sw) && rd != REG_SP && ra == REG_SP)
57
#define IS_ALSO_SPILL_REG(op, rd, ra, rb) \
58
        ((op == swi || op == sw) && rd != REG_SP && ra == 0 && rb == REG_SP)
59
#define IS_SETUP_FP(op, ra, rb) \
60
        ((op == add || op == addik || op == addk) && ra == REG_SP && rb == 0)
61
#define IS_SPILL_REG_FP(op, rd, ra, fpregnum) \
62
        ((op == swi || op == sw) && rd != REG_SP && ra == fpregnum && ra != 0)
63
#define IS_SAVE_HIDDEN_PTR(op, rd, ra, rb) \
64
        ((op == add || op == addik) && ra == MICROBLAZE_FIRST_ARGREG && rb == 0)
65
 
66
/* The registers of the Xilinx microblaze processor.  */
67
 
68
static const char *microblaze_register_names[] =
69
{
70
  "r0",   "r1",  "r2",    "r3",   "r4",   "r5",   "r6",   "r7",
71
  "r8",   "r9",  "r10",   "r11",  "r12",  "r13",  "r14",  "r15",
72
  "r16",  "r17", "r18",   "r19",  "r20",  "r21",  "r22",  "r23",
73
  "r24",  "r25", "r26",   "r27",  "r28",  "r29",  "r30",  "r31",
74
  "rpc",  "rmsr", "rear", "resr", "rfsr", "rbtr",
75
  "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
76
  "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
77
  "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi"
78
};
79
 
80
#define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
81
 
82
static int microblaze_debug_flag = 0;
83
 
84
void
85
microblaze_debug (const char *fmt, ...)
86
{
87
  if (microblaze_debug_flag)
88
    {
89
       va_list args;
90
 
91
       va_start (args, fmt);
92
       printf_unfiltered ("MICROBLAZE: ");
93
       vprintf_unfiltered (fmt, args);
94
       va_end (args);
95
    }
96
}
97
 
98
/* Return the name of register REGNUM.  */
99
 
100
static const char *
101
microblaze_register_name (struct gdbarch *gdbarch, int regnum)
102
{
103
  if (regnum >= 0 && regnum < MICROBLAZE_NUM_REGS)
104
    return microblaze_register_names[regnum];
105
  return NULL;
106
}
107
 
108
static struct type *
109
microblaze_register_type (struct gdbarch *gdbarch, int regnum)
110
{
111
  if (regnum == MICROBLAZE_SP_REGNUM)
112
    return builtin_type (gdbarch)->builtin_data_ptr;
113
 
114
  if (regnum == MICROBLAZE_PC_REGNUM)
115
    return builtin_type (gdbarch)->builtin_func_ptr;
116
 
117
  return builtin_type (gdbarch)->builtin_int;
118
}
119
 
120
 
121
/* Fetch the instruction at PC.  */
122
 
123
unsigned long
124
microblaze_fetch_instruction (CORE_ADDR pc)
125
{
126
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
127
  gdb_byte buf[4];
128
 
129
  /* If we can't read the instruction at PC, return zero.  */
130
  if (target_read_memory (pc, buf, sizeof (buf)))
131
    return 0;
132
 
133
  return extract_unsigned_integer (buf, 4, byte_order);
134
}
135
 
136
 
137
static CORE_ADDR
138
microblaze_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
139
                            CORE_ADDR funcaddr,
140
                            struct value **args, int nargs,
141
                            struct type *value_type,
142
                            CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
143
                            struct regcache *regcache)
144
{
145
  error (_("push_dummy_code not implemented"));
146
  return sp;
147
}
148
 
149
 
150
static CORE_ADDR
151
microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
152
                            struct regcache *regcache, CORE_ADDR bp_addr,
153
                            int nargs, struct value **args, CORE_ADDR sp,
154
                            int struct_return, CORE_ADDR struct_addr)
155
{
156
  error (_("store_arguments not implemented"));
157
  return sp;
158
}
159
 
160
static const gdb_byte *
161
microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc,
162
                               int *len)
163
{
164
  static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT;
165
 
166
  *len = sizeof (break_insn);
167
  return break_insn;
168
}
169
 
170
/* Allocate and initialize a frame cache.  */
171
 
172
static struct microblaze_frame_cache *
173
microblaze_alloc_frame_cache (void)
174
{
175
  struct microblaze_frame_cache *cache;
176
  int i;
177
 
178
  cache = FRAME_OBSTACK_ZALLOC (struct microblaze_frame_cache);
179
 
180
  /* Base address.  */
181
  cache->base = 0;
182
  cache->pc = 0;
183
 
184
  /* Frameless until proven otherwise.  */
185
  cache->frameless_p = 1;
186
 
187
  return cache;
188
}
189
 
190
/* The base of the current frame is actually in the stack pointer.
191
   This happens when there is no frame pointer (microblaze ABI does not
192
   require a frame pointer) or when we're stopped in the prologue or
193
   epilogue itself.  In these cases, microblaze_analyze_prologue will need
194
   to update fi->frame before returning or analyzing the register
195
   save instructions.  */
196
#define MICROBLAZE_MY_FRAME_IN_SP 0x1
197
 
198
/* The base of the current frame is in a frame pointer register.
199
   This register is noted in frame_extra_info->fp_regnum.
200
 
201
   Note that the existance of an FP might also indicate that the
202
   function has called alloca.  */
203
#define MICROBLAZE_MY_FRAME_IN_FP 0x2
204
 
205
/* Function prologues on the Xilinx microblaze processors consist of:
206
 
207
   - adjustments to the stack pointer (r1) (addi r1, r1, imm)
208
   - making a copy of r1 into another register (a "frame" pointer)
209
     (add r?, r1, r0)
210
   - store word/multiples that use r1 or the frame pointer as the
211
     base address (swi r?, r1, imm OR swi r?, fp, imm)
212
 
213
   Note that microblaze really doesn't have a real frame pointer.
214
   Instead, the compiler may copy the SP into a register (usually
215
   r19) to act as an arg pointer.  For our target-dependent purposes,
216
   the frame info's "frame" member will be the beginning of the
217
   frame.  The SP could, in fact, point below this.
218
 
219
   The prologue ends when an instruction fails to meet either of
220
   these criteria.  */
221
 
222
/* Analyze the prologue to determine where registers are saved,
223
   the end of the prologue, etc.  Return the address of the first line
224
   of "real" code (i.e., the end of the prologue). */
225
 
226
static CORE_ADDR
227
microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
228
                             CORE_ADDR current_pc,
229
                             struct microblaze_frame_cache *cache)
230
{
231
  char *name;
232
  CORE_ADDR func_addr, func_end, addr, stop, prologue_end_addr = 0;
233
  unsigned long insn;
234
  int rn, rd, ra, rb, imm;
235
  enum microblaze_instr op;
236
  int flags = 0;
237
  int save_hidden_pointer_found = 0;
238
  int non_stack_instruction_found = 0;
239
 
240
  /* Find the start of this function. */
241
  find_pc_partial_function (pc, &name, &func_addr, &func_end);
242
  if (func_addr < pc)
243
    pc = func_addr;
244
 
245
  if (current_pc < pc)
246
    return current_pc;
247
 
248
   /* Initialize info about frame.  */
249
   cache->framesize = 0;
250
   cache->fp_regnum = MICROBLAZE_SP_REGNUM;
251
   cache->frameless_p = 1;
252
 
253
  /* Start decoding the prologue.  We start by checking two special cases:
254
 
255
     1. We're about to return
256
     2. We're at the first insn of the prologue.
257
 
258
     If we're about to return, our frame has already been deallocated.
259
     If we are stopped at the first instruction of a prologue,
260
     then our frame has not yet been set up. */
261
 
262
  /* Get the first insn from memory.  */
263
 
264
  insn = microblaze_fetch_instruction (pc);
265
  op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
266
 
267
  if (IS_RETURN(op))
268
    return pc;
269
 
270
  /* Start at beginning of function and analyze until we get to the
271
     current pc, or the end of the function, whichever is first.  */
272
  stop = (current_pc < func_end ? current_pc : func_end);
273
 
274
  microblaze_debug ("Scanning prologue: name=%s, func_addr=%s, stop=%s\n",
275
                    name, paddress (gdbarch, func_addr),
276
                    paddress (gdbarch, stop));
277
 
278
  for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE)
279
    {
280
      insn = microblaze_fetch_instruction (addr);
281
      op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
282
      microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn);
283
 
284
      /* This code is very sensitive to what functions are present in the
285
         prologue.  It assumes that the (addi, addik, swi, sw) can be the
286
         only instructions in the prologue.  */
287
      if (IS_UPDATE_SP(op, rd, ra))
288
        {
289
          microblaze_debug ("got addi r1,r1,%d; contnuing\n", imm);
290
          if (cache->framesize)
291
            break;      /* break if framesize already computed.  */
292
          cache->framesize = -imm; /* stack grows towards low memory.  */
293
          cache->frameless_p = 0; /* Frame found.  */
294
          save_hidden_pointer_found = 0;
295
          non_stack_instruction_found = 0;
296
          continue;
297
        }
298
      else if (IS_SPILL_SP(op, rd, ra))
299
        {
300
          /* Spill stack pointer.  */
301
          cache->register_offsets[rd] = imm; /* SP spilled before updating.  */
302
 
303
          microblaze_debug ("swi r1 r1 %d, continuing\n", imm);
304
          save_hidden_pointer_found = 0;
305
          if (!cache->framesize)
306
            non_stack_instruction_found = 0;
307
          continue;
308
        }
309
      else if (IS_SPILL_REG(op, rd, ra))
310
        {
311
          /* Spill register.  */
312
          cache->register_offsets[rd] = imm - cache->framesize;
313
 
314
          microblaze_debug ("swi %d r1 %d, continuing\n", rd, imm);
315
          save_hidden_pointer_found = 0;
316
          if (!cache->framesize)
317
            non_stack_instruction_found = 0;
318
          continue;
319
        }
320
      else if (IS_ALSO_SPILL_REG(op, rd, ra, rb))
321
        {
322
          /* Spill register.  */
323
          cache->register_offsets[rd] = 0 - cache->framesize;
324
 
325
          microblaze_debug ("sw %d r0 r1, continuing\n", rd);
326
          save_hidden_pointer_found = 0;
327
          if (!cache->framesize)
328
            non_stack_instruction_found = 0;
329
          continue;
330
        }
331
      else if (IS_SETUP_FP(op, ra, rb))
332
        {
333
          /* We have a frame pointer.  Note the register which is
334
             acting as the frame pointer. */
335
          flags |= MICROBLAZE_MY_FRAME_IN_FP;
336
          flags &= ~MICROBLAZE_MY_FRAME_IN_SP;
337
          cache->fp_regnum = rd;
338
          microblaze_debug ("Found a frame pointer: r%d\n", cache->fp_regnum);
339
          save_hidden_pointer_found = 0;
340
          if (!cache->framesize)
341
            non_stack_instruction_found = 0;
342
          continue;
343
        }
344
      else if (IS_SPILL_REG_FP(op, rd, ra, cache->fp_regnum))
345
        {
346
          /* reg spilled after updating.  */
347
          cache->register_offsets[rd] = imm - cache->framesize;
348
 
349
          microblaze_debug ("swi %d %d %d, continuing\n", rd, ra, imm);
350
          save_hidden_pointer_found = 0;
351
          if (!cache->framesize)
352
            non_stack_instruction_found = 0;
353
          continue;
354
        }
355
      else if (IS_SAVE_HIDDEN_PTR(op, rd, ra, rb))
356
        {
357
          /* If the first argument is a hidden pointer to the area where the
358
             return structure is to be saved, then it is saved as part of the
359
             prologue.  */
360
 
361
          microblaze_debug ("add %d %d %d, continuing\n", rd, ra, rb);
362
          save_hidden_pointer_found = 1;
363
          if (!cache->framesize)
364
            non_stack_instruction_found = 0;
365
          continue;
366
        }
367
 
368
      /* As a result of the modification in the next step where we continue
369
         to analyze the prologue till we reach a control flow instruction,
370
         we need another variable to store when exactly a non-stack
371
         instruction was encountered, which is the current definition
372
         of a prologue.  */
373
      if (!non_stack_instruction_found)
374
        prologue_end_addr = addr;
375
      non_stack_instruction_found = 1;
376
 
377
      /* When optimizations are enabled, it is not guaranteed that prologue
378
         instructions are not mixed in with other instructions from the
379
         program. Some programs show this behavior at -O2. This can be
380
         avoided by adding -fno-schedule-insns2 switch as of now (edk 8.1)
381
         In such cases, we scan the function until we see the first control
382
         instruction.  */
383
 
384
      {
385
        unsigned op = (unsigned)insn >> 26;
386
 
387
        /* continue if not control flow (branch, return).  */
388
        if (op != 0x26 && op != 0x27 && op != 0x2d && op != 0x2e && op != 0x2f)
389
          continue;
390
        else if (op == 0x2c)
391
          continue;    /* continue if imm.  */
392
      }
393
 
394
      /* This is not a prologue insn, so stop here. */
395
      microblaze_debug ("insn is not a prologue insn -- ending scan\n");
396
      break;
397
    }
398
 
399
  microblaze_debug ("done analyzing prologue\n");
400
  microblaze_debug ("prologue end = 0x%x\n", (int) addr);
401
 
402
  /* If the last instruction was an add rd, r5, r0 then don't count it as
403
     part of the prologue.  */
404
  if (save_hidden_pointer_found)
405
    prologue_end_addr -= INST_WORD_SIZE;
406
 
407
  return prologue_end_addr;
408
}
409
 
410
static CORE_ADDR
411
microblaze_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
412
{
413
  gdb_byte buf[4];
414
  CORE_ADDR pc;
415
 
416
  frame_unwind_register (next_frame, MICROBLAZE_PC_REGNUM, buf);
417
  pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
418
  /* For sentinel frame, return address is actual PC.  For other frames,
419
     return address is pc+8.  This is a workaround because gcc does not
420
     generate correct return address in CIE.  */
421
  if (frame_relative_level (next_frame) >= 0)
422
    pc += 8;
423
  return pc;
424
}
425
 
426
/* Return PC of first real instruction of the function starting at
427
   START_PC.  */
428
 
429
CORE_ADDR
430
microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
431
{
432
  struct symtab_and_line sal;
433
  CORE_ADDR func_start, func_end, ostart_pc;
434
  struct microblaze_frame_cache cache;
435
 
436
  /* This is the preferred method, find the end of the prologue by
437
     using the debugging information.  Debugging info does not always
438
     give the right answer since parameters are stored on stack after this.
439
     Always analyze the prologue.  */
440
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
441
    {
442
      sal = find_pc_line (func_start, 0);
443
 
444
      if (sal.end < func_end
445
          && start_pc <= sal.end)
446
        start_pc = sal.end;
447
    }
448
 
449
  ostart_pc = microblaze_analyze_prologue (gdbarch, func_start, 0xffffffffUL,
450
                                           &cache);
451
 
452
  if (ostart_pc > start_pc)
453
    return ostart_pc;
454
  return start_pc;
455
}
456
 
457
/* Normal frames.  */
458
 
459
struct microblaze_frame_cache *
460
microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
461
{
462
  struct microblaze_frame_cache *cache;
463
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
464
  CORE_ADDR func, pc, fp;
465
  int rn;
466
 
467
  if (*this_cache)
468
    return *this_cache;
469
 
470
  cache = microblaze_alloc_frame_cache ();
471
  *this_cache = cache;
472
  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
473
 
474
  /* Clear offsets to saved regs in frame.  */
475
  for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
476
    cache->register_offsets[rn] = -1;
477
 
478
  func = get_frame_func (next_frame);
479
 
480
  cache->pc = get_frame_address_in_block (next_frame);
481
 
482
  return cache;
483
}
484
 
485
static void
486
microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
487
                       struct frame_id *this_id)
488
{
489
  struct microblaze_frame_cache *cache =
490
    microblaze_frame_cache (next_frame, this_cache);
491
 
492
  /* This marks the outermost frame.  */
493
  if (cache->base == 0)
494
    return;
495
 
496
  (*this_id) = frame_id_build (cache->base, cache->pc);
497
}
498
 
499
static struct value *
500
microblaze_frame_prev_register (struct frame_info *this_frame,
501
                                 void **this_cache, int regnum)
502
{
503
  struct microblaze_frame_cache *cache =
504
    microblaze_frame_cache (this_frame, this_cache);
505
 
506
  if (cache->frameless_p)
507
    {
508
      if (regnum == MICROBLAZE_PC_REGNUM)
509
        regnum = 15;
510
      if (regnum == MICROBLAZE_SP_REGNUM)
511
        regnum = 1;
512
      return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
513
    }
514
  else
515
    return trad_frame_get_prev_register (this_frame, cache->saved_regs,
516
                                         regnum);
517
 
518
}
519
 
520
static const struct frame_unwind microblaze_frame_unwind =
521
{
522
  NORMAL_FRAME,
523
  microblaze_frame_this_id,
524
  microblaze_frame_prev_register,
525
  NULL,
526
  default_frame_sniffer
527
};
528
 
529
static CORE_ADDR
530
microblaze_frame_base_address (struct frame_info *next_frame, void **this_cache)
531
{
532
  struct microblaze_frame_cache *cache =
533
    microblaze_frame_cache (next_frame, this_cache);
534
 
535
  return cache->base;
536
}
537
 
538
static const struct frame_base microblaze_frame_base =
539
{
540
  &microblaze_frame_unwind,
541
  microblaze_frame_base_address,
542
  microblaze_frame_base_address,
543
  microblaze_frame_base_address
544
};
545
 
546
/* Extract from an array REGBUF containing the (raw) register state, a
547
   function return value of TYPE, and copy that into VALBUF.  */
548
static void
549
microblaze_extract_return_value (struct type *type, struct regcache *regcache,
550
                                 gdb_byte *valbuf)
551
{
552
  gdb_byte buf[8];
553
 
554
  /* Copy the return value (starting) in RETVAL_REGNUM to VALBUF.  */
555
  switch (TYPE_LENGTH (type))
556
    {
557
      case 1:   /* return last byte in the register.  */
558
        regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
559
        memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 1, 1);
560
        return;
561
      case 2:   /* return last 2 bytes in register.  */
562
        memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 2, 2);
563
        return;
564
      case 4:   /* for sizes 4 or 8, copy the required length.  */
565
      case 8:
566
        regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
567
        regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf+4);
568
        memcpy (valbuf, buf, TYPE_LENGTH (type));
569
        return;
570
      default:
571
        internal_error (__FILE__, __LINE__,
572
                        _("Unsupported return value size requested"));
573
    }
574
}
575
 
576
/* Store the return value in VALBUF (of type TYPE) where the caller
577
   expects to see it.
578
 
579
   Integers up to four bytes are stored in r3.
580
 
581
   Longs are stored in r3 (most significant word) and r4 (least
582
   significant word).
583
 
584
   Small structures are always returned on stack.
585
*/
586
 
587
static void
588
microblaze_store_return_value (struct type *type, struct regcache *regcache,
589
                               const gdb_byte *valbuf)
590
{
591
  int len = TYPE_LENGTH (type);
592
  gdb_byte buf[8];
593
 
594
  memset (buf, 0, sizeof(buf));
595
 
596
  /* Integral and pointer return values.  */
597
 
598
  if (len > 4)
599
    {
600
       gdb_assert (len == 8);
601
       memcpy (buf, valbuf, 8);
602
       regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf + 4);
603
    }
604
  else
605
    /* ??? Do we need to do any sign-extension here?  */
606
    memcpy (buf + 4 - len, valbuf, len);
607
 
608
  regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
609
}
610
 
611
static enum return_value_convention
612
microblaze_return_value (struct gdbarch *gdbarch, struct type *func_type,
613
                         struct type *type, struct regcache *regcache,
614
                         gdb_byte *readbuf, const gdb_byte *writebuf)
615
{
616
  if (readbuf)
617
    microblaze_extract_return_value (type, regcache, readbuf);
618
  if (writebuf)
619
    microblaze_store_return_value (type, regcache, writebuf);
620
 
621
  return RETURN_VALUE_REGISTER_CONVENTION;
622
}
623
 
624
static int
625
microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
626
{
627
  return (TYPE_LENGTH (type) == 16);
628
}
629
 
630
static void
631
microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
632
{
633
  regcache_cooked_write_unsigned (regcache, MICROBLAZE_PC_REGNUM, pc);
634
}
635
 
636
static int dwarf2_to_reg_map[78] =
637
{ 0  /* r0  */,   1  /* r1  */,   2  /* r2  */,   3  /* r3  */,  /*  0- 3 */
638
  4  /* r4  */,   5  /* r5  */,   6  /* r6  */,   7  /* r7  */,  /*  4- 7 */
639
  8  /* r8  */,   9  /* r9  */,  10  /* r10 */,  11  /* r11 */,  /*  8-11 */
640
  12 /* r12 */,  13  /* r13 */,  14  /* r14 */,  15  /* r15 */,  /* 12-15 */
641
  16 /* r16 */,  17  /* r17 */,  18  /* r18 */,  19  /* r19 */,  /* 16-19 */
642
  20 /* r20 */,  21  /* r21 */,  22  /* r22 */,  23  /* r23 */,  /* 20-23 */
643
  24 /* r24 */,  25  /* r25 */,  26  /* r26 */,  27  /* r27 */,  /* 24-25 */
644
  28 /* r28 */,  29  /* r29 */,  30  /* r30 */,  31  /* r31 */,  /* 28-31 */
645
  -1 /* $f0 */,  -1  /* $f1 */,  -1  /* $f2 */,  -1  /* $f3 */,  /* 32-35 */
646
  -1 /* $f4 */,  -1  /* $f5 */,  -1  /* $f6 */,  -1  /* $f7 */,  /* 36-39 */
647
  -1 /* $f8 */,  -1  /* $f9 */,  -1  /* $f10 */, -1  /* $f11 */, /* 40-43 */
648
  -1 /* $f12 */, -1  /* $f13 */, -1  /* $f14 */, -1  /* $f15 */, /* 44-47 */
649
  -1 /* $f16 */, -1  /* $f17 */, -1  /* $f18 */, -1  /* $f19 */, /* 48-51 */
650
  -1 /* $f20 */, -1  /* $f21 */, -1  /* $f22 */, -1  /* $f23 */, /* 52-55 */
651
  -1 /* $f24 */, -1  /* $f25 */, -1  /* $f26 */, -1  /* $f27 */, /* 56-59 */
652
  -1 /* $f28 */, -1  /* $f29 */, -1  /* $f30 */, -1  /* $f31 */, /* 60-63 */
653
  -1 /* hi   */, -1  /* lo   */, -1  /* accum*/, 33  /* rmsr */, /* 64-67 */
654
  -1 /* $fcc1*/, -1  /* $fcc2*/, -1  /* $fcc3*/, -1  /* $fcc4*/, /* 68-71 */
655
  -1 /* $fcc5*/, -1  /* $fcc6*/, -1  /* $fcc7*/, -1  /* $ap  */, /* 72-75 */
656
  -1 /* $rap */, -1  /* $frp */                                  /* 76-77 */
657
};
658
 
659
static int
660
microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
661
{
662
  gdb_assert (reg < sizeof (dwarf2_to_reg_map));
663
  return dwarf2_to_reg_map[reg];
664
}
665
 
666
static struct gdbarch *
667
microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
668
{
669
  struct gdbarch_tdep *tdep;
670
  struct gdbarch *gdbarch;
671
 
672
  /* If there is already a candidate, use it.  */
673
  arches = gdbarch_list_lookup_by_info (arches, &info);
674
  if (arches != NULL)
675
    return arches->gdbarch;
676
 
677
  /* Allocate space for the new architecture.  */
678
  tdep = XMALLOC (struct gdbarch_tdep);
679
  gdbarch = gdbarch_alloc (&info, tdep);
680
 
681
  set_gdbarch_long_double_bit (gdbarch, 128);
682
 
683
  set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
684
  set_gdbarch_register_name (gdbarch, microblaze_register_name);
685
  set_gdbarch_register_type (gdbarch, microblaze_register_type);
686
 
687
  /* Register numbers of various important registers.  */
688
  set_gdbarch_sp_regnum (gdbarch, MICROBLAZE_SP_REGNUM);
689
  set_gdbarch_pc_regnum (gdbarch, MICROBLAZE_PC_REGNUM);
690
 
691
  /* Map Dwarf2 registers to GDB registers.  */
692
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);
693
 
694
  /* Call dummy code.  */
695
  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
696
  set_gdbarch_push_dummy_code (gdbarch, microblaze_push_dummy_code);
697
  set_gdbarch_push_dummy_call (gdbarch, microblaze_push_dummy_call);
698
 
699
  set_gdbarch_return_value (gdbarch, microblaze_return_value);
700
  set_gdbarch_stabs_argument_has_addr
701
    (gdbarch, microblaze_stabs_argument_has_addr);
702
 
703
  set_gdbarch_skip_prologue (gdbarch, microblaze_skip_prologue);
704
 
705
  /* Stack grows downward.  */
706
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
707
 
708
  set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);
709
 
710
  set_gdbarch_frame_args_skip (gdbarch, 8);
711
 
712
  set_gdbarch_print_insn (gdbarch, print_insn_microblaze);
713
 
714
  set_gdbarch_write_pc (gdbarch, microblaze_write_pc);
715
 
716
  set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);
717
 
718
  frame_base_set_default (gdbarch, &microblaze_frame_base);
719
 
720
  /* Hook in ABI-specific overrides, if they have been registered.  */
721
  gdbarch_init_osabi (info, gdbarch);
722
 
723
  /* Unwind the frame. */
724
  dwarf2_append_unwinders (gdbarch);
725
  frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
726
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
727
 
728
  return gdbarch;
729
}
730
 
731
/* Provide a prototype to silence -Wmissing-prototypes.  */
732
void _initialize_microblaze_tdep (void);
733
 
734
void
735
_initialize_microblaze_tdep (void)
736
{
737
  register_gdbarch_init (bfd_arch_microblaze, microblaze_gdbarch_init);
738
 
739
  /* Debug this files internals.  */
740
  add_setshow_zinteger_cmd ("microblaze", class_maintenance,
741
                            &microblaze_debug_flag, _("\
742
Set microblaze debugging."), _("\
743
Show microblaze debugging."), _("\
744
When non-zero, microblaze specific debugging is enabled."),
745
                            NULL,
746
                            NULL,
747
                            &setdebuglist, &showdebuglist);
748
 
749
}

powered by: WebSVN 2.1.0

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