1 /* Target-dependent code for the SPARC 64 for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Contributed by Doug Evans (dje@cygnus.com).
5 This file is part of GDB.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "ieee-float.h"
28 /*#include "symfile.h" /* for objfiles.h */
29 /*#include "objfiles.h" /* for find_pc_section */
31 /* This file contains replacements and additions to sparc-tdep.c only.
32 Some of this code has been written for a day when we can merge at least
33 some of this with sparc-tdep.c. Macro TARGET_SPARC64 exists to allow some
34 code to potentially be used by both. */
36 #define TARGET_SPARC64 1 /* later make a config parm or some such */
39 extern int stop_after_trap
;
41 /* Branches with prediction are treated like their non-predicting cousins. */
42 /* FIXME: What about floating point branches? */
46 Error
, not_branch
, bicc
, bicca
, ba
, baa
, ticc
, ta
, done_retry
49 /* Simulate single-step ptrace call for sun4. Code written by Gary
50 Beihl (beihl@mcc.com). */
52 /* npc4 and next_pc describe the situation at the time that the
53 step-breakpoint was set, not necessary the current value of NPC_REGNUM. */
54 static CORE_ADDR next_pc
, npc4
, target
;
55 static int brknpc4
, brktrg
;
56 typedef char binsn_quantum
[BREAKPOINT_MAX
];
57 static binsn_quantum break_mem
[3];
59 /* Non-zero if we just simulated a single-step ptrace call. This is
60 needed because we cannot remove the breakpoints in the inferior
61 process until after the `wait' in `wait_for_inferior'. Used for
66 /* sparc64_single_step() is called just before we want to resume the inferior,
67 if we want to single-step it but there is no hardware or kernel single-step
68 support (as on all SPARCs). We find all the possible targets of the
69 coming instruction and breakpoint them.
71 single_step is also called just after the inferior stops. If we had
72 set up a simulated single-step, we undo our damage. */
74 /* FIXME: When the code is releasable, sparc's single step could become this
75 one, removing the duplication. */
78 sparc64_single_step (ignore
)
79 int ignore
; /* pid, but we don't need it */
81 branch_type br
, isbranch();
87 /* Always set breakpoint for NPC. */
88 next_pc
= read_register (NPC_REGNUM
);
89 npc4
= next_pc
+ 4; /* branch not taken */
91 target_insert_breakpoint (next_pc
, break_mem
[0]);
92 /* printf ("set break at %x\n",next_pc); */
94 pc
= read_register (PC_REGNUM
);
95 pc_instruction
= read_memory_integer (pc
, sizeof(pc_instruction
));
96 br
= isbranch (pc_instruction
, pc
, &target
);
101 /* Conditional annulled branch will either end up at
102 npc (if taken) or at npc+4 (if not taken).
105 target_insert_breakpoint (npc4
, break_mem
[1]);
107 else if ((br
== baa
&& target
!= next_pc
)
108 || (TARGET_SPARC64
&& br
== done_retry
))
110 /* Unconditional annulled branch will always end up at
113 target_insert_breakpoint (target
, break_mem
[2]);
116 /* We are ready to let it go */
122 /* Remove breakpoints */
123 target_remove_breakpoint (next_pc
, break_mem
[0]);
126 target_remove_breakpoint (npc4
, break_mem
[1]);
129 target_remove_breakpoint (target
, break_mem
[2]);
135 /* FIXME: sparc64_frame_chain() is temporary. sparc_frame_chain() can
136 be fixed to support both of us. */
138 #define FRAME_SAVED_L0 0 /* Byte offset from SP */
139 #define FRAME_SAVED_I0 (8*REGISTER_RAW_SIZE (0)) /* Byte offset from SP */
142 sparc64_frame_chain (thisframe
)
145 REGISTER_TYPE retval
;
149 addr
= thisframe
->frame
+ FRAME_SAVED_I0
+
150 REGISTER_RAW_SIZE (0) * (FP_REGNUM
- I0_REGNUM
);
151 err
= target_read_memory (addr
, (char *) &retval
, sizeof (REGISTER_TYPE
));
154 SWAP_TARGET_AND_HOST (&retval
, sizeof (retval
));
159 sparc64_extract_struct_value_address (regbuf
)
160 char regbuf
[REGISTER_BYTES
];
164 /* FIXME: We assume a non-leaf function. */
165 addr
= read_register (I0_REGNUM
);
169 /* Find the pc saved in frame FRAME. */
170 /* FIXME: This function can be removed when sparc_frame_saved_pc
174 sparc64_frame_saved_pc (frame
)
178 REGISTER_TYPE retval
;
179 CORE_ADDR addr
,prev_pc
;
181 if (get_current_frame () == frame
) /* FIXME, debug check. Remove >=gdb-4.6 */
183 if (read_register (SP_REGNUM
) != frame
->bottom
) abort();
186 addr
= frame
->bottom
+ FRAME_SAVED_I0
+
187 REGISTER_RAW_SIZE (0) * (I7_REGNUM
- I0_REGNUM
);
188 err
= target_read_memory (addr
, (char *) &retval
, sizeof (REGISTER_TYPE
));
191 SWAP_TARGET_AND_HOST (&retval
, sizeof (retval
));
193 /* CORE_ADDR isn't always the same size as REGISTER_TYPE, so convert. */
195 prev_pc
= (CORE_ADDR
) retval
;
196 return PC_ADJUST (prev_pc
);
199 /* Check instruction at ADDR to see if it is an annulled branch or other
200 instruction whose npc isn't pc+4 (eg: trap, done, retry).
201 All other instructions will go to NPC or will trap.
202 Set *TARGET if we find a candidate branch; set to zero if not. */
205 isbranch (instruction
, addr
, target
)
207 CORE_ADDR addr
, *target
;
209 branch_type val
= not_branch
;
210 long int offset
; /* Must be signed for sign-extend. */
213 unsigned long int code
;
220 unsigned int disp22
:22;
230 unsigned int disp19
:19;
237 unsigned int rcond
:3;
239 unsigned int disp16hi
:2;
242 unsigned int disp16lo
:14;
249 unsigned int reserved
:19;
254 insn
.code
= instruction
;
257 && (insn
.b
.op2
== 1 || insn
.b
.op2
== 2 || insn
.b
.op2
==3
258 || insn
.b
.op2
== 5 || insn
.b
.op2
== 6))
260 if (insn
.b
.cond
== 8)
261 val
= insn
.b
.a
? baa
: ba
;
263 val
= insn
.b
.a
? bicca
: bicc
;
267 offset
= 4 * ((int) (insn
.bp
.disp19
<< 13) >> 13);
270 offset
= 4 * ((int) (insn
.b
.disp22
<< 10) >> 10);
273 offset
= 4 * ((int) ((insn
.bpr
.disp16hi
<< 10)
274 || (insn
.bpr
.disp16lo
<< 18)) >> 13);
277 offset
= 4 * ((int) (insn
.bp
.disp19
<< 13) >> 13);
280 offset
= 4 * ((int) (insn
.b
.disp22
<< 10) >> 10);
283 *target
= addr
+ offset
;
285 else if (insn
.dr
.op
== 2 && insn
.dr
.op3
== 62)
287 if (insn
.dr
.fcn
== 0)
290 *target
= read_register (TNPC_REGNUM
);
293 else if (insn
.dr
.fcn
== 1)
296 *target
= read_register (TPC_REGNUM
);
304 /* We try to support 32 bit and 64 bit pointers.
305 We are called when the Shade target is selected by shadeif.c. */
307 int target_ptr_bit
= 64; /* default */
310 set_target_ptr_bit(ptr_bit
)
313 target_ptr_bit
= ptr_bit
;