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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [m68k-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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