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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [v850-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
2
   Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
#include "frame.h"
23
#include "inferior.h"
24
#include "obstack.h"
25
#include "target.h"
26
#include "value.h"
27
#include "bfd.h"
28
#include "gdb_string.h"
29
#include "gdbcore.h"
30
#include "symfile.h"
31
#include "arch-utils.h"
32
#include "regcache.h"
33
 
34
 
35
static char *v850_generic_reg_names[] = REGISTER_NAMES;
36
 
37
static char *v850e_reg_names[] =
38
{
39
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
40
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
41
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
42
  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
43
  "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
44
  "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
45
  "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
46
  "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
47
  "pc", "fp"
48
};
49
 
50
char **v850_register_names = v850_generic_reg_names;
51
 
52
struct
53
  {
54
    char **regnames;
55
    int mach;
56
  }
57
v850_processor_type_table[] =
58
{
59
  {
60
    v850_generic_reg_names, bfd_mach_v850
61
  }
62
  ,
63
  {
64
    v850e_reg_names, bfd_mach_v850e
65
  }
66
  ,
67
  {
68
    v850e_reg_names, bfd_mach_v850ea
69
  }
70
  ,
71
  {
72
    NULL, 0
73
  }
74
};
75
 
76
/* Info gleaned from scanning a function's prologue.  */
77
 
78
struct pifsr                    /* Info about one saved reg */
79
  {
80
    int framereg;               /* Frame reg (SP or FP) */
81
    int offset;                 /* Offset from framereg */
82
    int cur_frameoffset;        /* Current frameoffset */
83
    int reg;                    /* Saved register number */
84
  };
85
 
86
struct prologue_info
87
  {
88
    int framereg;
89
    int frameoffset;
90
    int start_function;
91
    struct pifsr *pifsrs;
92
  };
93
 
94
static CORE_ADDR v850_scan_prologue (CORE_ADDR pc, struct prologue_info *fs);
95
 
96
 
97
/* Should call_function allocate stack space for a struct return?  */
98
int
99
v850_use_struct_convention (int gcc_p, struct type *type)
100
{
101
  return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 4);
102
}
103
 
104
 
105
 
106
/* Structure for mapping bits in register lists to register numbers. */
107
struct reg_list
108
{
109
  long mask;
110
  int regno;
111
};
112
 
113
/* Helper function for v850_scan_prologue to handle prepare instruction. */
114
 
115
static void
116
handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr,
117
                struct prologue_info *pi, struct pifsr **pifsr_ptr)
118
{
119
  CORE_ADDR current_pc = *current_pc_ptr;
120
  struct pifsr *pifsr = *pifsr_ptr;
121
  long next = insn2 & 0xffff;
122
  long list12 = ((insn & 1) << 16) + (next & 0xffe0);
123
  long offset = (insn & 0x3e) << 1;
124
  static struct reg_list reg_table[] =
125
  {
126
    {0x00800, 20},              /* r20 */
127
    {0x00400, 21},              /* r21 */
128
    {0x00200, 22},              /* r22 */
129
    {0x00100, 23},              /* r23 */
130
    {0x08000, 24},              /* r24 */
131
    {0x04000, 25},              /* r25 */
132
    {0x02000, 26},              /* r26 */
133
    {0x01000, 27},              /* r27 */
134
    {0x00080, 28},              /* r28 */
135
    {0x00040, 29},              /* r29 */
136
    {0x10000, 30},              /* ep */
137
    {0x00020, 31},              /* lp */
138
    {0, 0}                        /* end of table */
139
  };
140
  int i;
141
 
142
  if ((next & 0x1f) == 0x0b)    /* skip imm16 argument */
143
    current_pc += 2;
144
  else if ((next & 0x1f) == 0x13)       /* skip imm16 argument */
145
    current_pc += 2;
146
  else if ((next & 0x1f) == 0x1b)       /* skip imm32 argument */
147
    current_pc += 4;
148
 
149
  /* Calculate the total size of the saved registers, and add it
150
     it to the immediate value used to adjust SP. */
151
  for (i = 0; reg_table[i].mask != 0; i++)
152
    if (list12 & reg_table[i].mask)
153
      offset += REGISTER_RAW_SIZE (regtable[i].regno);
154
  pi->frameoffset -= offset;
155
 
156
  /* Calculate the offsets of the registers relative to the value
157
     the SP will have after the registers have been pushed and the
158
     imm5 value has been subtracted from it. */
159
  if (pifsr)
160
    {
161
      for (i = 0; reg_table[i].mask != 0; i++)
162
        {
163
          if (list12 & reg_table[i].mask)
164
            {
165
              int reg = reg_table[i].regno;
166
              offset -= REGISTER_RAW_SIZE (reg);
167
              pifsr->reg = reg;
168
              pifsr->offset = offset;
169
              pifsr->cur_frameoffset = pi->frameoffset;
170
#ifdef DEBUG
171
              printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
172
#endif
173
              pifsr++;
174
            }
175
        }
176
    }
177
#ifdef DEBUG
178
  printf_filtered ("\tfound ctret after regsave func");
179
#endif
180
 
181
  /* Set result parameters. */
182
  *current_pc_ptr = current_pc;
183
  *pifsr_ptr = pifsr;
184
}
185
 
186
 
187
/* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
188
   FIXME: the SR bit of the register list is not supported; must check
189
   that the compiler does not ever generate this bit. */
190
 
191
static void
192
handle_pushm (int insn, int insn2, struct prologue_info *pi,
193
              struct pifsr **pifsr_ptr)
194
{
195
  struct pifsr *pifsr = *pifsr_ptr;
196
  long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
197
  long offset = 0;
198
  static struct reg_list pushml_reg_table[] =
199
  {
200
    {0x80000, PS_REGNUM},       /* PSW */
201
    {0x40000, 1},               /* r1 */
202
    {0x20000, 2},               /* r2 */
203
    {0x10000, 3},               /* r3 */
204
    {0x00800, 4},               /* r4 */
205
    {0x00400, 5},               /* r5 */
206
    {0x00200, 6},               /* r6 */
207
    {0x00100, 7},               /* r7 */
208
    {0x08000, 8},               /* r8 */
209
    {0x04000, 9},               /* r9 */
210
    {0x02000, 10},              /* r10 */
211
    {0x01000, 11},              /* r11 */
212
    {0x00080, 12},              /* r12 */
213
    {0x00040, 13},              /* r13 */
214
    {0x00020, 14},              /* r14 */
215
    {0x00010, 15},              /* r15 */
216
    {0, 0}                        /* end of table */
217
  };
218
  static struct reg_list pushmh_reg_table[] =
219
  {
220
    {0x80000, 16},              /* r16 */
221
    {0x40000, 17},              /* r17 */
222
    {0x20000, 18},              /* r18 */
223
    {0x10000, 19},              /* r19 */
224
    {0x00800, 20},              /* r20 */
225
    {0x00400, 21},              /* r21 */
226
    {0x00200, 22},              /* r22 */
227
    {0x00100, 23},              /* r23 */
228
    {0x08000, 24},              /* r24 */
229
    {0x04000, 25},              /* r25 */
230
    {0x02000, 26},              /* r26 */
231
    {0x01000, 27},              /* r27 */
232
    {0x00080, 28},              /* r28 */
233
    {0x00040, 29},              /* r29 */
234
    {0x00010, 30},              /* r30 */
235
    {0x00020, 31},              /* r31 */
236
    {0, 0}                        /* end of table */
237
  };
238
  struct reg_list *reg_table;
239
  int i;
240
 
241
  /* Is this a pushml or a pushmh? */
242
  if ((insn2 & 7) == 1)
243
    reg_table = pushml_reg_table;
244
  else
245
    reg_table = pushmh_reg_table;
246
 
247
  /* Calculate the total size of the saved registers, and add it
248
     it to the immediate value used to adjust SP. */
249
  for (i = 0; reg_table[i].mask != 0; i++)
250
    if (list12 & reg_table[i].mask)
251
      offset += REGISTER_RAW_SIZE (regtable[i].regno);
252
  pi->frameoffset -= offset;
253
 
254
  /* Calculate the offsets of the registers relative to the value
255
     the SP will have after the registers have been pushed and the
256
     imm5 value is subtracted from it. */
257
  if (pifsr)
258
    {
259
      for (i = 0; reg_table[i].mask != 0; i++)
260
        {
261
          if (list12 & reg_table[i].mask)
262
            {
263
              int reg = reg_table[i].regno;
264
              offset -= REGISTER_RAW_SIZE (reg);
265
              pifsr->reg = reg;
266
              pifsr->offset = offset;
267
              pifsr->cur_frameoffset = pi->frameoffset;
268
#ifdef DEBUG
269
              printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
270
#endif
271
              pifsr++;
272
            }
273
        }
274
    }
275
#ifdef DEBUG
276
  printf_filtered ("\tfound ctret after regsave func");
277
#endif
278
 
279
  /* Set result parameters. */
280
  *pifsr_ptr = pifsr;
281
}
282
 
283
 
284
 
285
 
286
/* Function: scan_prologue
287
   Scan the prologue of the function that contains PC, and record what
288
   we find in PI.  PI->fsr must be zeroed by the called.  Returns the
289
   pc after the prologue.  Note that the addresses saved in pi->fsr
290
   are actually just frame relative (negative offsets from the frame
291
   pointer).  This is because we don't know the actual value of the
292
   frame pointer yet.  In some circumstances, the frame pointer can't
293
   be determined till after we have scanned the prologue.  */
294
 
295
static CORE_ADDR
296
v850_scan_prologue (CORE_ADDR pc, struct prologue_info *pi)
297
{
298
  CORE_ADDR func_addr, prologue_end, current_pc;
299
  struct pifsr *pifsr, *pifsr_tmp;
300
  int fp_used;
301
  int ep_used;
302
  int reg;
303
  CORE_ADDR save_pc, save_end;
304
  int regsave_func_p;
305
  int r12_tmp;
306
 
307
  /* First, figure out the bounds of the prologue so that we can limit the
308
     search to something reasonable.  */
309
 
310
  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
311
    {
312
      struct symtab_and_line sal;
313
 
314
      sal = find_pc_line (func_addr, 0);
315
 
316
      if (func_addr == entry_point_address ())
317
        pi->start_function = 1;
318
      else
319
        pi->start_function = 0;
320
 
321
#if 0
322
      if (sal.line == 0)
323
        prologue_end = pc;
324
      else
325
        prologue_end = sal.end;
326
#else
327
      prologue_end = pc;
328
#endif
329
    }
330
  else
331
    {                           /* We're in the boondocks */
332
      func_addr = pc - 100;
333
      prologue_end = pc;
334
    }
335
 
336
  prologue_end = min (prologue_end, pc);
337
 
338
  /* Now, search the prologue looking for instructions that setup fp, save
339
     rp, adjust sp and such.  We also record the frame offset of any saved
340
     registers. */
341
 
342
  pi->frameoffset = 0;
343
  pi->framereg = SP_REGNUM;
344
  fp_used = 0;
345
  ep_used = 0;
346
  pifsr = pi->pifsrs;
347
  regsave_func_p = 0;
348
  save_pc = 0;
349
  save_end = 0;
350
  r12_tmp = 0;
351
 
352
#ifdef DEBUG
353
  printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n",
354
                   (long) func_addr, (long) prologue_end);
355
#endif
356
 
357
  for (current_pc = func_addr; current_pc < prologue_end;)
358
    {
359
      int insn;
360
      int insn2 = -1; /* dummy value */
361
 
362
#ifdef DEBUG
363
      printf_filtered ("0x%.8lx ", (long) current_pc);
364
      (*tm_print_insn) (current_pc, &tm_print_insn_info);
365
#endif
366
 
367
      insn = read_memory_unsigned_integer (current_pc, 2);
368
      current_pc += 2;
369
      if ((insn & 0x0780) >= 0x0600)    /* Four byte instruction? */
370
        {
371
          insn2 = read_memory_unsigned_integer (current_pc, 2);
372
          current_pc += 2;
373
        }
374
 
375
      if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
376
        {                       /* jarl <func>,10 */
377
          long low_disp = insn2 & ~(long) 1;
378
          long disp = (((((insn & 0x3f) << 16) + low_disp)
379
                        & ~(long) 1) ^ 0x00200000) - 0x00200000;
380
 
381
          save_pc = current_pc;
382
          save_end = prologue_end;
383
          regsave_func_p = 1;
384
          current_pc += disp - 4;
385
          prologue_end = (current_pc
386
                          + (2 * 3)     /* moves to/from ep */
387
                          + 4   /* addi <const>,sp,sp */
388
                          + 2   /* jmp [r10] */
389
                          + (2 * 12)    /* sst.w to save r2, r20-r29, r31 */
390
                          + 20);        /* slop area */
391
 
392
#ifdef DEBUG
393
          printf_filtered ("\tfound jarl <func>,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n",
394
                           disp, low_disp, (long) current_pc + 2);
395
#endif
396
          continue;
397
        }
398
      else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p)
399
        {                       /* callt <imm6> */
400
          long ctbp = read_register (CTBP_REGNUM);
401
          long adr = ctbp + ((insn & 0x3f) << 1);
402
 
403
          save_pc = current_pc;
404
          save_end = prologue_end;
405
          regsave_func_p = 1;
406
          current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff);
407
          prologue_end = (current_pc
408
                          + (2 * 3)     /* prepare list2,imm5,sp/imm */
409
                          + 4   /* ctret */
410
                          + 20);        /* slop area */
411
 
412
#ifdef DEBUG
413
          printf_filtered ("\tfound callt,  ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n",
414
                           ctbp, adr, (long) current_pc);
415
#endif
416
          continue;
417
        }
418
      else if ((insn & 0xffc0) == 0x0780)       /* prepare list2,imm5 */
419
        {
420
          handle_prepare (insn, insn2, &current_pc, pi, &pifsr);
421
          continue;
422
        }
423
      else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144)
424
        {                       /* ctret after processing register save function */
425
          current_pc = save_pc;
426
          prologue_end = save_end;
427
          regsave_func_p = 0;
428
#ifdef DEBUG
429
          printf_filtered ("\tfound ctret after regsave func");
430
#endif
431
          continue;
432
        }
433
      else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1)
434
        {                       /* pushml, pushmh */
435
          handle_pushm (insn, insn2, pi, &pifsr);
436
          continue;
437
        }
438
      else if ((insn & 0xffe0) == 0x0060 && regsave_func_p)
439
        {                       /* jmp after processing register save function */
440
          current_pc = save_pc;
441
          prologue_end = save_end;
442
          regsave_func_p = 0;
443
#ifdef DEBUG
444
          printf_filtered ("\tfound jmp after regsave func");
445
#endif
446
          continue;
447
        }
448
      else if ((insn & 0x07c0) == 0x0780        /* jarl or jr */
449
               || (insn & 0xffe0) == 0x0060     /* jmp */
450
               || (insn & 0x0780) == 0x0580)    /* branch */
451
        {
452
#ifdef DEBUG
453
          printf_filtered ("\n");
454
#endif
455
          break;                /* Ran into end of prologue */
456
        }
457
 
458
      else if ((insn & 0xffe0) == ((SP_REGNUM << 11) | 0x0240))         /* add <imm>,sp */
459
        pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10;
460
      else if (insn == ((SP_REGNUM << 11) | 0x0600 | SP_REGNUM))        /* addi <imm>,sp,sp */
461
        pi->frameoffset += insn2;
462
      else if (insn == ((FP_RAW_REGNUM << 11) | 0x0000 | SP_REGNUM))    /* mov sp,fp */
463
        {
464
          fp_used = 1;
465
          pi->framereg = FP_RAW_REGNUM;
466
        }
467
 
468
      else if (insn == ((R12_REGNUM << 11) | 0x0640 | R0_REGNUM))       /* movhi hi(const),r0,r12 */
469
        r12_tmp = insn2 << 16;
470
      else if (insn == ((R12_REGNUM << 11) | 0x0620 | R12_REGNUM))      /* movea lo(const),r12,r12 */
471
        r12_tmp += insn2;
472
      else if (insn == ((SP_REGNUM << 11) | 0x01c0 | R12_REGNUM) && r12_tmp)    /* add r12,sp */
473
        pi->frameoffset = r12_tmp;
474
      else if (insn == ((EP_REGNUM << 11) | 0x0000 | SP_REGNUM))        /* mov sp,ep */
475
        ep_used = 1;
476
      else if (insn == ((EP_REGNUM << 11) | 0x0000 | R1_REGNUM))        /* mov r1,ep */
477
        ep_used = 0;
478
      else if (((insn & 0x07ff) == (0x0760 | SP_REGNUM)         /* st.w <reg>,<offset>[sp] */
479
                || (fp_used
480
                    && (insn & 0x07ff) == (0x0760 | FP_RAW_REGNUM)))    /* st.w <reg>,<offset>[fp] */
481
               && pifsr
482
               && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM)
483
                   || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM)
484
                 || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM)))
485
        {
486
          pifsr->reg = reg;
487
          pifsr->offset = insn2 & ~1;
488
          pifsr->cur_frameoffset = pi->frameoffset;
489
#ifdef DEBUG
490
          printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
491
#endif
492
          pifsr++;
493
        }
494
 
495
      else if (ep_used          /* sst.w <reg>,<offset>[ep] */
496
               && ((insn & 0x0781) == 0x0501)
497
               && pifsr
498
               && (((reg = (insn >> 11) & 0x1f) >= SAVE1_START_REGNUM && reg <= SAVE1_END_REGNUM)
499
                   || (reg >= SAVE2_START_REGNUM && reg <= SAVE2_END_REGNUM)
500
                 || (reg >= SAVE3_START_REGNUM && reg <= SAVE3_END_REGNUM)))
501
        {
502
          pifsr->reg = reg;
503
          pifsr->offset = (insn & 0x007e) << 1;
504
          pifsr->cur_frameoffset = pi->frameoffset;
505
#ifdef DEBUG
506
          printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
507
#endif
508
          pifsr++;
509
        }
510
 
511
#ifdef DEBUG
512
      printf_filtered ("\n");
513
#endif
514
    }
515
 
516
  if (pifsr)
517
    pifsr->framereg = 0; /* Tie off last entry */
518
 
519
  /* Fix up any offsets to the final offset.  If a frame pointer was created, use it
520
     instead of the stack pointer.  */
521
  for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++)
522
    {
523
      pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset;
524
      pifsr_tmp->framereg = pi->framereg;
525
 
526
#ifdef DEBUG
527
      printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n",
528
                    pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg);
529
#endif
530
    }
531
 
532
#ifdef DEBUG
533
  printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset);
534
#endif
535
 
536
  return current_pc;
537
}
538
 
539
/* Function: init_extra_frame_info
540
   Setup the frame's frame pointer, pc, and frame addresses for saved
541
   registers.  Most of the work is done in scan_prologue().
542
 
543
   Note that when we are called for the last frame (currently active frame),
544
   that fi->pc and fi->frame will already be setup.  However, fi->frame will
545
   be valid only if this routine uses FP.  For previous frames, fi-frame will
546
   always be correct (since that is derived from v850_frame_chain ()).
547
 
548
   We can be called with the PC in the call dummy under two circumstances.
549
   First, during normal backtracing, second, while figuring out the frame
550
   pointer just prior to calling the target function (see run_stack_dummy).  */
551
 
552
void
553
v850_init_extra_frame_info (struct frame_info *fi)
554
{
555
  struct prologue_info pi;
556
  struct pifsr pifsrs[NUM_REGS + 1], *pifsr;
557
 
558
  if (fi->next)
559
    fi->pc = FRAME_SAVED_PC (fi->next);
560
 
561
  memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
562
 
563
  /* The call dummy doesn't save any registers on the stack, so we can return
564
     now.  */
565
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
566
    return;
567
 
568
  pi.pifsrs = pifsrs;
569
 
570
  v850_scan_prologue (fi->pc, &pi);
571
 
572
  if (!fi->next && pi.framereg == SP_REGNUM)
573
    fi->frame = read_register (pi.framereg) - pi.frameoffset;
574
 
575
  for (pifsr = pifsrs; pifsr->framereg; pifsr++)
576
    {
577
      fi->fsr.regs[pifsr->reg] = pifsr->offset + fi->frame;
578
 
579
      if (pifsr->framereg == SP_REGNUM)
580
        fi->fsr.regs[pifsr->reg] += pi.frameoffset;
581
    }
582
}
583
 
584
/* Function: frame_chain
585
   Figure out the frame prior to FI.  Unfortunately, this involves
586
   scanning the prologue of the caller, which will also be done
587
   shortly by v850_init_extra_frame_info.  For the dummy frame, we
588
   just return the stack pointer that was in use at the time the
589
   function call was made.  */
590
 
591
CORE_ADDR
592
v850_frame_chain (struct frame_info *fi)
593
{
594
  struct prologue_info pi;
595
  CORE_ADDR callers_pc, fp;
596
 
597
  /* First, find out who called us */
598
  callers_pc = FRAME_SAVED_PC (fi);
599
  /* If caller is a call-dummy, then our FP bears no relation to his FP! */
600
  fp = v850_find_callers_reg (fi, FP_RAW_REGNUM);
601
  if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
602
    return fp;                  /* caller is call-dummy: return oldest value of FP */
603
 
604
  /* Caller is NOT a call-dummy, so everything else should just work.
605
     Even if THIS frame is a call-dummy! */
606
  pi.pifsrs = NULL;
607
 
608
  v850_scan_prologue (callers_pc, &pi);
609
 
610
  if (pi.start_function)
611
    return 0;                    /* Don't chain beyond the start function */
612
 
613
  if (pi.framereg == FP_RAW_REGNUM)
614
    return v850_find_callers_reg (fi, pi.framereg);
615
 
616
  return fi->frame - pi.frameoffset;
617
}
618
 
619
/* Function: find_callers_reg
620
   Find REGNUM on the stack.  Otherwise, it's in an active register.
621
   One thing we might want to do here is to check REGNUM against the
622
   clobber mask, and somehow flag it as invalid if it isn't saved on
623
   the stack somewhere.  This would provide a graceful failure mode
624
   when trying to get the value of caller-saves registers for an inner
625
   frame.  */
626
 
627
CORE_ADDR
628
v850_find_callers_reg (struct frame_info *fi, int regnum)
629
{
630
  for (; fi; fi = fi->next)
631
    if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
632
      return generic_read_register_dummy (fi->pc, fi->frame, regnum);
633
    else if (fi->fsr.regs[regnum] != 0)
634
      return read_memory_unsigned_integer (fi->fsr.regs[regnum],
635
                                           REGISTER_RAW_SIZE (regnum));
636
 
637
  return read_register (regnum);
638
}
639
 
640
/* Function: skip_prologue
641
   Return the address of the first code past the prologue of the function.  */
642
 
643
CORE_ADDR
644
v850_skip_prologue (CORE_ADDR pc)
645
{
646
  CORE_ADDR func_addr, func_end;
647
 
648
  /* See what the symbol table says */
649
 
650
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
651
    {
652
      struct symtab_and_line sal;
653
 
654
      sal = find_pc_line (func_addr, 0);
655
 
656
      if (sal.line != 0 && sal.end < func_end)
657
        return sal.end;
658
      else
659
        /* Either there's no line info, or the line after the prologue is after
660
           the end of the function.  In this case, there probably isn't a
661
           prologue.  */
662
        return pc;
663
    }
664
 
665
/* We can't find the start of this function, so there's nothing we can do. */
666
  return pc;
667
}
668
 
669
/* Function: pop_frame
670
   This routine gets called when either the user uses the `return'
671
   command, or the call dummy breakpoint gets hit.  */
672
 
673
void
674
v850_pop_frame (struct frame_info *frame)
675
{
676
  int regnum;
677
 
678
  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
679
    generic_pop_dummy_frame ();
680
  else
681
    {
682
      write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
683
 
684
      for (regnum = 0; regnum < NUM_REGS; regnum++)
685
        if (frame->fsr.regs[regnum] != 0)
686
          write_register (regnum,
687
                      read_memory_unsigned_integer (frame->fsr.regs[regnum],
688
                                               REGISTER_RAW_SIZE (regnum)));
689
 
690
      write_register (SP_REGNUM, FRAME_FP (frame));
691
    }
692
 
693
  flush_cached_frames ();
694
}
695
 
696
/* Function: push_arguments
697
   Setup arguments and RP for a call to the target.  First four args
698
   go in R6->R9, subsequent args go into sp + 16 -> sp + ...  Structs
699
   are passed by reference.  64 bit quantities (doubles and long
700
   longs) may be split between the regs and the stack.  When calling a
701
   function that returns a struct, a pointer to the struct is passed
702
   in as a secret first argument (always in R6).
703
 
704
   Stack space for the args has NOT been allocated: that job is up to us.
705
 */
706
 
707
CORE_ADDR
708
v850_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
709
                     unsigned char struct_return, CORE_ADDR struct_addr)
710
{
711
  int argreg;
712
  int argnum;
713
  int len = 0;
714
  int stack_offset;
715
 
716
  /* First, just for safety, make sure stack is aligned */
717
  sp &= ~3;
718
 
719
  /* Now make space on the stack for the args. */
720
  for (argnum = 0; argnum < nargs; argnum++)
721
    len += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
722
  sp -= len;                    /* possibly over-allocating, but it works... */
723
  /* (you might think we could allocate 16 bytes */
724
  /* less, but the ABI seems to use it all! )  */
725
  argreg = ARG0_REGNUM;
726
 
727
  /* the struct_return pointer occupies the first parameter-passing reg */
728
  if (struct_return)
729
    write_register (argreg++, struct_addr);
730
 
731
  stack_offset = 16;
732
  /* The offset onto the stack at which we will start copying parameters
733
     (after the registers are used up) begins at 16 rather than at zero.
734
     I don't really know why, that's just the way it seems to work.  */
735
 
736
  /* Now load as many as possible of the first arguments into
737
     registers, and push the rest onto the stack.  There are 16 bytes
738
     in four registers available.  Loop thru args from first to last.  */
739
  for (argnum = 0; argnum < nargs; argnum++)
740
    {
741
      int len;
742
      char *val;
743
      char valbuf[REGISTER_RAW_SIZE (ARG0_REGNUM)];
744
 
745
      if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
746
          && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
747
        {
748
          store_address (valbuf, 4, VALUE_ADDRESS (*args));
749
          len = 4;
750
          val = valbuf;
751
        }
752
      else
753
        {
754
          len = TYPE_LENGTH (VALUE_TYPE (*args));
755
          val = (char *) VALUE_CONTENTS (*args);
756
        }
757
 
758
      while (len > 0)
759
        if (argreg <= ARGLAST_REGNUM)
760
          {
761
            CORE_ADDR regval;
762
 
763
            regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
764
            write_register (argreg, regval);
765
 
766
            len -= REGISTER_RAW_SIZE (argreg);
767
            val += REGISTER_RAW_SIZE (argreg);
768
            argreg++;
769
          }
770
        else
771
          {
772
            write_memory (sp + stack_offset, val, 4);
773
 
774
            len -= 4;
775
            val += 4;
776
            stack_offset += 4;
777
          }
778
      args++;
779
    }
780
  return sp;
781
}
782
 
783
/* Function: push_return_address (pc)
784
   Set up the return address for the inferior function call.
785
   Needed for targets where we don't actually execute a JSR/BSR instruction */
786
 
787
CORE_ADDR
788
v850_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
789
{
790
  write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ());
791
  return sp;
792
}
793
 
794
/* Function: frame_saved_pc
795
   Find the caller of this frame.  We do this by seeing if RP_REGNUM
796
   is saved in the stack anywhere, otherwise we get it from the
797
   registers.  If the inner frame is a dummy frame, return its PC
798
   instead of RP, because that's where "caller" of the dummy-frame
799
   will be found.  */
800
 
801
CORE_ADDR
802
v850_frame_saved_pc (struct frame_info *fi)
803
{
804
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
805
    return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
806
  else
807
    return v850_find_callers_reg (fi, RP_REGNUM);
808
}
809
 
810
 
811
/* Function: fix_call_dummy
812
   Pokes the callee function's address into the CALL_DUMMY assembly stub.
813
   Assumes that the CALL_DUMMY looks like this:
814
   jarl <offset24>, r31
815
   trap
816
 */
817
 
818
int
819
v850_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs,
820
                     value_ptr *args, struct type *type, int gcc_p)
821
{
822
  long offset24;
823
 
824
  offset24 = (long) fun - (long) entry_point_address ();
825
  offset24 &= 0x3fffff;
826
  offset24 |= 0xff800000;       /* jarl <offset24>, r31 */
827
 
828
  store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff);
829
  store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16);
830
  return 0;
831
}
832
 
833
/* Change the register names based on the current machine type. */
834
 
835
static int
836
v850_target_architecture_hook (const bfd_arch_info_type *ap)
837
{
838
  int i, j;
839
 
840
  if (ap->arch != bfd_arch_v850)
841
    return 0;
842
 
843
  for (i = 0; v850_processor_type_table[i].regnames != NULL; i++)
844
    {
845
      if (v850_processor_type_table[i].mach == ap->mach)
846
        {
847
          v850_register_names = v850_processor_type_table[i].regnames;
848
          tm_print_insn_info.mach = ap->mach;
849
          return 1;
850
        }
851
    }
852
 
853
  internal_error (__FILE__, __LINE__,
854
                  "Architecture `%s' unrecognized", ap->printable_name);
855
}
856
 
857
void
858
_initialize_v850_tdep (void)
859
{
860
  tm_print_insn = print_insn_v850;
861
  target_architecture_hook = v850_target_architecture_hook;
862
}

powered by: WebSVN 2.1.0

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