* Makefile.in (copying.o, f-exp.tab.o, dpx2-nat.o, dstread.o,
[deliverable/binutils-gdb.git] / gdb / sp64-tdep.c
CommitLineData
cb747ec5
DE
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).
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include "defs.h"
22#include "frame.h"
23#include "inferior.h"
24#include "obstack.h"
25#include "target.h"
cb747ec5
DE
26
27/*#include "symfile.h" /* for objfiles.h */
28/*#include "objfiles.h" /* for find_pc_section */
29
30/* This file contains replacements and additions to sparc-tdep.c only.
31 Some of this code has been written for a day when we can merge at least
32 some of this with sparc-tdep.c. Macro TARGET_SPARC64 exists to allow some
33 code to potentially be used by both. */
34
35#define TARGET_SPARC64 1 /* later make a config parm or some such */
36
37/* From infrun.c */
38extern int stop_after_trap;
39
40/* Branches with prediction are treated like their non-predicting cousins. */
41/* FIXME: What about floating point branches? */
42
43typedef enum
44{
45 Error, not_branch, bicc, bicca, ba, baa, ticc, ta, done_retry
46} branch_type;
47
48/* Simulate single-step ptrace call for sun4. Code written by Gary
49 Beihl (beihl@mcc.com). */
50
51/* npc4 and next_pc describe the situation at the time that the
52 step-breakpoint was set, not necessary the current value of NPC_REGNUM. */
53static CORE_ADDR next_pc, npc4, target;
54static int brknpc4, brktrg;
55typedef char binsn_quantum[BREAKPOINT_MAX];
56static binsn_quantum break_mem[3];
57
58/* Non-zero if we just simulated a single-step ptrace call. This is
59 needed because we cannot remove the breakpoints in the inferior
60 process until after the `wait' in `wait_for_inferior'. Used for
61 sun4. */
62
63int one_stepped;
64
65/* sparc64_single_step() is called just before we want to resume the inferior,
66 if we want to single-step it but there is no hardware or kernel single-step
67 support (as on all SPARCs). We find all the possible targets of the
68 coming instruction and breakpoint them.
69
70 single_step is also called just after the inferior stops. If we had
71 set up a simulated single-step, we undo our damage. */
72
73/* FIXME: When the code is releasable, sparc's single step could become this
74 one, removing the duplication. */
75
76void
77sparc64_single_step (ignore)
78 int ignore; /* pid, but we don't need it */
79{
80 branch_type br, isbranch();
81 CORE_ADDR pc;
82 long pc_instruction;
83
84 if (!one_stepped)
85 {
86 /* Always set breakpoint for NPC. */
87 next_pc = read_register (NPC_REGNUM);
88 npc4 = next_pc + 4; /* branch not taken */
89
90 target_insert_breakpoint (next_pc, break_mem[0]);
199b2450 91 /* printf_unfiltered ("set break at %x\n",next_pc); */
cb747ec5
DE
92
93 pc = read_register (PC_REGNUM);
94 pc_instruction = read_memory_integer (pc, sizeof(pc_instruction));
95 br = isbranch (pc_instruction, pc, &target);
96 brknpc4 = brktrg = 0;
97
98 if (br == bicca)
99 {
100 /* Conditional annulled branch will either end up at
101 npc (if taken) or at npc+4 (if not taken).
102 Trap npc+4. */
103 brknpc4 = 1;
104 target_insert_breakpoint (npc4, break_mem[1]);
105 }
106 else if ((br == baa && target != next_pc)
107 || (TARGET_SPARC64 && br == done_retry))
108 {
109 /* Unconditional annulled branch will always end up at
110 the target. */
111 brktrg = 1;
112 target_insert_breakpoint (target, break_mem[2]);
113 }
114
115 /* We are ready to let it go */
116 one_stepped = 1;
117 return;
118 }
119 else
120 {
121 /* Remove breakpoints */
122 target_remove_breakpoint (next_pc, break_mem[0]);
123
124 if (brknpc4)
125 target_remove_breakpoint (npc4, break_mem[1]);
126
127 if (brktrg)
128 target_remove_breakpoint (target, break_mem[2]);
129
130 one_stepped = 0;
131 }
132}
133\f
cb747ec5
DE
134CORE_ADDR
135sparc64_extract_struct_value_address (regbuf)
136 char regbuf[REGISTER_BYTES];
137{
138 CORE_ADDR addr;
139
140 /* FIXME: We assume a non-leaf function. */
141 addr = read_register (I0_REGNUM);
142 return addr;
143}
144
cb747ec5
DE
145/* Check instruction at ADDR to see if it is an annulled branch or other
146 instruction whose npc isn't pc+4 (eg: trap, done, retry).
147 All other instructions will go to NPC or will trap.
148 Set *TARGET if we find a candidate branch; set to zero if not. */
149
150branch_type
151isbranch (instruction, addr, target)
152 long instruction;
153 CORE_ADDR addr, *target;
154{
155 branch_type val = not_branch;
156 long int offset; /* Must be signed for sign-extend. */
157 union
158 {
159 unsigned long int code;
160 struct
161 {
162 unsigned int op:2;
163 unsigned int a:1;
164 unsigned int cond:4;
165 unsigned int op2:3;
166 unsigned int disp22:22;
167 } b;
168 struct
169 {
170 unsigned int op:2;
171 unsigned int a:1;
172 unsigned int cond:4;
173 unsigned int op2:3;
174 unsigned int cc:2;
175 unsigned int p:1;
176 unsigned int disp19:19;
177 } bp;
178 struct
179 {
180 unsigned int op:2;
181 unsigned int a:1;
182 unsigned int zero:1;
183 unsigned int rcond:3;
184 unsigned int op2:3;
185 unsigned int disp16hi:2;
186 unsigned int p:1;
187 unsigned int rs1:5;
188 unsigned int disp16lo:14;
189 } bpr;
190 struct
191 {
192 unsigned int op:2;
193 unsigned int fcn:5;
194 unsigned int op3:6;
195 unsigned int reserved:19;
196 } dr;
197 } insn;
198
199 *target = 0;
200 insn.code = instruction;
201
202 if (insn.b.op == 0
203 && (insn.b.op2 == 1 || insn.b.op2 == 2 || insn.b.op2 ==3
204 || insn.b.op2 == 5 || insn.b.op2 == 6))
205 {
206 if (insn.b.cond == 8)
207 val = insn.b.a ? baa : ba;
208 else
209 val = insn.b.a ? bicca : bicc;
210 switch (insn.b.op2)
211 {
212 case 1: /* bpcc */
213 offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
214 break;
215 case 2: /* bicc */
216 offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
217 break;
218 case 3: /* bpr */
219 offset = 4 * ((int) ((insn.bpr.disp16hi << 10)
220 || (insn.bpr.disp16lo << 18)) >> 13);
221 break;
222 case 5: /* fbpfcc */
223 offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
224 break;
225 case 6: /* fbfcc */
226 offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
227 break;
228 }
229 *target = addr + offset;
230 }
231 else if (insn.dr.op == 2 && insn.dr.op3 == 62)
232 {
233 if (insn.dr.fcn == 0)
234 {
235 /* done */
236 *target = read_register (TNPC_REGNUM);
237 val = done_retry;
238 }
239 else if (insn.dr.fcn == 1)
240 {
241 /* retry */
242 *target = read_register (TPC_REGNUM);
243 val = done_retry;
244 }
245 }
246
247 return val;
248}
249
b562a186
DE
250/* PRINT_REGISTER_HOOK routine.
251 Pretty print various registers. */
252
253static void
254dump_ccreg (reg, val)
255 char *reg;
256 int val;
257{
199b2450 258 printf_unfiltered ("%s:%s,%s,%s,%s", reg,
b562a186
DE
259 val & 8 ? "N" : "NN",
260 val & 4 ? "Z" : "NZ",
261 val & 2 ? "O" : "NO",
262 val & 1 ? "C" : "NC"
263 );
264}
265
266void
267sparc_print_register_hook (regno)
268 int regno;
269{
270 if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM)
271 && ((regno) & 1) == 0)
272 {
273 char doublereg[8]; /* two float regs */
274 if (!read_relative_register_raw_bytes ((regno), doublereg))
275 {
199b2450
TL
276 printf_unfiltered("\t");
277 print_floating (doublereg, builtin_type_double, gdb_stdout);
b562a186
DE
278 }
279 }
280 else if ((regno) == CCR_REGNUM)
281 {
282 int ccr = read_register (CCR_REGNUM);
199b2450 283 printf_unfiltered("\t");
b562a186 284 dump_ccreg ("xcc", ccr >> 4);
199b2450 285 printf_unfiltered(", ");
b562a186
DE
286 dump_ccreg ("icc", ccr & 15);
287 }
288}
This page took 0.50948 seconds and 4 git commands to generate.