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.
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
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]);
136 sparc64_extract_struct_value_address (regbuf)
137 char regbuf[REGISTER_BYTES];
141 /* FIXME: We assume a non-leaf function. */
142 addr = read_register (I0_REGNUM);
146 /* Check instruction at ADDR to see if it is an annulled branch or other
147 instruction whose npc isn't pc+4 (eg: trap, done, retry).
148 All other instructions will go to NPC or will trap.
149 Set *TARGET if we find a candidate branch; set to zero if not. */
152 isbranch (instruction, addr, target)
154 CORE_ADDR addr, *target;
156 branch_type val = not_branch;
157 long int offset; /* Must be signed for sign-extend. */
160 unsigned long int code;
167 unsigned int disp22:22;
177 unsigned int disp19:19;
184 unsigned int rcond:3;
186 unsigned int disp16hi:2;
189 unsigned int disp16lo:14;
196 unsigned int reserved:19;
201 insn.code = instruction;
204 && (insn.b.op2 == 1 || insn.b.op2 == 2 || insn.b.op2 ==3
205 || insn.b.op2 == 5 || insn.b.op2 == 6))
207 if (insn.b.cond == 8)
208 val = insn.b.a ? baa : ba;
210 val = insn.b.a ? bicca : bicc;
214 offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
217 offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
220 offset = 4 * ((int) ((insn.bpr.disp16hi << 10)
221 || (insn.bpr.disp16lo << 18)) >> 13);
224 offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
227 offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
230 *target = addr + offset;
232 else if (insn.dr.op == 2 && insn.dr.op3 == 62)
234 if (insn.dr.fcn == 0)
237 *target = read_register (TNPC_REGNUM);
240 else if (insn.dr.fcn == 1)
243 *target = read_register (TPC_REGNUM);
251 /* PRINT_REGISTER_HOOK routine.
252 Pretty print various registers. */
255 dump_ccreg (reg, val)
259 printf ("%s:%s,%s,%s,%s", reg,
260 val & 8 ? "N" : "NN",
261 val & 4 ? "Z" : "NZ",
262 val & 2 ? "O" : "NO",
268 sparc_print_register_hook (regno)
271 if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM)
272 && ((regno) & 1) == 0)
274 char doublereg[8]; /* two float regs */
275 if (!read_relative_register_raw_bytes ((regno), doublereg))
278 print_floating (doublereg, builtin_type_double, stdout);
281 else if ((regno) == CCR_REGNUM)
283 int ccr = read_register (CCR_REGNUM);
285 dump_ccreg ("xcc", ccr >> 4);
287 dump_ccreg ("icc", ccr & 15);
291 /* We try to support 32 bit and 64 bit pointers.
292 We are called when the Shade target is selected by shadeif.c. */
294 int target_ptr_bit = 64; /* default */
297 set_target_ptr_bit(ptr_bit)
300 target_ptr_bit = ptr_bit;