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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [m68k-tdep.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/* Target dependent code for the Motorola 68000 series.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
3
   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 2 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, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "frame.h"
24
#include "symtab.h"
25
#include "gdbcore.h"
26
#include "value.h"
27
#include "gdb_string.h"
28
#include "inferior.h"
29
#include "regcache.h"
30
 
31
 
32
#define P_LINKL_FP      0x480e
33
#define P_LINKW_FP      0x4e56
34
#define P_PEA_FP        0x4856
35
#define P_MOVL_SP_FP    0x2c4f
36
#define P_MOVL          0x207c
37
#define P_JSR           0x4eb9
38
#define P_BSR           0x61ff
39
#define P_LEAL          0x43fb
40
#define P_MOVML         0x48ef
41
#define P_FMOVM         0xf237
42
#define P_TRAP          0x4e40
43
 
44
/* The only reason this is here is the tm-altos.h reference below.  It
45
   was moved back here from tm-m68k.h.  FIXME? */
46
 
47
extern CORE_ADDR
48
altos_skip_prologue (CORE_ADDR pc)
49
{
50
  register int op = read_memory_integer (pc, 2);
51
  if (op == P_LINKW_FP)
52
    pc += 4;                    /* Skip link #word */
53
  else if (op == P_LINKL_FP)
54
    pc += 6;                    /* Skip link #long */
55
  /* Not sure why branches are here.  */
56
  /* From tm-altos.h */
57
  else if (op == 0060000)
58
    pc += 4;                    /* Skip bra #word */
59
  else if (op == 00600377)
60
    pc += 6;                    /* skip bra #long */
61
  else if ((op & 0177400) == 0060000)
62
    pc += 2;                    /* skip bra #char */
63
  return pc;
64
}
65
 
66
/* The only reason this is here is the tm-isi.h reference below.  It
67
   was moved back here from tm-m68k.h.  FIXME? */
68
 
69
/* OBSOLETE extern CORE_ADDR */
70
/* OBSOLETE isi_skip_prologue (CORE_ADDR pc) */
71
/* OBSOLETE { */
72
/* OBSOLETE   register int op = read_memory_integer (pc, 2); */
73
/* OBSOLETE   if (op == P_LINKW_FP) */
74
/* OBSOLETE     pc += 4;                         *//* Skip link #word */
75
/* OBSOLETE   else if (op == P_LINKL_FP) */
76
/* OBSOLETE     pc += 6;                         *//* Skip link #long */
77
/* OBSOLETE    *//* Not sure why branches are here.  */
78
/* OBSOLETE    *//* From tm-isi.h, tm-altos.h */
79
/* OBSOLETE   else if (op == 0060000) */
80
/* OBSOLETE     pc += 4;                         *//* Skip bra #word */
81
/* OBSOLETE   else if (op == 00600377) */
82
/* OBSOLETE     pc += 6;                         *//* skip bra #long */
83
/* OBSOLETE   else if ((op & 0177400) == 0060000) */
84
/* OBSOLETE     pc += 2;                         *//* skip bra #char */
85
/* OBSOLETE   return pc; */
86
/* OBSOLETE } */
87
 
88
int
89
delta68_in_sigtramp (CORE_ADDR pc, char *name)
90
{
91
  if (name != NULL)
92
    return strcmp (name, "_sigcode") == 0;
93
  else
94
    return 0;
95
}
96
 
97
CORE_ADDR
98
delta68_frame_args_address (struct frame_info *frame_info)
99
{
100
  /* we assume here that the only frameless functions are the system calls
101
     or other functions who do not put anything on the stack. */
102
  if (frame_info->signal_handler_caller)
103
    return frame_info->frame + 12;
104
  else if (frameless_look_for_prologue (frame_info))
105
    {
106
    /* Check for an interrupted system call */
107
    if (frame_info->next && frame_info->next->signal_handler_caller)
108
      return frame_info->next->frame + 16;
109
    else
110
      return frame_info->frame + 4;
111
    }
112
  else
113
    return frame_info->frame;
114
}
115
 
116
CORE_ADDR
117
delta68_frame_saved_pc (struct frame_info *frame_info)
118
{
119
  return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
120
}
121
 
122
/* Return number of args passed to a frame.
123
   Can return -1, meaning no way to tell.  */
124
 
125
int
126
isi_frame_num_args (struct frame_info *fi)
127
{
128
  int val;
129
  CORE_ADDR pc = FRAME_SAVED_PC (fi);
130
  int insn = 0177777 & read_memory_integer (pc, 2);
131
  val = 0;
132
  if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
133
    val = read_memory_integer (pc + 2, 2);
134
  else if ((insn & 0170777) == 0050217  /* addql #N, sp */
135
           || (insn & 0170777) == 0050117)      /* addqw */
136
    {
137
      val = (insn >> 9) & 7;
138
      if (val == 0)
139
        val = 8;
140
    }
141
  else if (insn == 0157774)     /* addal #WW, sp */
142
    val = read_memory_integer (pc + 2, 4);
143
  val >>= 2;
144
  return val;
145
}
146
 
147
int
148
delta68_frame_num_args (struct frame_info *fi)
149
{
150
  int val;
151
  CORE_ADDR pc = FRAME_SAVED_PC (fi);
152
  int insn = 0177777 & read_memory_integer (pc, 2);
153
  val = 0;
154
  if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
155
    val = read_memory_integer (pc + 2, 2);
156
  else if ((insn & 0170777) == 0050217  /* addql #N, sp */
157
           || (insn & 0170777) == 0050117)      /* addqw */
158
    {
159
      val = (insn >> 9) & 7;
160
      if (val == 0)
161
        val = 8;
162
    }
163
  else if (insn == 0157774)     /* addal #WW, sp */
164
    val = read_memory_integer (pc + 2, 4);
165
  val >>= 2;
166
  return val;
167
}
168
 
169
int
170
news_frame_num_args (struct frame_info *fi)
171
{
172
  int val;
173
  CORE_ADDR pc = FRAME_SAVED_PC (fi);
174
  int insn = 0177777 & read_memory_integer (pc, 2);
175
  val = 0;
176
  if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
177
    val = read_memory_integer (pc + 2, 2);
178
  else if ((insn & 0170777) == 0050217  /* addql #N, sp */
179
           || (insn & 0170777) == 0050117)      /* addqw */
180
    {
181
      val = (insn >> 9) & 7;
182
      if (val == 0)
183
        val = 8;
184
    }
185
  else if (insn == 0157774)     /* addal #WW, sp */
186
    val = read_memory_integer (pc + 2, 4);
187
  val >>= 2;
188
  return val;
189
}
190
 
191
/* Push an empty stack frame, to record the current PC, etc.  */
192
 
193
void
194
m68k_push_dummy_frame (void)
195
{
196
  register CORE_ADDR sp = read_register (SP_REGNUM);
197
  register int regnum;
198
  char raw_buffer[12];
199
 
200
  sp = push_word (sp, read_register (PC_REGNUM));
201
  sp = push_word (sp, read_register (FP_REGNUM));
202
  write_register (FP_REGNUM, sp);
203
 
204
  /* Always save the floating-point registers, whether they exist on
205
     this target or not.  */
206
  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
207
    {
208
      read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
209
      sp = push_bytes (sp, raw_buffer, 12);
210
    }
211
 
212
  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
213
    {
214
      sp = push_word (sp, read_register (regnum));
215
    }
216
  sp = push_word (sp, read_register (PS_REGNUM));
217
  write_register (SP_REGNUM, sp);
218
}
219
 
220
/* Discard from the stack the innermost frame,
221
   restoring all saved registers.  */
222
 
223
void
224
m68k_pop_frame (void)
225
{
226
  register struct frame_info *frame = get_current_frame ();
227
  register CORE_ADDR fp;
228
  register int regnum;
229
  struct frame_saved_regs fsr;
230
  char raw_buffer[12];
231
 
232
  fp = FRAME_FP (frame);
233
  get_frame_saved_regs (frame, &fsr);
234
  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
235
    {
236
      if (fsr.regs[regnum])
237
        {
238
          read_memory (fsr.regs[regnum], raw_buffer, 12);
239
          write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
240
        }
241
    }
242
  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
243
    {
244
      if (fsr.regs[regnum])
245
        {
246
          write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
247
        }
248
    }
249
  if (fsr.regs[PS_REGNUM])
250
    {
251
      write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
252
    }
253
  write_register (FP_REGNUM, read_memory_integer (fp, 4));
254
  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
255
  write_register (SP_REGNUM, fp + 8);
256
  flush_cached_frames ();
257
}
258
 
259
 
260
/* Given an ip value corresponding to the start of a function,
261
   return the ip of the first instruction after the function
262
   prologue.  This is the generic m68k support.  Machines which
263
   require something different can override the SKIP_PROLOGUE
264
   macro to point elsewhere.
265
 
266
   Some instructions which typically may appear in a function
267
   prologue include:
268
 
269
   A link instruction, word form:
270
 
271
   link.w       %a6,&0                  4e56  XXXX
272
 
273
   A link instruction, long form:
274
 
275
   link.l  %fp,&F%1             480e  XXXX  XXXX
276
 
277
   A movm instruction to preserve integer regs:
278
 
279
   movm.l  &M%1,(4,%sp)         48ef  XXXX  XXXX
280
 
281
   A fmovm instruction to preserve float regs:
282
 
283
   fmovm   &FPM%1,(FPO%1,%sp)   f237  XXXX  XXXX  XXXX  XXXX
284
 
285
   Some profiling setup code (FIXME, not recognized yet):
286
 
287
   lea.l   (.L3,%pc),%a1                43fb  XXXX  XXXX  XXXX
288
   bsr     _mcount                      61ff  XXXX  XXXX
289
 
290
 */
291
 
292
CORE_ADDR
293
m68k_skip_prologue (CORE_ADDR ip)
294
{
295
  register CORE_ADDR limit;
296
  struct symtab_and_line sal;
297
  register int op;
298
 
299
  /* Find out if there is a known limit for the extent of the prologue.
300
     If so, ensure we don't go past it.  If not, assume "infinity". */
301
 
302
  sal = find_pc_line (ip, 0);
303
  limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
304
 
305
  while (ip < limit)
306
    {
307
      op = read_memory_integer (ip, 2);
308
      op &= 0xFFFF;
309
 
310
      if (op == P_LINKW_FP)
311
        ip += 4;                /* Skip link.w */
312
      else if (op == P_PEA_FP)
313
        ip += 2;                /* Skip pea %fp */
314
      else if (op == P_MOVL_SP_FP)
315
        ip += 2;                /* Skip move.l %sp, %fp */
316
      else if (op == P_LINKL_FP)
317
        ip += 6;                /* Skip link.l */
318
      else if (op == P_MOVML)
319
        ip += 6;                /* Skip movm.l */
320
      else if (op == P_FMOVM)
321
        ip += 10;               /* Skip fmovm */
322
      else
323
        break;          /* Found unknown code, bail out. */
324
    }
325
  return (ip);
326
}
327
 
328
void
329
m68k_find_saved_regs (struct frame_info *frame_info,
330
                      struct frame_saved_regs *saved_regs)
331
{
332
  register int regnum;
333
  register int regmask;
334
  register CORE_ADDR next_addr;
335
  register CORE_ADDR pc;
336
 
337
  /* First possible address for a pc in a call dummy for this frame.  */
338
  CORE_ADDR possible_call_dummy_start =
339
  (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
340
 
341
  int nextinsn;
342
  memset (saved_regs, 0, sizeof (*saved_regs));
343
  if ((frame_info)->pc >= possible_call_dummy_start
344
      && (frame_info)->pc <= (frame_info)->frame)
345
    {
346
 
347
      /* It is a call dummy.  We could just stop now, since we know
348
         what the call dummy saves and where.  But this code proceeds
349
         to parse the "prologue" which is part of the call dummy.
350
         This is needlessly complex and confusing.  FIXME.  */
351
 
352
      next_addr = (frame_info)->frame;
353
      pc = possible_call_dummy_start;
354
    }
355
  else
356
    {
357
      pc = get_pc_function_start ((frame_info)->pc);
358
 
359
      nextinsn = read_memory_integer (pc, 2);
360
      if (P_PEA_FP == nextinsn
361
          && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
362
        {
363
          /* pea %fp
364
             move.l %sp, %fp */
365
          next_addr = frame_info->frame;
366
          pc += 4;
367
        }
368
      else if (P_LINKL_FP == nextinsn)
369
        /* link.l %fp */
370
        /* Find the address above the saved
371
           regs using the amount of storage from the link instruction.  */
372
        {
373
          next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
374
          pc += 6;
375
        }
376
      else if (P_LINKW_FP == nextinsn)
377
        /* link.w %fp */
378
        /* Find the address above the saved
379
           regs using the amount of storage from the link instruction.  */
380
        {
381
          next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
382
          pc += 4;
383
        }
384
      else
385
        goto lose;
386
 
387
      /* If have an addal #-n, sp next, adjust next_addr.  */
388
      if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
389
        next_addr += read_memory_integer (pc += 2, 4), pc += 4;
390
    }
391
 
392
  for ( ; ; )
393
    {
394
      nextinsn = 0xffff & read_memory_integer (pc, 2);
395
      regmask = read_memory_integer (pc + 2, 2);
396
      /* fmovemx to -(sp) */
397
      if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
398
        {
399
          /* Regmask's low bit is for register fp7, the first pushed */
400
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
401
            if (regmask & 1)
402
              saved_regs->regs[regnum] = (next_addr -= 12);
403
          pc += 4;
404
        }
405
      /* fmovemx to (fp + displacement) */
406
      else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
407
        {
408
          register CORE_ADDR addr;
409
 
410
          addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
411
          /* Regmask's low bit is for register fp7, the first pushed */
412
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
413
            if (regmask & 1)
414
              {
415
                saved_regs->regs[regnum] = addr;
416
                addr += 12;
417
              }
418
          pc += 6;
419
        }
420
      /* moveml to (sp) */
421
      else if (0044327 == nextinsn)
422
        {
423
          /* Regmask's low bit is for register 0, the first written */
424
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
425
            if (regmask & 1)
426
              {
427
                saved_regs->regs[regnum] = next_addr;
428
                next_addr += 4;
429
              }
430
          pc += 4;
431
        }
432
      /* moveml to (fp + displacement) */
433
      else if (0044356 == nextinsn)
434
        {
435
          register CORE_ADDR addr;
436
 
437
          addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
438
          /* Regmask's low bit is for register 0, the first written */
439
          for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
440
            if (regmask & 1)
441
              {
442
                saved_regs->regs[regnum] = addr;
443
                addr += 4;
444
              }
445
          pc += 6;
446
        }
447
      /* moveml to -(sp) */
448
      else if (0044347 == nextinsn)
449
        {
450
          /* Regmask's low bit is for register 15, the first pushed */
451
          for (regnum = 16; --regnum >= 0; regmask >>= 1)
452
            if (regmask & 1)
453
              saved_regs->regs[regnum] = (next_addr -= 4);
454
          pc += 4;
455
        }
456
      /* movl r,-(sp) */
457
      else if (0x2f00 == (0xfff0 & nextinsn))
458
        {
459
          regnum = 0xf & nextinsn;
460
          saved_regs->regs[regnum] = (next_addr -= 4);
461
          pc += 2;
462
        }
463
      /* fmovemx to index of sp */
464
      else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
465
        {
466
          /* Regmask's low bit is for register fp0, the first written */
467
          for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
468
            if (regmask & 1)
469
              {
470
                saved_regs->regs[regnum] = next_addr;
471
                next_addr += 12;
472
              }
473
          pc += 10;
474
        }
475
      /* clrw -(sp); movw ccr,-(sp) */
476
      else if (0x4267 == nextinsn && 0x42e7 == regmask)
477
        {
478
          saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
479
          pc += 4;
480
        }
481
      else
482
        break;
483
    }
484
lose:;
485
  saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
486
  saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
487
  saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
488
#ifdef SIG_SP_FP_OFFSET
489
  /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
490
  if (frame_info->signal_handler_caller && frame_info->next)
491
    saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
492
#endif
493
}
494
 
495
 
496
#ifdef USE_PROC_FS              /* Target dependent support for /proc */
497
 
498
#include <sys/procfs.h>
499
 
500
/* Prototypes for supply_gregset etc. */
501
#include "gregset.h"
502
 
503
/*  The /proc interface divides the target machine's register set up into
504
   two different sets, the general register set (gregset) and the floating
505
   point register set (fpregset).  For each set, there is an ioctl to get
506
   the current register set and another ioctl to set the current values.
507
 
508
   The actual structure passed through the ioctl interface is, of course,
509
   naturally machine dependent, and is different for each set of registers.
510
   For the m68k for example, the general register set is typically defined
511
   by:
512
 
513
   typedef int gregset_t[18];
514
 
515
   #define      R_D0    0
516
   ...
517
   #define      R_PS    17
518
 
519
   and the floating point set by:
520
 
521
   typedef      struct fpregset {
522
   int  f_pcr;
523
   int  f_psr;
524
   int  f_fpiaddr;
525
   int  f_fpregs[8][3];         (8 regs, 96 bits each)
526
   } fpregset_t;
527
 
528
   These routines provide the packing and unpacking of gregset_t and
529
   fpregset_t formatted data.
530
 
531
 */
532
 
533
/* Atari SVR4 has R_SR but not R_PS */
534
 
535
#if !defined (R_PS) && defined (R_SR)
536
#define R_PS R_SR
537
#endif
538
 
539
/*  Given a pointer to a general register set in /proc format (gregset_t *),
540
   unpack the register contents and supply them as gdb's idea of the current
541
   register values. */
542
 
543
void
544
supply_gregset (gregset_t *gregsetp)
545
{
546
  register int regi;
547
  register greg_t *regp = (greg_t *) gregsetp;
548
 
549
  for (regi = 0; regi < R_PC; regi++)
550
    {
551
      supply_register (regi, (char *) (regp + regi));
552
    }
553
  supply_register (PS_REGNUM, (char *) (regp + R_PS));
554
  supply_register (PC_REGNUM, (char *) (regp + R_PC));
555
}
556
 
557
void
558
fill_gregset (gregset_t *gregsetp, int regno)
559
{
560
  register int regi;
561
  register greg_t *regp = (greg_t *) gregsetp;
562
 
563
  for (regi = 0; regi < R_PC; regi++)
564
    {
565
      if ((regno == -1) || (regno == regi))
566
        {
567
          *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
568
        }
569
    }
570
  if ((regno == -1) || (regno == PS_REGNUM))
571
    {
572
      *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
573
    }
574
  if ((regno == -1) || (regno == PC_REGNUM))
575
    {
576
      *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
577
    }
578
}
579
 
580
#if defined (FP0_REGNUM)
581
 
582
/*  Given a pointer to a floating point register set in /proc format
583
   (fpregset_t *), unpack the register contents and supply them as gdb's
584
   idea of the current floating point register values. */
585
 
586
void
587
supply_fpregset (fpregset_t *fpregsetp)
588
{
589
  register int regi;
590
  char *from;
591
 
592
  for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
593
    {
594
      from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
595
      supply_register (regi, from);
596
    }
597
  supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
598
  supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
599
  supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
600
}
601
 
602
/*  Given a pointer to a floating point register set in /proc format
603
   (fpregset_t *), update the register specified by REGNO from gdb's idea
604
   of the current floating point register set.  If REGNO is -1, update
605
   them all. */
606
 
607
void
608
fill_fpregset (fpregset_t *fpregsetp, int regno)
609
{
610
  int regi;
611
  char *to;
612
  char *from;
613
 
614
  for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
615
    {
616
      if ((regno == -1) || (regno == regi))
617
        {
618
          from = (char *) &registers[REGISTER_BYTE (regi)];
619
          to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
620
          memcpy (to, from, REGISTER_RAW_SIZE (regi));
621
        }
622
    }
623
  if ((regno == -1) || (regno == FPC_REGNUM))
624
    {
625
      fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
626
    }
627
  if ((regno == -1) || (regno == FPS_REGNUM))
628
    {
629
      fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
630
    }
631
  if ((regno == -1) || (regno == FPI_REGNUM))
632
    {
633
      fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
634
    }
635
}
636
 
637
#endif /* defined (FP0_REGNUM) */
638
 
639
#endif /* USE_PROC_FS */
640
 
641
/* Figure out where the longjmp will land.  Slurp the args out of the stack.
642
   We expect the first arg to be a pointer to the jmp_buf structure from which
643
   we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
644
   This routine returns true on success. */
645
 
646
/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched
647
   the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into
648
   the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI
649
   dependant basis. */
650
 
651
int
652
m68k_get_longjmp_target (CORE_ADDR *pc)
653
{
654
#if defined (JB_PC) && defined (JB_ELEMENT_SIZE)
655
  char *buf;
656
  CORE_ADDR sp, jb_addr;
657
 
658
  buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
659
  sp = read_register (SP_REGNUM);
660
 
661
  if (target_read_memory (sp + SP_ARG0,         /* Offset of first arg on stack */
662
                          buf,
663
                          TARGET_PTR_BIT / TARGET_CHAR_BIT))
664
    return 0;
665
 
666
  jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
667
 
668
  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
669
                          TARGET_PTR_BIT / TARGET_CHAR_BIT))
670
    return 0;
671
 
672
  *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
673
 
674
  return 1;
675
#else
676
  internal_error (__FILE__, __LINE__,
677
                  "m68k_get_longjmp_target: not implemented");
678
  return 0;
679
#endif
680
}
681
 
682
/* Immediately after a function call, return the saved pc before the frame
683
   is setup.  For sun3's, we check for the common case of being inside of a
684
   system call, and if so, we know that Sun pushes the call # on the stack
685
   prior to doing the trap. */
686
 
687
CORE_ADDR
688
m68k_saved_pc_after_call (struct frame_info *frame)
689
{
690
#ifdef SYSCALL_TRAP
691
  int op;
692
 
693
  op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
694
 
695
  if (op == SYSCALL_TRAP)
696
    return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
697
  else
698
#endif /* SYSCALL_TRAP */
699
    return read_memory_integer (read_register (SP_REGNUM), 4);
700
}
701
 
702
 
703
void
704
_initialize_m68k_tdep (void)
705
{
706
  tm_print_insn = print_insn_m68k;
707
}

powered by: WebSVN 2.1.0

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