Change the stream argument to _filtered to GDB_FILE *.
[deliverable/binutils-gdb.git] / gdb / m68k-tdep.c
CommitLineData
bd5635a1 1/* Target dependent code for the Motorola 68000 series.
f4992534 2 Copyright (C) 1990, 1992 Free Software Foundation, Inc.
bd5635a1
RP
3
4This file is part of GDB.
5
b6666a5d 6This program is free software; you can redistribute it and/or modify
bd5635a1 7it under the terms of the GNU General Public License as published by
b6666a5d
FF
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
bd5635a1 10
b6666a5d 11This program is distributed in the hope that it will be useful,
bd5635a1
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
b6666a5d
FF
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
bd5635a1
RP
19
20#include "defs.h"
b6666a5d
FF
21#include "frame.h"
22#include "symtab.h"
bd5635a1 23
b6666a5d 24\f
b6666a5d
FF
25/* Push an empty stack frame, to record the current PC, etc. */
26
27void
28m68k_push_dummy_frame ()
29{
30 register CORE_ADDR sp = read_register (SP_REGNUM);
31 register int regnum;
32 char raw_buffer[12];
33
34 sp = push_word (sp, read_register (PC_REGNUM));
35 sp = push_word (sp, read_register (FP_REGNUM));
36 write_register (FP_REGNUM, sp);
37#if defined (HAVE_68881)
38 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
39 {
40 read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
41 sp = push_bytes (sp, raw_buffer, 12);
42 }
43#endif
44 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
45 {
46 sp = push_word (sp, read_register (regnum));
47 }
48 sp = push_word (sp, read_register (PS_REGNUM));
49 write_register (SP_REGNUM, sp);
50}
51
52/* Discard from the stack the innermost frame,
53 restoring all saved registers. */
54
55void
56m68k_pop_frame ()
57{
58 register FRAME frame = get_current_frame ();
59 register CORE_ADDR fp;
60 register int regnum;
61 struct frame_saved_regs fsr;
62 struct frame_info *fi;
63 char raw_buffer[12];
64
65 fi = get_frame_info (frame);
66 fp = fi -> frame;
67 get_frame_saved_regs (fi, &fsr);
68#if defined (HAVE_68881)
69 for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--)
70 {
71 if (fsr.regs[regnum])
72 {
73 read_memory (fsr.regs[regnum], raw_buffer, 12);
74 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
75 }
76 }
77#endif
78 for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--)
79 {
80 if (fsr.regs[regnum])
81 {
82 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
83 }
84 }
85 if (fsr.regs[PS_REGNUM])
86 {
87 write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
88 }
89 write_register (FP_REGNUM, read_memory_integer (fp, 4));
90 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
91 write_register (SP_REGNUM, fp + 8);
92 flush_cached_frames ();
93 set_current_frame (create_new_frame (read_register (FP_REGNUM),
94 read_pc ()));
95}
96
97\f
98/* Given an ip value corresponding to the start of a function,
99 return the ip of the first instruction after the function
100 prologue. This is the generic m68k support. Machines which
101 require something different can override the SKIP_PROLOGUE
102 macro to point elsewhere.
103
104 Some instructions which typically may appear in a function
105 prologue include:
106
107 A link instruction, word form:
108
109 link.w %a6,&0 4e56 XXXX
110
111 A link instruction, long form:
112
113 link.l %fp,&F%1 480e XXXX XXXX
114
115 A movm instruction to preserve integer regs:
116
117 movm.l &M%1,(4,%sp) 48ef XXXX XXXX
118
119 A fmovm instruction to preserve float regs:
120
121 fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
122
123 Some profiling setup code (FIXME, not recognized yet):
124
125 lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
126 bsr _mcount 61ff XXXX XXXX
127
128 */
129
130#define P_LINK_L 0x480e
131#define P_LINK_W 0x4e56
132#define P_MOV_L 0x207c
133#define P_JSR 0x4eb9
134#define P_BSR 0x61ff
135#define P_LEA_L 0x43fb
136#define P_MOVM_L 0x48ef
137#define P_FMOVM 0xf237
f4992534 138#define P_TRAP 0x4e40
b6666a5d
FF
139
140CORE_ADDR
141m68k_skip_prologue (ip)
142CORE_ADDR ip;
143{
144 register CORE_ADDR limit;
145 struct symtab_and_line sal;
146 register int op;
147
148 /* Find out if there is a known limit for the extent of the prologue.
149 If so, ensure we don't go past it. If not, assume "infinity". */
150
151 sal = find_pc_line (ip, 0);
152 limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
153
154 while (ip < limit)
155 {
156 op = read_memory_integer (ip, 2);
157 op &= 0xFFFF;
158
159 if (op == P_LINK_W)
160 {
161 ip += 4; /* Skip link.w */
162 }
163 else if (op == P_LINK_L)
164 {
165 ip += 6; /* Skip link.l */
166 }
167 else if (op == P_MOVM_L)
168 {
169 ip += 6; /* Skip movm.l */
170 }
171 else if (op == P_FMOVM)
172 {
173 ip += 10; /* Skip fmovm */
174 }
175 else
176 {
177 break; /* Found unknown code, bail out. */
178 }
179 }
180 return (ip);
181}
182
ade40d31
RP
183void
184m68k_find_saved_regs (frame_info, saved_regs)
185 struct frame_info *frame_info;
186 struct frame_saved_regs *saved_regs;
187{
188 register int regnum;
189 register int regmask;
190 register CORE_ADDR next_addr;
191 register CORE_ADDR pc;
192
193 /* First possible address for a pc in a call dummy for this frame. */
194 CORE_ADDR possible_call_dummy_start =
195 (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4
196#if defined (HAVE_68881)
197 - 8*12
198#endif
199 ;
200
201 int nextinsn;
202 memset (saved_regs, 0, sizeof (*saved_regs));
203 if ((frame_info)->pc >= possible_call_dummy_start
204 && (frame_info)->pc <= (frame_info)->frame)
205 {
206
207 /* It is a call dummy. We could just stop now, since we know
208 what the call dummy saves and where. But this code proceeds
209 to parse the "prologue" which is part of the call dummy.
210 This is needlessly complex, confusing, and also is the only
211 reason that the call dummy is customized based on HAVE_68881.
212 FIXME. */
213
214 next_addr = (frame_info)->frame;
215 pc = possible_call_dummy_start;
216 }
217 else
218 {
219 pc = get_pc_function_start ((frame_info)->pc);
220 /* Verify we have a link a6 instruction next;
221 if not we lose. If we win, find the address above the saved
222 regs using the amount of storage from the link instruction. */
223 if (044016 == read_memory_integer (pc, 2))
224 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4;
225 else if (047126 == read_memory_integer (pc, 2))
226 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2;
227 else goto lose;
228 /* If have an addal #-n, sp next, adjust next_addr. */
229 if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
230 next_addr += read_memory_integer (pc += 2, 4), pc += 4;
231 }
232 regmask = read_memory_integer (pc + 2, 2);
233#if defined (HAVE_68881)
234 /* Here can come an fmovem. Check for it. */
235 nextinsn = 0xffff & read_memory_integer (pc, 2);
236 if (0xf227 == nextinsn
237 && (regmask & 0xff00) == 0xe000)
238 { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */
239 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
240 if (regmask & 1)
241 saved_regs->regs[regnum] = (next_addr -= 12);
242 regmask = read_memory_integer (pc + 2, 2); }
243#endif
244 /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */
245 if (0044327 == read_memory_integer (pc, 2))
246 { pc += 4; /* Regmask's low bit is for register 0, the first written */
247 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
248 if (regmask & 1)
249 saved_regs->regs[regnum] = (next_addr += 4) - 4; }
250 else if (0044347 == read_memory_integer (pc, 2))
251 {
252 pc += 4; /* Regmask's low bit is for register 15, the first pushed */
253 for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)
254 if (regmask & 1)
255 saved_regs->regs[regnum] = (next_addr -= 4);
256 }
257 else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
258 {
259 regnum = 0xf & read_memory_integer (pc, 2); pc += 2;
260 saved_regs->regs[regnum] = (next_addr -= 4);
261 /* gcc, at least, may use a pair of movel instructions when saving
262 exactly 2 registers. */
263 if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
264 {
265 regnum = 0xf & read_memory_integer (pc, 2);
266 pc += 2;
267 saved_regs->regs[regnum] = (next_addr -= 4);
268 }
269 }
270#if defined (HAVE_68881)
271 /* fmovemx to index of sp may follow. */
272 regmask = read_memory_integer (pc + 2, 2);
273 nextinsn = 0xffff & read_memory_integer (pc, 2);
274 if (0xf236 == nextinsn
275 && (regmask & 0xff00) == 0xf000)
276 { pc += 10; /* Regmask's low bit is for register fp0, the first written */
277 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
278 if (regmask & 1)
279 saved_regs->regs[regnum] = (next_addr += 12) - 12;
280 regmask = read_memory_integer (pc + 2, 2); }
281#endif
282 /* clrw -(sp); movw ccr,-(sp) may follow. */
283 if (0x426742e7 == read_memory_integer (pc, 4))
284 saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
285 lose: ;
286 saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
287 saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
288 saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
289#ifdef SIG_SP_FP_OFFSET
290 /* Adjust saved SP_REGNUM for fake _sigtramp frames. */
291 if (frame_info->signal_handler_caller && frame_info->next)
292 saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
293#endif
294}
295
296
b6666a5d
FF
297#ifdef USE_PROC_FS /* Target dependent support for /proc */
298
299#include <sys/procfs.h>
300
301/* The /proc interface divides the target machine's register set up into
302 two different sets, the general register set (gregset) and the floating
303 point register set (fpregset). For each set, there is an ioctl to get
304 the current register set and another ioctl to set the current values.
305
306 The actual structure passed through the ioctl interface is, of course,
307 naturally machine dependent, and is different for each set of registers.
308 For the m68k for example, the general register set is typically defined
309 by:
310
311 typedef int gregset_t[18];
312
313 #define R_D0 0
314 ...
315 #define R_PS 17
316
317 and the floating point set by:
318
319 typedef struct fpregset {
320 int f_pcr;
321 int f_psr;
322 int f_fpiaddr;
323 int f_fpregs[8][3]; (8 regs, 96 bits each)
324 } fpregset_t;
325
326 These routines provide the packing and unpacking of gregset_t and
327 fpregset_t formatted data.
328
329 */
330
331
332/* Given a pointer to a general register set in /proc format (gregset_t *),
333 unpack the register contents and supply them as gdb's idea of the current
334 register values. */
335
336void
337supply_gregset (gregsetp)
338gregset_t *gregsetp;
339{
f4992534 340 register int regi;
b6666a5d
FF
341 register greg_t *regp = (greg_t *) gregsetp;
342
f4992534 343 for (regi = 0 ; regi < R_PC ; regi++)
b6666a5d 344 {
f4992534 345 supply_register (regi, (char *) (regp + regi));
b6666a5d
FF
346 }
347 supply_register (PS_REGNUM, (char *) (regp + R_PS));
348 supply_register (PC_REGNUM, (char *) (regp + R_PC));
349}
350
351void
352fill_gregset (gregsetp, regno)
353gregset_t *gregsetp;
354int regno;
355{
f4992534 356 register int regi;
b6666a5d
FF
357 register greg_t *regp = (greg_t *) gregsetp;
358 extern char registers[];
359
360 for (regi = 0 ; regi < R_PC ; regi++)
361 {
362 if ((regno == -1) || (regno == regi))
363 {
f4992534 364 *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
b6666a5d
FF
365 }
366 }
367 if ((regno == -1) || (regno == PS_REGNUM))
368 {
369 *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
370 }
371 if ((regno == -1) || (regno == PC_REGNUM))
372 {
373 *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
374 }
375}
376
377#if defined (FP0_REGNUM)
378
379/* Given a pointer to a floating point register set in /proc format
380 (fpregset_t *), unpack the register contents and supply them as gdb's
381 idea of the current floating point register values. */
382
383void
384supply_fpregset (fpregsetp)
385fpregset_t *fpregsetp;
386{
f4992534
SG
387 register int regi;
388 char *from;
b6666a5d 389
f4992534 390 for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
b6666a5d 391 {
f4992534
SG
392 from = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
393 supply_register (regi, from);
b6666a5d
FF
394 }
395 supply_register (FPC_REGNUM, (char *) &(fpregsetp -> f_pcr));
396 supply_register (FPS_REGNUM, (char *) &(fpregsetp -> f_psr));
397 supply_register (FPI_REGNUM, (char *) &(fpregsetp -> f_fpiaddr));
398}
399
400/* Given a pointer to a floating point register set in /proc format
401 (fpregset_t *), update the register specified by REGNO from gdb's idea
402 of the current floating point register set. If REGNO is -1, update
403 them all. */
404
405void
406fill_fpregset (fpregsetp, regno)
407fpregset_t *fpregsetp;
408int regno;
409{
410 int regi;
411 char *to;
412 char *from;
413 extern char registers[];
414
415 for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
416 {
417 if ((regno == -1) || (regno == regi))
418 {
419 from = (char *) &registers[REGISTER_BYTE (regi)];
f4992534 420 to = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
ade40d31 421 memcpy (to, from, REGISTER_RAW_SIZE (regi));
b6666a5d
FF
422 }
423 }
424 if ((regno == -1) || (regno == FPC_REGNUM))
425 {
426 fpregsetp -> f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
427 }
428 if ((regno == -1) || (regno == FPS_REGNUM))
429 {
430 fpregsetp -> f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
431 }
432 if ((regno == -1) || (regno == FPI_REGNUM))
433 {
434 fpregsetp -> f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
435 }
436}
437
438#endif /* defined (FP0_REGNUM) */
439
440#endif /* USE_PROC_FS */
f4992534
SG
441
442#ifdef GET_LONGJMP_TARGET
443/* Figure out where the longjmp will land. Slurp the args out of the stack.
444 We expect the first arg to be a pointer to the jmp_buf structure from which
445 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
446 This routine returns true on success. */
447
448int
449get_longjmp_target(pc)
450 CORE_ADDR *pc;
451{
ade40d31 452 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
f4992534
SG
453 CORE_ADDR sp, jb_addr;
454
455 sp = read_register(SP_REGNUM);
456
ade40d31
RP
457 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
458 buf,
459 TARGET_PTR_BIT / TARGET_CHAR_BIT))
f4992534
SG
460 return 0;
461
ade40d31 462 jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
f4992534 463
ade40d31
RP
464 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
465 TARGET_PTR_BIT / TARGET_CHAR_BIT))
f4992534
SG
466 return 0;
467
ade40d31 468 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
f4992534
SG
469
470 return 1;
471}
472#endif /* GET_LONGJMP_TARGET */
473
474/* Immediately after a function call, return the saved pc before the frame
ade40d31
RP
475 is setup. For sun3's, we check for the common case of being inside of a
476 system call, and if so, we know that Sun pushes the call # on the stack
477 prior to doing the trap. */
f4992534
SG
478
479CORE_ADDR
480m68k_saved_pc_after_call(frame)
481 struct frame_info *frame;
482{
ade40d31 483#ifdef GDB_TARGET_IS_SUN3
f4992534
SG
484 int op;
485
486 op = read_memory_integer (frame->pc, 2);
487 op &= 0xFFFF;
488
489 if (op == P_TRAP)
490 return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
491 else
ade40d31 492#endif /* GDB_TARGET_IS_SUN3 */
f4992534
SG
493 return read_memory_integer (read_register (SP_REGNUM), 4);
494}
This page took 0.14503 seconds and 4 git commands to generate.