Commit | Line | Data |
---|---|---|
eb4c54a2 AC |
1 | // OBSOLETE /* ARC target-dependent stuff. |
2 | // OBSOLETE Copyright 1995, 1996, 1999, 2000, 2001 Free Software Foundation, Inc. | |
3 | // OBSOLETE | |
4 | // OBSOLETE This file is part of GDB. | |
5 | // OBSOLETE | |
6 | // OBSOLETE This program is free software; you can redistribute it and/or modify | |
7 | // OBSOLETE it under the terms of the GNU General Public License as published by | |
8 | // OBSOLETE the Free Software Foundation; either version 2 of the License, or | |
9 | // OBSOLETE (at your option) any later version. | |
10 | // OBSOLETE | |
11 | // OBSOLETE This program is distributed in the hope that it will be useful, | |
12 | // OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // OBSOLETE GNU General Public License for more details. | |
15 | // OBSOLETE | |
16 | // OBSOLETE You should have received a copy of the GNU General Public License | |
17 | // OBSOLETE along with this program; if not, write to the Free Software | |
18 | // OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, | |
19 | // OBSOLETE Boston, MA 02111-1307, USA. */ | |
20 | // OBSOLETE | |
21 | // OBSOLETE #include "defs.h" | |
22 | // OBSOLETE #include "frame.h" | |
23 | // OBSOLETE #include "inferior.h" | |
24 | // OBSOLETE #include "gdbcore.h" | |
25 | // OBSOLETE #include "target.h" | |
26 | // OBSOLETE #include "floatformat.h" | |
27 | // OBSOLETE #include "symtab.h" | |
28 | // OBSOLETE #include "gdbcmd.h" | |
29 | // OBSOLETE #include "regcache.h" | |
30 | // OBSOLETE #include "gdb_string.h" | |
31 | // OBSOLETE | |
32 | // OBSOLETE /* Local functions */ | |
33 | // OBSOLETE | |
34 | // OBSOLETE static int arc_set_cpu_type (char *str); | |
35 | // OBSOLETE | |
36 | // OBSOLETE /* Current CPU, set with the "set cpu" command. */ | |
37 | // OBSOLETE static int arc_bfd_mach_type; | |
38 | // OBSOLETE char *arc_cpu_type; | |
39 | // OBSOLETE char *tmp_arc_cpu_type; | |
40 | // OBSOLETE | |
41 | // OBSOLETE /* Table of cpu names. */ | |
42 | // OBSOLETE struct | |
43 | // OBSOLETE { | |
44 | // OBSOLETE char *name; | |
45 | // OBSOLETE int value; | |
46 | // OBSOLETE } | |
47 | // OBSOLETE arc_cpu_type_table[] = | |
48 | // OBSOLETE { | |
49 | // OBSOLETE { "arc5", bfd_mach_arc_5 }, | |
50 | // OBSOLETE { "arc6", bfd_mach_arc_6 }, | |
51 | // OBSOLETE { "arc7", bfd_mach_arc_7 }, | |
52 | // OBSOLETE { "arc8", bfd_mach_arc_8 }, | |
53 | // OBSOLETE { NULL, 0 } | |
54 | // OBSOLETE }; | |
55 | // OBSOLETE | |
56 | // OBSOLETE /* Used by simulator. */ | |
57 | // OBSOLETE int display_pipeline_p; | |
58 | // OBSOLETE int cpu_timer; | |
59 | // OBSOLETE /* This one must have the same type as used in the emulator. | |
60 | // OBSOLETE It's currently an enum so this should be ok for now. */ | |
61 | // OBSOLETE int debug_pipeline_p; | |
62 | // OBSOLETE | |
63 | // OBSOLETE #define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24) | |
64 | // OBSOLETE | |
65 | // OBSOLETE #define OPMASK 0xf8000000 | |
66 | // OBSOLETE | |
67 | // OBSOLETE /* Instruction field accessor macros. | |
68 | // OBSOLETE See the Programmer's Reference Manual. */ | |
69 | // OBSOLETE #define X_OP(i) (((i) >> 27) & 0x1f) | |
70 | // OBSOLETE #define X_A(i) (((i) >> 21) & 0x3f) | |
71 | // OBSOLETE #define X_B(i) (((i) >> 15) & 0x3f) | |
72 | // OBSOLETE #define X_C(i) (((i) >> 9) & 0x3f) | |
73 | // OBSOLETE #define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100) | |
74 | // OBSOLETE #define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000) | |
75 | // OBSOLETE #define X_N(i) (((i) >> 5) & 3) | |
76 | // OBSOLETE #define X_Q(i) ((i) & 0x1f) | |
77 | // OBSOLETE | |
78 | // OBSOLETE /* Return non-zero if X is a short immediate data indicator. */ | |
79 | // OBSOLETE #define SHIMM_P(x) ((x) == 61 || (x) == 63) | |
80 | // OBSOLETE | |
81 | // OBSOLETE /* Return non-zero if X is a "long" (32 bit) immediate data indicator. */ | |
82 | // OBSOLETE #define LIMM_P(x) ((x) == 62) | |
83 | // OBSOLETE | |
84 | // OBSOLETE /* Build a simple instruction. */ | |
85 | // OBSOLETE #define BUILD_INSN(op, a, b, c, d) \ | |
86 | // OBSOLETE ((((op) & 31) << 27) \ | |
87 | // OBSOLETE | (((a) & 63) << 21) \ | |
88 | // OBSOLETE | (((b) & 63) << 15) \ | |
89 | // OBSOLETE | (((c) & 63) << 9) \ | |
90 | // OBSOLETE | ((d) & 511)) | |
91 | // OBSOLETE \f | |
92 | // OBSOLETE /* Codestream stuff. */ | |
93 | // OBSOLETE static void codestream_read (unsigned int *, int); | |
94 | // OBSOLETE static void codestream_seek (CORE_ADDR); | |
95 | // OBSOLETE static unsigned int codestream_fill (int); | |
96 | // OBSOLETE | |
97 | // OBSOLETE #define CODESTREAM_BUFSIZ 16 | |
98 | // OBSOLETE static CORE_ADDR codestream_next_addr; | |
99 | // OBSOLETE static CORE_ADDR codestream_addr; | |
100 | // OBSOLETE /* FIXME assumes sizeof (int) == 32? */ | |
101 | // OBSOLETE static unsigned int codestream_buf[CODESTREAM_BUFSIZ]; | |
102 | // OBSOLETE static int codestream_off; | |
103 | // OBSOLETE static int codestream_cnt; | |
104 | // OBSOLETE | |
105 | // OBSOLETE #define codestream_tell() \ | |
106 | // OBSOLETE (codestream_addr + codestream_off * sizeof (codestream_buf[0])) | |
107 | // OBSOLETE #define codestream_peek() \ | |
108 | // OBSOLETE (codestream_cnt == 0 \ | |
109 | // OBSOLETE ? codestream_fill (1) \ | |
110 | // OBSOLETE : codestream_buf[codestream_off]) | |
111 | // OBSOLETE #define codestream_get() \ | |
112 | // OBSOLETE (codestream_cnt-- == 0 \ | |
113 | // OBSOLETE ? codestream_fill (0) \ | |
114 | // OBSOLETE : codestream_buf[codestream_off++]) | |
115 | // OBSOLETE | |
116 | // OBSOLETE static unsigned int | |
117 | // OBSOLETE codestream_fill (int peek_flag) | |
118 | // OBSOLETE { | |
119 | // OBSOLETE codestream_addr = codestream_next_addr; | |
120 | // OBSOLETE codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]); | |
121 | // OBSOLETE codestream_off = 0; | |
122 | // OBSOLETE codestream_cnt = CODESTREAM_BUFSIZ; | |
123 | // OBSOLETE read_memory (codestream_addr, (char *) codestream_buf, | |
124 | // OBSOLETE CODESTREAM_BUFSIZ * sizeof (codestream_buf[0])); | |
125 | // OBSOLETE /* FIXME: check return code? */ | |
126 | // OBSOLETE | |
127 | // OBSOLETE | |
128 | // OBSOLETE /* Handle byte order differences -> convert to host byte ordering. */ | |
129 | // OBSOLETE { | |
130 | // OBSOLETE int i; | |
131 | // OBSOLETE for (i = 0; i < CODESTREAM_BUFSIZ; i++) | |
132 | // OBSOLETE codestream_buf[i] = | |
133 | // OBSOLETE extract_unsigned_integer (&codestream_buf[i], | |
134 | // OBSOLETE sizeof (codestream_buf[i])); | |
135 | // OBSOLETE } | |
136 | // OBSOLETE | |
137 | // OBSOLETE if (peek_flag) | |
138 | // OBSOLETE return codestream_peek (); | |
139 | // OBSOLETE else | |
140 | // OBSOLETE return codestream_get (); | |
141 | // OBSOLETE } | |
142 | // OBSOLETE | |
143 | // OBSOLETE static void | |
144 | // OBSOLETE codestream_seek (CORE_ADDR place) | |
145 | // OBSOLETE { | |
146 | // OBSOLETE codestream_next_addr = place / CODESTREAM_BUFSIZ; | |
147 | // OBSOLETE codestream_next_addr *= CODESTREAM_BUFSIZ; | |
148 | // OBSOLETE codestream_cnt = 0; | |
149 | // OBSOLETE codestream_fill (1); | |
150 | // OBSOLETE while (codestream_tell () != place) | |
151 | // OBSOLETE codestream_get (); | |
152 | // OBSOLETE } | |
153 | // OBSOLETE | |
154 | // OBSOLETE /* This function is currently unused but leave in for now. */ | |
155 | // OBSOLETE | |
156 | // OBSOLETE static void | |
157 | // OBSOLETE codestream_read (unsigned int *buf, int count) | |
158 | // OBSOLETE { | |
159 | // OBSOLETE unsigned int *p; | |
160 | // OBSOLETE int i; | |
161 | // OBSOLETE p = buf; | |
162 | // OBSOLETE for (i = 0; i < count; i++) | |
163 | // OBSOLETE *p++ = codestream_get (); | |
164 | // OBSOLETE } | |
165 | // OBSOLETE \f | |
166 | // OBSOLETE /* Set up prologue scanning and return the first insn. */ | |
167 | // OBSOLETE | |
168 | // OBSOLETE static unsigned int | |
169 | // OBSOLETE setup_prologue_scan (CORE_ADDR pc) | |
170 | // OBSOLETE { | |
171 | // OBSOLETE unsigned int insn; | |
172 | // OBSOLETE | |
173 | // OBSOLETE codestream_seek (pc); | |
174 | // OBSOLETE insn = codestream_get (); | |
175 | // OBSOLETE | |
176 | // OBSOLETE return insn; | |
177 | // OBSOLETE } | |
178 | // OBSOLETE | |
179 | // OBSOLETE /* | |
180 | // OBSOLETE * Find & return amount a local space allocated, and advance codestream to | |
181 | // OBSOLETE * first register push (if any). | |
182 | // OBSOLETE * If entry sequence doesn't make sense, return -1, and leave | |
183 | // OBSOLETE * codestream pointer random. | |
184 | // OBSOLETE */ | |
185 | // OBSOLETE | |
186 | // OBSOLETE static long | |
187 | // OBSOLETE arc_get_frame_setup (CORE_ADDR pc) | |
188 | // OBSOLETE { | |
189 | // OBSOLETE unsigned int insn; | |
190 | // OBSOLETE /* Size of frame or -1 if unrecognizable prologue. */ | |
191 | // OBSOLETE int frame_size = -1; | |
192 | // OBSOLETE /* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */ | |
193 | // OBSOLETE int maybe_stdarg_decr = -1; | |
194 | // OBSOLETE | |
195 | // OBSOLETE insn = setup_prologue_scan (pc); | |
196 | // OBSOLETE | |
197 | // OBSOLETE /* The authority for what appears here is the home-grown ABI. | |
198 | // OBSOLETE The most recent version is 1.2. */ | |
199 | // OBSOLETE | |
200 | // OBSOLETE /* First insn may be "sub sp,sp,N" if stdarg fn. */ | |
201 | // OBSOLETE if ((insn & BUILD_INSN (-1, -1, -1, -1, 0)) | |
202 | // OBSOLETE == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0)) | |
203 | // OBSOLETE { | |
204 | // OBSOLETE maybe_stdarg_decr = X_D (insn); | |
205 | // OBSOLETE insn = codestream_get (); | |
206 | // OBSOLETE } | |
207 | // OBSOLETE | |
208 | // OBSOLETE if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */ | |
209 | // OBSOLETE == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4)) | |
210 | // OBSOLETE { | |
211 | // OBSOLETE insn = codestream_get (); | |
212 | // OBSOLETE /* Frame may not be necessary, even though blink is saved. | |
213 | // OBSOLETE At least this is something we recognize. */ | |
214 | // OBSOLETE frame_size = 0; | |
215 | // OBSOLETE } | |
216 | // OBSOLETE | |
217 | // OBSOLETE if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */ | |
218 | // OBSOLETE == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0)) | |
219 | // OBSOLETE { | |
220 | // OBSOLETE insn = codestream_get (); | |
221 | // OBSOLETE if ((insn & BUILD_INSN (-1, -1, -1, -1, 0)) | |
222 | // OBSOLETE != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0)) | |
223 | // OBSOLETE return -1; | |
224 | // OBSOLETE | |
225 | // OBSOLETE /* Check for stack adjustment sub sp,sp,N. */ | |
226 | // OBSOLETE insn = codestream_peek (); | |
227 | // OBSOLETE if ((insn & BUILD_INSN (-1, -1, -1, 0, 0)) | |
228 | // OBSOLETE == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0)) | |
229 | // OBSOLETE { | |
230 | // OBSOLETE if (LIMM_P (X_C (insn))) | |
231 | // OBSOLETE frame_size = codestream_get (); | |
232 | // OBSOLETE else if (SHIMM_P (X_C (insn))) | |
233 | // OBSOLETE frame_size = X_D (insn); | |
234 | // OBSOLETE else | |
235 | // OBSOLETE return -1; | |
236 | // OBSOLETE if (frame_size < 0) | |
237 | // OBSOLETE return -1; | |
238 | // OBSOLETE | |
239 | // OBSOLETE codestream_get (); | |
240 | // OBSOLETE | |
241 | // OBSOLETE /* This sequence is used to get the address of the return | |
242 | // OBSOLETE buffer for a function that returns a structure. */ | |
243 | // OBSOLETE insn = codestream_peek (); | |
244 | // OBSOLETE if ((insn & OPMASK) == 0x60000000) | |
245 | // OBSOLETE codestream_get (); | |
246 | // OBSOLETE } | |
247 | // OBSOLETE /* Frameless fn. */ | |
248 | // OBSOLETE else | |
249 | // OBSOLETE { | |
250 | // OBSOLETE frame_size = 0; | |
251 | // OBSOLETE } | |
252 | // OBSOLETE } | |
253 | // OBSOLETE | |
254 | // OBSOLETE /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a | |
255 | // OBSOLETE stdarg fn. The stdarg decrement is not treated as part of the frame size, | |
256 | // OBSOLETE so we have a dilemma: what do we return? For now, if we get a | |
257 | // OBSOLETE "sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way | |
258 | // OBSOLETE to fix this completely would be to add a bit to the function descriptor | |
259 | // OBSOLETE that says the function is a stdarg function. */ | |
260 | // OBSOLETE | |
261 | // OBSOLETE if (frame_size < 0 && maybe_stdarg_decr > 0) | |
262 | // OBSOLETE return maybe_stdarg_decr; | |
263 | // OBSOLETE return frame_size; | |
264 | // OBSOLETE } | |
265 | // OBSOLETE | |
266 | // OBSOLETE /* Given a pc value, skip it forward past the function prologue by | |
267 | // OBSOLETE disassembling instructions that appear to be a prologue. | |
268 | // OBSOLETE | |
269 | // OBSOLETE If FRAMELESS_P is set, we are only testing to see if the function | |
270 | // OBSOLETE is frameless. If it is a frameless function, return PC unchanged. | |
271 | // OBSOLETE This allows a quicker answer. */ | |
272 | // OBSOLETE | |
273 | // OBSOLETE CORE_ADDR | |
274 | // OBSOLETE arc_skip_prologue (CORE_ADDR pc, int frameless_p) | |
275 | // OBSOLETE { | |
276 | // OBSOLETE unsigned int insn; | |
277 | // OBSOLETE int i, frame_size; | |
278 | // OBSOLETE | |
279 | // OBSOLETE if ((frame_size = arc_get_frame_setup (pc)) < 0) | |
280 | // OBSOLETE return (pc); | |
281 | // OBSOLETE | |
282 | // OBSOLETE if (frameless_p) | |
283 | // OBSOLETE return frame_size == 0 ? pc : codestream_tell (); | |
284 | // OBSOLETE | |
285 | // OBSOLETE /* Skip over register saves. */ | |
286 | // OBSOLETE for (i = 0; i < 8; i++) | |
287 | // OBSOLETE { | |
288 | // OBSOLETE insn = codestream_peek (); | |
289 | // OBSOLETE if ((insn & BUILD_INSN (-1, 0, -1, 0, 0)) | |
290 | // OBSOLETE != BUILD_INSN (2, 0, SP_REGNUM, 0, 0)) | |
291 | // OBSOLETE break; /* not st insn */ | |
292 | // OBSOLETE if (!ARC_CALL_SAVED_REG (X_C (insn))) | |
293 | // OBSOLETE break; | |
294 | // OBSOLETE codestream_get (); | |
295 | // OBSOLETE } | |
296 | // OBSOLETE | |
297 | // OBSOLETE return codestream_tell (); | |
298 | // OBSOLETE } | |
299 | // OBSOLETE | |
300 | // OBSOLETE /* Is the prologue at PC frameless? */ | |
301 | // OBSOLETE | |
302 | // OBSOLETE int | |
303 | // OBSOLETE arc_prologue_frameless_p (CORE_ADDR pc) | |
304 | // OBSOLETE { | |
305 | // OBSOLETE return (pc == arc_skip_prologue (pc, 1)); | |
306 | // OBSOLETE } | |
307 | // OBSOLETE | |
308 | // OBSOLETE /* Return the return address for a frame. | |
309 | // OBSOLETE This is used to implement FRAME_SAVED_PC. | |
310 | // OBSOLETE This is taken from frameless_look_for_prologue. */ | |
311 | // OBSOLETE | |
312 | // OBSOLETE CORE_ADDR | |
313 | // OBSOLETE arc_frame_saved_pc (struct frame_info *frame) | |
314 | // OBSOLETE { | |
315 | // OBSOLETE CORE_ADDR func_start; | |
316 | // OBSOLETE unsigned int insn; | |
317 | // OBSOLETE | |
318 | // OBSOLETE func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET; | |
319 | // OBSOLETE if (func_start == 0) | |
320 | // OBSOLETE { | |
321 | // OBSOLETE /* Best guess. */ | |
322 | // OBSOLETE return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4)); | |
323 | // OBSOLETE } | |
324 | // OBSOLETE | |
325 | // OBSOLETE /* The authority for what appears here is the home-grown ABI. | |
326 | // OBSOLETE The most recent version is 1.2. */ | |
327 | // OBSOLETE | |
328 | // OBSOLETE insn = setup_prologue_scan (func_start); | |
329 | // OBSOLETE | |
330 | // OBSOLETE /* First insn may be "sub sp,sp,N" if stdarg fn. */ | |
331 | // OBSOLETE if ((insn & BUILD_INSN (-1, -1, -1, -1, 0)) | |
332 | // OBSOLETE == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0)) | |
333 | // OBSOLETE insn = codestream_get (); | |
334 | // OBSOLETE | |
335 | // OBSOLETE /* If the next insn is "st blink,[sp,4]" we can get blink from there. | |
336 | // OBSOLETE Otherwise this is a leaf function and we can use blink. Note that | |
337 | // OBSOLETE this still allows for the case where a leaf function saves/clobbers/ | |
338 | // OBSOLETE restores blink. */ | |
339 | // OBSOLETE | |
340 | // OBSOLETE if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */ | |
341 | // OBSOLETE != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4)) | |
342 | // OBSOLETE return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM)); | |
343 | // OBSOLETE else | |
344 | // OBSOLETE return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4)); | |
345 | // OBSOLETE } | |
346 | // OBSOLETE | |
347 | // OBSOLETE /* | |
348 | // OBSOLETE * Parse the first few instructions of the function to see | |
349 | // OBSOLETE * what registers were stored. | |
350 | // OBSOLETE * | |
351 | // OBSOLETE * The startup sequence can be at the start of the function. | |
352 | // OBSOLETE * 'st blink,[sp+4], st fp,[sp], mov fp,sp' | |
353 | // OBSOLETE * | |
354 | // OBSOLETE * Local space is allocated just below by sub sp,sp,nnn. | |
355 | // OBSOLETE * Next, the registers used by this function are stored (as offsets from sp). | |
356 | // OBSOLETE */ | |
357 | // OBSOLETE | |
358 | // OBSOLETE void | |
359 | // OBSOLETE frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp) | |
360 | // OBSOLETE { | |
361 | // OBSOLETE long locals; | |
362 | // OBSOLETE unsigned int insn; | |
363 | // OBSOLETE CORE_ADDR dummy_bottom; | |
364 | // OBSOLETE CORE_ADDR adr; | |
365 | // OBSOLETE int i, regnum, offset; | |
366 | // OBSOLETE | |
367 | // OBSOLETE memset (fsrp, 0, sizeof *fsrp); | |
368 | // OBSOLETE | |
369 | // OBSOLETE /* If frame is the end of a dummy, compute where the beginning would be. */ | |
370 | // OBSOLETE dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH; | |
371 | // OBSOLETE | |
372 | // OBSOLETE /* Check if the PC is in the stack, in a dummy frame. */ | |
373 | // OBSOLETE if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) | |
374 | // OBSOLETE { | |
375 | // OBSOLETE /* all regs were saved by push_call_dummy () */ | |
376 | // OBSOLETE adr = fip->frame; | |
377 | // OBSOLETE for (i = 0; i < NUM_REGS; i++) | |
378 | // OBSOLETE { | |
379 | // OBSOLETE adr -= REGISTER_RAW_SIZE (i); | |
380 | // OBSOLETE fsrp->regs[i] = adr; | |
381 | // OBSOLETE } | |
382 | // OBSOLETE return; | |
383 | // OBSOLETE } | |
384 | // OBSOLETE | |
385 | // OBSOLETE locals = arc_get_frame_setup (get_pc_function_start (fip->pc)); | |
386 | // OBSOLETE | |
387 | // OBSOLETE if (locals >= 0) | |
388 | // OBSOLETE { | |
389 | // OBSOLETE /* Set `adr' to the value of `sp'. */ | |
390 | // OBSOLETE adr = fip->frame - locals; | |
391 | // OBSOLETE for (i = 0; i < 8; i++) | |
392 | // OBSOLETE { | |
393 | // OBSOLETE insn = codestream_get (); | |
394 | // OBSOLETE if ((insn & BUILD_INSN (-1, 0, -1, 0, 0)) | |
395 | // OBSOLETE != BUILD_INSN (2, 0, SP_REGNUM, 0, 0)) | |
396 | // OBSOLETE break; | |
397 | // OBSOLETE regnum = X_C (insn); | |
398 | // OBSOLETE offset = X_D (insn); | |
399 | // OBSOLETE fsrp->regs[regnum] = adr + offset; | |
400 | // OBSOLETE } | |
401 | // OBSOLETE } | |
402 | // OBSOLETE | |
403 | // OBSOLETE fsrp->regs[PC_REGNUM] = fip->frame + 4; | |
404 | // OBSOLETE fsrp->regs[FP_REGNUM] = fip->frame; | |
405 | // OBSOLETE } | |
406 | // OBSOLETE | |
407 | // OBSOLETE void | |
408 | // OBSOLETE arc_push_dummy_frame (void) | |
409 | // OBSOLETE { | |
410 | // OBSOLETE CORE_ADDR sp = read_register (SP_REGNUM); | |
411 | // OBSOLETE int regnum; | |
412 | // OBSOLETE char regbuf[MAX_REGISTER_RAW_SIZE]; | |
413 | // OBSOLETE | |
414 | // OBSOLETE read_register_gen (PC_REGNUM, regbuf); | |
415 | // OBSOLETE write_memory (sp + 4, regbuf, REGISTER_SIZE); | |
416 | // OBSOLETE read_register_gen (FP_REGNUM, regbuf); | |
417 | // OBSOLETE write_memory (sp, regbuf, REGISTER_SIZE); | |
418 | // OBSOLETE write_register (FP_REGNUM, sp); | |
419 | // OBSOLETE for (regnum = 0; regnum < NUM_REGS; regnum++) | |
420 | // OBSOLETE { | |
421 | // OBSOLETE read_register_gen (regnum, regbuf); | |
422 | // OBSOLETE sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum)); | |
423 | // OBSOLETE } | |
424 | // OBSOLETE sp += (2 * REGISTER_SIZE); | |
425 | // OBSOLETE write_register (SP_REGNUM, sp); | |
426 | // OBSOLETE } | |
427 | // OBSOLETE | |
428 | // OBSOLETE void | |
429 | // OBSOLETE arc_pop_frame (void) | |
430 | // OBSOLETE { | |
431 | // OBSOLETE struct frame_info *frame = get_current_frame (); | |
432 | // OBSOLETE CORE_ADDR fp; | |
433 | // OBSOLETE int regnum; | |
434 | // OBSOLETE struct frame_saved_regs fsr; | |
435 | // OBSOLETE char regbuf[MAX_REGISTER_RAW_SIZE]; | |
436 | // OBSOLETE | |
437 | // OBSOLETE fp = FRAME_FP (frame); | |
438 | // OBSOLETE get_frame_saved_regs (frame, &fsr); | |
439 | // OBSOLETE for (regnum = 0; regnum < NUM_REGS; regnum++) | |
440 | // OBSOLETE { | |
441 | // OBSOLETE CORE_ADDR adr; | |
442 | // OBSOLETE adr = fsr.regs[regnum]; | |
443 | // OBSOLETE if (adr) | |
444 | // OBSOLETE { | |
445 | // OBSOLETE read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum)); | |
446 | // OBSOLETE write_register_bytes (REGISTER_BYTE (regnum), regbuf, | |
447 | // OBSOLETE REGISTER_RAW_SIZE (regnum)); | |
448 | // OBSOLETE } | |
449 | // OBSOLETE } | |
450 | // OBSOLETE write_register (FP_REGNUM, read_memory_integer (fp, 4)); | |
451 | // OBSOLETE write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); | |
452 | // OBSOLETE write_register (SP_REGNUM, fp + 8); | |
453 | // OBSOLETE flush_cached_frames (); | |
454 | // OBSOLETE } | |
455 | // OBSOLETE \f | |
456 | // OBSOLETE /* Simulate single-step. */ | |
457 | // OBSOLETE | |
458 | // OBSOLETE typedef enum | |
459 | // OBSOLETE { | |
460 | // OBSOLETE NORMAL4, /* a normal 4 byte insn */ | |
461 | // OBSOLETE NORMAL8, /* a normal 8 byte insn */ | |
462 | // OBSOLETE BRANCH4, /* a 4 byte branch insn, including ones without delay slots */ | |
463 | // OBSOLETE BRANCH8, /* an 8 byte branch insn, including ones with delay slots */ | |
464 | // OBSOLETE } | |
465 | // OBSOLETE insn_type; | |
466 | // OBSOLETE | |
467 | // OBSOLETE /* Return the type of INSN and store in TARGET the destination address of a | |
468 | // OBSOLETE branch if this is one. */ | |
469 | // OBSOLETE /* ??? Need to verify all cases are properly handled. */ | |
470 | // OBSOLETE | |
471 | // OBSOLETE static insn_type | |
472 | // OBSOLETE get_insn_type (unsigned long insn, CORE_ADDR pc, CORE_ADDR *target) | |
473 | // OBSOLETE { | |
474 | // OBSOLETE unsigned long limm; | |
475 | // OBSOLETE | |
476 | // OBSOLETE switch (insn >> 27) | |
477 | // OBSOLETE { | |
478 | // OBSOLETE case 0: | |
479 | // OBSOLETE case 1: | |
480 | // OBSOLETE case 2: /* load/store insns */ | |
481 | // OBSOLETE if (LIMM_P (X_A (insn)) | |
482 | // OBSOLETE || LIMM_P (X_B (insn)) | |
483 | // OBSOLETE || LIMM_P (X_C (insn))) | |
484 | // OBSOLETE return NORMAL8; | |
485 | // OBSOLETE return NORMAL4; | |
486 | // OBSOLETE case 4: | |
487 | // OBSOLETE case 5: | |
488 | // OBSOLETE case 6: /* branch insns */ | |
489 | // OBSOLETE *target = pc + 4 + X_L (insn); | |
490 | // OBSOLETE /* ??? It isn't clear that this is always the right answer. | |
491 | // OBSOLETE The problem occurs when the next insn is an 8 byte insn. If the | |
492 | // OBSOLETE branch is conditional there's no worry as there shouldn't be an 8 | |
493 | // OBSOLETE byte insn following. The programmer may be cheating if s/he knows | |
494 | // OBSOLETE the branch will never be taken, but we don't deal with that. | |
495 | // OBSOLETE Note that the programmer is also allowed to play games by putting | |
496 | // OBSOLETE an insn with long immediate data in the delay slot and then duplicate | |
497 | // OBSOLETE the long immediate data at the branch target. Ugh! */ | |
498 | // OBSOLETE if (X_N (insn) == 0) | |
499 | // OBSOLETE return BRANCH4; | |
500 | // OBSOLETE return BRANCH8; | |
501 | // OBSOLETE case 7: /* jump insns */ | |
502 | // OBSOLETE if (LIMM_P (X_B (insn))) | |
503 | // OBSOLETE { | |
504 | // OBSOLETE limm = read_memory_integer (pc + 4, 4); | |
505 | // OBSOLETE *target = ARC_PC_TO_REAL_ADDRESS (limm); | |
506 | // OBSOLETE return BRANCH8; | |
507 | // OBSOLETE } | |
508 | // OBSOLETE if (SHIMM_P (X_B (insn))) | |
509 | // OBSOLETE *target = ARC_PC_TO_REAL_ADDRESS (X_D (insn)); | |
510 | // OBSOLETE else | |
511 | // OBSOLETE *target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn))); | |
512 | // OBSOLETE if (X_Q (insn) == 0 && X_N (insn) == 0) | |
513 | // OBSOLETE return BRANCH4; | |
514 | // OBSOLETE return BRANCH8; | |
515 | // OBSOLETE default: /* arithmetic insns, etc. */ | |
516 | // OBSOLETE if (LIMM_P (X_A (insn)) | |
517 | // OBSOLETE || LIMM_P (X_B (insn)) | |
518 | // OBSOLETE || LIMM_P (X_C (insn))) | |
519 | // OBSOLETE return NORMAL8; | |
520 | // OBSOLETE return NORMAL4; | |
521 | // OBSOLETE } | |
522 | // OBSOLETE } | |
523 | // OBSOLETE | |
524 | // OBSOLETE /* single_step() is called just before we want to resume the inferior, if we | |
525 | // OBSOLETE want to single-step it but there is no hardware or kernel single-step | |
526 | // OBSOLETE support. We find all the possible targets of the coming instruction and | |
527 | // OBSOLETE breakpoint them. | |
528 | // OBSOLETE | |
529 | // OBSOLETE single_step is also called just after the inferior stops. If we had | |
530 | // OBSOLETE set up a simulated single-step, we undo our damage. */ | |
531 | // OBSOLETE | |
532 | // OBSOLETE void | |
533 | // OBSOLETE arc_software_single_step (enum target_signal ignore, /* sig but we don't need it */ | |
534 | // OBSOLETE int insert_breakpoints_p) | |
535 | // OBSOLETE { | |
536 | // OBSOLETE static CORE_ADDR next_pc, target; | |
537 | // OBSOLETE static int brktrg_p; | |
538 | // OBSOLETE typedef char binsn_quantum[BREAKPOINT_MAX]; | |
539 | // OBSOLETE static binsn_quantum break_mem[2]; | |
540 | // OBSOLETE | |
541 | // OBSOLETE if (insert_breakpoints_p) | |
542 | // OBSOLETE { | |
543 | // OBSOLETE insn_type type; | |
544 | // OBSOLETE CORE_ADDR pc; | |
545 | // OBSOLETE unsigned long insn; | |
546 | // OBSOLETE | |
547 | // OBSOLETE pc = read_register (PC_REGNUM); | |
548 | // OBSOLETE insn = read_memory_integer (pc, 4); | |
549 | // OBSOLETE type = get_insn_type (insn, pc, &target); | |
550 | // OBSOLETE | |
551 | // OBSOLETE /* Always set a breakpoint for the insn after the branch. */ | |
552 | // OBSOLETE next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4); | |
553 | // OBSOLETE target_insert_breakpoint (next_pc, break_mem[0]); | |
554 | // OBSOLETE | |
555 | // OBSOLETE brktrg_p = 0; | |
556 | // OBSOLETE | |
557 | // OBSOLETE if ((type == BRANCH4 || type == BRANCH8) | |
558 | // OBSOLETE /* Watch out for branches to the following location. | |
559 | // OBSOLETE We just stored a breakpoint there and another call to | |
560 | // OBSOLETE target_insert_breakpoint will think the real insn is the | |
561 | // OBSOLETE breakpoint we just stored there. */ | |
562 | // OBSOLETE && target != next_pc) | |
563 | // OBSOLETE { | |
564 | // OBSOLETE brktrg_p = 1; | |
565 | // OBSOLETE target_insert_breakpoint (target, break_mem[1]); | |
566 | // OBSOLETE } | |
567 | // OBSOLETE | |
568 | // OBSOLETE } | |
569 | // OBSOLETE else | |
570 | // OBSOLETE { | |
571 | // OBSOLETE /* Remove breakpoints. */ | |
572 | // OBSOLETE target_remove_breakpoint (next_pc, break_mem[0]); | |
573 | // OBSOLETE | |
574 | // OBSOLETE if (brktrg_p) | |
575 | // OBSOLETE target_remove_breakpoint (target, break_mem[1]); | |
576 | // OBSOLETE | |
577 | // OBSOLETE /* Fix the pc. */ | |
578 | // OBSOLETE stop_pc -= DECR_PC_AFTER_BREAK; | |
579 | // OBSOLETE write_pc (stop_pc); | |
580 | // OBSOLETE } | |
581 | // OBSOLETE } | |
582 | // OBSOLETE \f | |
583 | // OBSOLETE /* Because of Multi-arch, GET_LONGJMP_TARGET is always defined. So test | |
584 | // OBSOLETE for a definition of JB_PC. */ | |
585 | // OBSOLETE #ifdef JB_PC | |
586 | // OBSOLETE /* Figure out where the longjmp will land. Slurp the args out of the stack. | |
587 | // OBSOLETE We expect the first arg to be a pointer to the jmp_buf structure from which | |
588 | // OBSOLETE we extract the pc (JB_PC) that we will land at. The pc is copied into PC. | |
589 | // OBSOLETE This routine returns true on success. */ | |
590 | // OBSOLETE | |
591 | // OBSOLETE int | |
592 | // OBSOLETE get_longjmp_target (CORE_ADDR *pc) | |
593 | // OBSOLETE { | |
594 | // OBSOLETE char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; | |
595 | // OBSOLETE CORE_ADDR sp, jb_addr; | |
596 | // OBSOLETE | |
597 | // OBSOLETE sp = read_register (SP_REGNUM); | |
598 | // OBSOLETE | |
599 | // OBSOLETE if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */ | |
600 | // OBSOLETE buf, | |
601 | // OBSOLETE TARGET_PTR_BIT / TARGET_CHAR_BIT)) | |
602 | // OBSOLETE return 0; | |
603 | // OBSOLETE | |
604 | // OBSOLETE jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); | |
605 | // OBSOLETE | |
606 | // OBSOLETE if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, | |
607 | // OBSOLETE TARGET_PTR_BIT / TARGET_CHAR_BIT)) | |
608 | // OBSOLETE return 0; | |
609 | // OBSOLETE | |
610 | // OBSOLETE *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); | |
611 | // OBSOLETE | |
612 | // OBSOLETE return 1; | |
613 | // OBSOLETE } | |
614 | // OBSOLETE #endif /* GET_LONGJMP_TARGET */ | |
615 | // OBSOLETE \f | |
616 | // OBSOLETE /* Disassemble one instruction. */ | |
617 | // OBSOLETE | |
618 | // OBSOLETE static int | |
619 | // OBSOLETE arc_print_insn (bfd_vma vma, disassemble_info *info) | |
620 | // OBSOLETE { | |
621 | // OBSOLETE static int current_mach; | |
622 | // OBSOLETE static int current_endian; | |
623 | // OBSOLETE static disassembler_ftype current_disasm; | |
624 | // OBSOLETE | |
625 | // OBSOLETE if (current_disasm == NULL | |
626 | // OBSOLETE || arc_bfd_mach_type != current_mach | |
627 | // OBSOLETE || TARGET_BYTE_ORDER != current_endian) | |
628 | // OBSOLETE { | |
629 | // OBSOLETE current_mach = arc_bfd_mach_type; | |
630 | // OBSOLETE current_endian = TARGET_BYTE_ORDER; | |
631 | // OBSOLETE current_disasm = arc_get_disassembler (NULL); | |
632 | // OBSOLETE } | |
633 | // OBSOLETE | |
634 | // OBSOLETE return (*current_disasm) (vma, info); | |
635 | // OBSOLETE } | |
636 | // OBSOLETE \f | |
637 | // OBSOLETE /* Command to set cpu type. */ | |
638 | // OBSOLETE | |
639 | // OBSOLETE void | |
640 | // OBSOLETE arc_set_cpu_type_command (char *args, int from_tty) | |
641 | // OBSOLETE { | |
642 | // OBSOLETE int i; | |
643 | // OBSOLETE | |
644 | // OBSOLETE if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0') | |
645 | // OBSOLETE { | |
646 | // OBSOLETE printf_unfiltered ("The known ARC cpu types are as follows:\n"); | |
647 | // OBSOLETE for (i = 0; arc_cpu_type_table[i].name != NULL; ++i) | |
648 | // OBSOLETE printf_unfiltered ("%s\n", arc_cpu_type_table[i].name); | |
649 | // OBSOLETE | |
650 | // OBSOLETE /* Restore the value. */ | |
651 | // OBSOLETE tmp_arc_cpu_type = xstrdup (arc_cpu_type); | |
652 | // OBSOLETE | |
653 | // OBSOLETE return; | |
654 | // OBSOLETE } | |
655 | // OBSOLETE | |
656 | // OBSOLETE if (!arc_set_cpu_type (tmp_arc_cpu_type)) | |
657 | // OBSOLETE { | |
658 | // OBSOLETE error ("Unknown cpu type `%s'.", tmp_arc_cpu_type); | |
659 | // OBSOLETE /* Restore its value. */ | |
660 | // OBSOLETE tmp_arc_cpu_type = xstrdup (arc_cpu_type); | |
661 | // OBSOLETE } | |
662 | // OBSOLETE } | |
663 | // OBSOLETE | |
664 | // OBSOLETE static void | |
665 | // OBSOLETE arc_show_cpu_type_command (char *args, int from_tty) | |
666 | // OBSOLETE { | |
667 | // OBSOLETE } | |
668 | // OBSOLETE | |
669 | // OBSOLETE /* Modify the actual cpu type. | |
670 | // OBSOLETE Result is a boolean indicating success. */ | |
671 | // OBSOLETE | |
672 | // OBSOLETE static int | |
673 | // OBSOLETE arc_set_cpu_type (char *str) | |
674 | // OBSOLETE { | |
675 | // OBSOLETE int i, j; | |
676 | // OBSOLETE | |
677 | // OBSOLETE if (str == NULL) | |
678 | // OBSOLETE return 0; | |
679 | // OBSOLETE | |
680 | // OBSOLETE for (i = 0; arc_cpu_type_table[i].name != NULL; ++i) | |
681 | // OBSOLETE { | |
682 | // OBSOLETE if (strcasecmp (str, arc_cpu_type_table[i].name) == 0) | |
683 | // OBSOLETE { | |
684 | // OBSOLETE arc_cpu_type = str; | |
685 | // OBSOLETE arc_bfd_mach_type = arc_cpu_type_table[i].value; | |
686 | // OBSOLETE return 1; | |
687 | // OBSOLETE } | |
688 | // OBSOLETE } | |
689 | // OBSOLETE | |
690 | // OBSOLETE return 0; | |
691 | // OBSOLETE } | |
692 | // OBSOLETE \f | |
693 | // OBSOLETE void | |
694 | // OBSOLETE _initialize_arc_tdep (void) | |
695 | // OBSOLETE { | |
696 | // OBSOLETE struct cmd_list_element *c; | |
697 | // OBSOLETE | |
698 | // OBSOLETE c = add_set_cmd ("cpu", class_support, var_string_noescape, | |
699 | // OBSOLETE (char *) &tmp_arc_cpu_type, | |
700 | // OBSOLETE "Set the type of ARC cpu in use.\n\ | |
701 | // OBSOLETE This command has two purposes. In a multi-cpu system it lets one\n\ | |
702 | // OBSOLETE change the cpu being debugged. It also gives one access to\n\ | |
703 | // OBSOLETE cpu-type-specific registers and recognize cpu-type-specific instructions.\ | |
704 | // OBSOLETE ", | |
705 | // OBSOLETE &setlist); | |
706 | // OBSOLETE set_cmd_cfunc (c, arc_set_cpu_type_command); | |
707 | // OBSOLETE c = add_show_from_set (c, &showlist); | |
708 | // OBSOLETE set_cmd_cfunc (c, arc_show_cpu_type_command); | |
709 | // OBSOLETE | |
710 | // OBSOLETE /* We have to use xstrdup() here because the `set' command frees it | |
711 | // OBSOLETE before setting a new value. */ | |
712 | // OBSOLETE tmp_arc_cpu_type = xstrdup (DEFAULT_ARC_CPU_TYPE); | |
713 | // OBSOLETE arc_set_cpu_type (tmp_arc_cpu_type); | |
714 | // OBSOLETE | |
715 | // OBSOLETE c = add_set_cmd ("displaypipeline", class_support, var_zinteger, | |
716 | // OBSOLETE (char *) &display_pipeline_p, | |
717 | // OBSOLETE "Set pipeline display (simulator only).\n\ | |
718 | // OBSOLETE When enabled, the state of the pipeline after each cycle is displayed.", | |
719 | // OBSOLETE &setlist); | |
720 | // OBSOLETE c = add_show_from_set (c, &showlist); | |
721 | // OBSOLETE | |
722 | // OBSOLETE c = add_set_cmd ("debugpipeline", class_support, var_zinteger, | |
723 | // OBSOLETE (char *) &debug_pipeline_p, | |
724 | // OBSOLETE "Set pipeline debug display (simulator only).\n\ | |
725 | // OBSOLETE When enabled, debugging information about the pipeline is displayed.", | |
726 | // OBSOLETE &setlist); | |
727 | // OBSOLETE c = add_show_from_set (c, &showlist); | |
728 | // OBSOLETE | |
729 | // OBSOLETE c = add_set_cmd ("cputimer", class_support, var_zinteger, | |
730 | // OBSOLETE (char *) &cpu_timer, | |
731 | // OBSOLETE "Set maximum cycle count (simulator only).\n\ | |
732 | // OBSOLETE Control will return to gdb if the timer expires.\n\ | |
733 | // OBSOLETE A negative value disables the timer.", | |
734 | // OBSOLETE &setlist); | |
735 | // OBSOLETE c = add_show_from_set (c, &showlist); | |
736 | // OBSOLETE | |
737 | // OBSOLETE tm_print_insn = arc_print_insn; | |
738 | // OBSOLETE } |