]> Git Repo - binutils.git/blob - gdb/sp64-tdep.c
Initial versions of sparc64 port.
[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 /* FIXME: sparc64_frame_chain() is temporary.  sparc_frame_chain() can
136    be fixed to support both of us.  */
137
138 #define FRAME_SAVED_L0  0                         /* Byte offset from SP */
139 #define FRAME_SAVED_I0  (8*REGISTER_RAW_SIZE (0)) /* Byte offset from SP */
140
141 CORE_ADDR
142 sparc64_frame_chain (thisframe)
143      FRAME thisframe;
144 {
145   REGISTER_TYPE retval;
146   int err;
147   CORE_ADDR addr;
148
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));
152   if (err)
153     return 0;
154   SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
155   return retval;
156 }
157
158 CORE_ADDR
159 sparc64_extract_struct_value_address (regbuf)
160      char regbuf[REGISTER_BYTES];
161 {
162   CORE_ADDR addr;
163
164   /* FIXME: We assume a non-leaf function.  */
165   addr = read_register (I0_REGNUM);
166   return addr;
167 }
168
169 /* Find the pc saved in frame FRAME.  */
170 /* FIXME: This function can be removed when sparc_frame_saved_pc
171    handles us too.  */
172
173 CORE_ADDR
174 sparc64_frame_saved_pc (frame)
175      FRAME frame;
176 {
177   int err;
178   REGISTER_TYPE retval;
179   CORE_ADDR addr,prev_pc;
180
181   if (get_current_frame () == frame)  /* FIXME, debug check. Remove >=gdb-4.6 */
182     {
183       if (read_register (SP_REGNUM) != frame->bottom) abort();
184     }
185
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));
189   if (err)
190     return 0;
191   SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
192
193   /* CORE_ADDR isn't always the same size as REGISTER_TYPE, so convert.  */
194
195   prev_pc = (CORE_ADDR) retval;
196   return PC_ADJUST (prev_pc);
197 }
198
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. */
203    
204 branch_type
205 isbranch (instruction, addr, target)
206      long instruction;
207      CORE_ADDR addr, *target;
208 {
209   branch_type val = not_branch;
210   long int offset;              /* Must be signed for sign-extend.  */
211   union
212     {
213       unsigned long int code;
214       struct
215         {
216           unsigned int op:2;
217           unsigned int a:1;
218           unsigned int cond:4;
219           unsigned int op2:3;
220           unsigned int disp22:22;
221         } b;
222       struct
223         {
224           unsigned int op:2;
225           unsigned int a:1;
226           unsigned int cond:4;
227           unsigned int op2:3;
228           unsigned int cc:2;
229           unsigned int p:1;
230           unsigned int disp19:19;
231         } bp;
232       struct
233         {
234           unsigned int op:2;
235           unsigned int a:1;
236           unsigned int zero:1;
237           unsigned int rcond:3;
238           unsigned int op2:3;
239           unsigned int disp16hi:2;
240           unsigned int p:1;
241           unsigned int rs1:5;
242           unsigned int disp16lo:14;
243         } bpr;
244       struct
245         {
246           unsigned int op:2;
247           unsigned int fcn:5;
248           unsigned int op3:6;
249           unsigned int reserved:19;
250         } dr;
251     } insn;
252
253   *target = 0;
254   insn.code = instruction;
255
256   if (insn.b.op == 0
257       && (insn.b.op2 == 1 || insn.b.op2 == 2 || insn.b.op2 ==3
258           || insn.b.op2 == 5 || insn.b.op2 == 6))
259     {
260       if (insn.b.cond == 8)
261         val = insn.b.a ? baa : ba;
262       else
263         val = insn.b.a ? bicca : bicc;
264       switch (insn.b.op2)
265         {
266         case 1: /* bpcc */
267           offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
268           break;
269         case 2: /* bicc */
270           offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
271           break;
272         case 3: /* bpr */
273           offset = 4 * ((int) ((insn.bpr.disp16hi << 10)
274                                || (insn.bpr.disp16lo << 18)) >> 13);
275           break;
276         case 5: /* fbpfcc */
277           offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
278           break;
279         case 6: /* fbfcc */
280           offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
281           break;
282         }
283       *target = addr + offset;
284     }
285   else if (insn.dr.op == 2 && insn.dr.op3 == 62)
286     {
287       if (insn.dr.fcn == 0)
288         {
289           /* done */
290           *target = read_register (TNPC_REGNUM);
291           val = done_retry;
292         }
293       else if (insn.dr.fcn == 1)
294         {
295           /* retry */
296           *target = read_register (TPC_REGNUM);
297           val = done_retry;
298         }
299     }
300
301   return val;
302 }
303
304 /* We try to support 32 bit and 64 bit pointers.
305    We are called when the Shade target is selected by shadeif.c.  */
306
307 int target_ptr_bit = 64;        /* default */
308
309 void
310 set_target_ptr_bit(ptr_bit)
311      int ptr_bit;
312 {
313   target_ptr_bit = ptr_bit;
314 }
This page took 0.040854 seconds and 4 git commands to generate.