]> Git Repo - binutils.git/blob - gdb/sp64-tdep.c
comment change
[binutils.git] / gdb / sp64-tdep.c
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 ([email protected]).
4
5 This file is part of GDB.
6
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.
11
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.
16
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.  */
20
21 #include "defs.h"
22 #include "frame.h"
23 #include "inferior.h"
24 #include "obstack.h"
25 #include "target.h"
26 #include "ieee-float.h"
27
28 /*#include "symfile.h" /* for objfiles.h */
29 /*#include "objfiles.h" /* for find_pc_section */
30
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.  */
35
36 #define TARGET_SPARC64 1        /* later make a config parm or some such */
37
38 /* From infrun.c */
39 extern int stop_after_trap;
40
41 /* Branches with prediction are treated like their non-predicting cousins.  */
42 /* FIXME: What about floating point branches?  */
43
44 typedef enum
45 {
46   Error, not_branch, bicc, bicca, ba, baa, ticc, ta, done_retry
47 } branch_type;
48
49 /* Simulate single-step ptrace call for sun4.  Code written by Gary
50    Beihl ([email protected]).  */
51
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];
58
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
62    sun4. */
63
64 int one_stepped;
65
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.
70
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.  */
73
74 /* FIXME: When the code is releasable, sparc's single step could become this
75    one, removing the duplication.  */
76
77 void
78 sparc64_single_step (ignore)
79      int ignore; /* pid, but we don't need it */
80 {
81   branch_type br, isbranch();
82   CORE_ADDR pc;
83   long pc_instruction;
84
85   if (!one_stepped)
86     {
87       /* Always set breakpoint for NPC.  */
88       next_pc = read_register (NPC_REGNUM);
89       npc4 = next_pc + 4; /* branch not taken */
90
91       target_insert_breakpoint (next_pc, break_mem[0]);
92       /* printf ("set break at %x\n",next_pc); */
93
94       pc = read_register (PC_REGNUM);
95       pc_instruction = read_memory_integer (pc, sizeof(pc_instruction));
96       br = isbranch (pc_instruction, pc, &target);
97       brknpc4 = brktrg = 0;
98
99       if (br == bicca)
100         {
101           /* Conditional annulled branch will either end up at
102              npc (if taken) or at npc+4 (if not taken).
103              Trap npc+4.  */
104           brknpc4 = 1;
105           target_insert_breakpoint (npc4, break_mem[1]);
106         }
107       else if ((br == baa && target != next_pc)
108                || (TARGET_SPARC64 && br == done_retry))
109         {
110           /* Unconditional annulled branch will always end up at
111              the target.  */
112           brktrg = 1;
113           target_insert_breakpoint (target, break_mem[2]);
114         }
115
116       /* We are ready to let it go */
117       one_stepped = 1;
118       return;
119     }
120   else
121     {
122       /* Remove breakpoints */
123       target_remove_breakpoint (next_pc, break_mem[0]);
124
125       if (brknpc4)
126         target_remove_breakpoint (npc4, break_mem[1]);
127
128       if (brktrg)
129         target_remove_breakpoint (target, break_mem[2]);
130
131       one_stepped = 0;
132     }
133 }
134 \f
135 CORE_ADDR
136 sparc64_extract_struct_value_address (regbuf)
137      char regbuf[REGISTER_BYTES];
138 {
139   CORE_ADDR addr;
140
141   /* FIXME: We assume a non-leaf function.  */
142   addr = read_register (I0_REGNUM);
143   return addr;
144 }
145
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. */
150    
151 branch_type
152 isbranch (instruction, addr, target)
153      long instruction;
154      CORE_ADDR addr, *target;
155 {
156   branch_type val = not_branch;
157   long int offset;              /* Must be signed for sign-extend.  */
158   union
159     {
160       unsigned long int code;
161       struct
162         {
163           unsigned int op:2;
164           unsigned int a:1;
165           unsigned int cond:4;
166           unsigned int op2:3;
167           unsigned int disp22:22;
168         } b;
169       struct
170         {
171           unsigned int op:2;
172           unsigned int a:1;
173           unsigned int cond:4;
174           unsigned int op2:3;
175           unsigned int cc:2;
176           unsigned int p:1;
177           unsigned int disp19:19;
178         } bp;
179       struct
180         {
181           unsigned int op:2;
182           unsigned int a:1;
183           unsigned int zero:1;
184           unsigned int rcond:3;
185           unsigned int op2:3;
186           unsigned int disp16hi:2;
187           unsigned int p:1;
188           unsigned int rs1:5;
189           unsigned int disp16lo:14;
190         } bpr;
191       struct
192         {
193           unsigned int op:2;
194           unsigned int fcn:5;
195           unsigned int op3:6;
196           unsigned int reserved:19;
197         } dr;
198     } insn;
199
200   *target = 0;
201   insn.code = instruction;
202
203   if (insn.b.op == 0
204       && (insn.b.op2 == 1 || insn.b.op2 == 2 || insn.b.op2 ==3
205           || insn.b.op2 == 5 || insn.b.op2 == 6))
206     {
207       if (insn.b.cond == 8)
208         val = insn.b.a ? baa : ba;
209       else
210         val = insn.b.a ? bicca : bicc;
211       switch (insn.b.op2)
212         {
213         case 1: /* bpcc */
214           offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
215           break;
216         case 2: /* bicc */
217           offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
218           break;
219         case 3: /* bpr */
220           offset = 4 * ((int) ((insn.bpr.disp16hi << 10)
221                                || (insn.bpr.disp16lo << 18)) >> 13);
222           break;
223         case 5: /* fbpfcc */
224           offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
225           break;
226         case 6: /* fbfcc */
227           offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
228           break;
229         }
230       *target = addr + offset;
231     }
232   else if (insn.dr.op == 2 && insn.dr.op3 == 62)
233     {
234       if (insn.dr.fcn == 0)
235         {
236           /* done */
237           *target = read_register (TNPC_REGNUM);
238           val = done_retry;
239         }
240       else if (insn.dr.fcn == 1)
241         {
242           /* retry */
243           *target = read_register (TPC_REGNUM);
244           val = done_retry;
245         }
246     }
247
248   return val;
249 }
250
251 /* PRINT_REGISTER_HOOK routine.
252    Pretty print various registers.  */
253
254 static void
255 dump_ccreg (reg, val)
256      char *reg;
257      int val;
258 {
259   printf ("%s:%s,%s,%s,%s", reg,
260           val & 8 ? "N" : "NN",
261           val & 4 ? "Z" : "NZ",
262           val & 2 ? "O" : "NO",
263           val & 1 ? "C" : "NC"
264   );
265 }
266
267 void
268 sparc_print_register_hook (regno)
269      int regno;
270 {
271   if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM)
272        && ((regno) & 1) == 0)
273     {
274       char doublereg[8];                /* two float regs */
275       if (!read_relative_register_raw_bytes ((regno), doublereg))
276         {
277           printf("\t");
278           print_floating (doublereg, builtin_type_double, stdout);
279         }
280     }
281   else if ((regno) == CCR_REGNUM)
282     {
283       int ccr = read_register (CCR_REGNUM);
284       printf("\t");
285       dump_ccreg ("xcc", ccr >> 4);
286       printf(", ");
287       dump_ccreg ("icc", ccr & 15);
288     }
289 }
290
291 /* We try to support 32 bit and 64 bit pointers.
292    We are called when the Shade target is selected by shadeif.c.  */
293
294 int target_ptr_bit = 64;        /* default */
295
296 void
297 set_target_ptr_bit(ptr_bit)
298      int ptr_bit;
299 {
300   target_ptr_bit = ptr_bit;
301 }
This page took 0.066497 seconds and 4 git commands to generate.