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