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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [v850-tdep.c] - Blame information for rev 1774

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

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

powered by: WebSVN 2.1.0

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