Commit | Line | Data |
---|---|---|
5198e746 | 1 | /* Target-dependent code for the Fujitsu FR30. |
17139ec5 ZR |
2 | Copyright 1996, Free Software Foundation, Inc. |
3 | ||
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "frame.h" | |
22 | #include "inferior.h" | |
23 | #include "obstack.h" | |
24 | #include "target.h" | |
25 | #include "value.h" | |
26 | #include "bfd.h" | |
27 | #include "gdb_string.h" | |
28 | #include "gdbcore.h" | |
29 | #include "symfile.h" | |
30 | ||
492eae09 | 31 | __t(int l, char *s, int a) |
17139ec5 | 32 | { |
492eae09 | 33 | fprintf(stderr, "(%d): %s: 0x%08x\n", l, s, a); |
17139ec5 | 34 | } |
492eae09 | 35 | #define T(s, a) __t(__LINE__, s, (int)(a)) |
17139ec5 | 36 | |
5198e746 ZR |
37 | /* Function: pop_frame |
38 | This routine gets called when either the user uses the `return' | |
39 | command, or the call dummy breakpoint gets hit. */ | |
40 | ||
17139ec5 | 41 | void |
5198e746 | 42 | fr30_pop_frame () |
17139ec5 | 43 | { |
5198e746 ZR |
44 | struct frame_info *frame = get_current_frame(); |
45 | int regnum; | |
17139ec5 | 46 | |
5198e746 ZR |
47 | if (PC_IN_CALL_DUMMY(frame->pc, frame->frame, frame->frame)) |
48 | generic_pop_dummy_frame (); | |
49 | else | |
50 | { | |
51 | write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); | |
17139ec5 | 52 | |
5198e746 ZR |
53 | for (regnum = 0; regnum < NUM_REGS; regnum++) |
54 | if (frame->fsr.regs[regnum] != 0) | |
55 | write_register (regnum, | |
56 | read_memory_unsigned_integer (frame->fsr.regs[regnum], | |
57 | REGISTER_RAW_SIZE(regnum))); | |
58 | ||
e53f7058 | 59 | write_register (SP_REGNUM, read_register (frame->framereg)); |
5198e746 ZR |
60 | } |
61 | ||
62 | flush_cached_frames (); | |
17139ec5 ZR |
63 | } |
64 | ||
5198e746 ZR |
65 | /* Function: skip_prologue |
66 | Return the address of the first code past the prologue of the function. */ | |
67 | ||
17139ec5 ZR |
68 | CORE_ADDR |
69 | fr30_skip_prologue(CORE_ADDR pc) | |
70 | { | |
5198e746 ZR |
71 | CORE_ADDR func_addr, func_end; |
72 | ||
73 | /* See what the symbol table says */ | |
74 | ||
75 | if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) | |
76 | { | |
77 | struct symtab_and_line sal; | |
78 | ||
79 | sal = find_pc_line (func_addr, 0); | |
80 | ||
492eae09 | 81 | if (sal.line != 0 && sal.end < func_end) { |
5198e746 | 82 | return sal.end; |
492eae09 | 83 | } |
5198e746 ZR |
84 | } |
85 | ||
86 | /* Either we didn't find the start of this function (nothing we can do), | |
87 | or there's no line info, or the line after the prologue is after | |
88 | the end of the function (there probably isn't a prologue). */ | |
89 | ||
90 | return pc; | |
17139ec5 ZR |
91 | } |
92 | ||
93 | ||
94 | CORE_ADDR | |
95 | fr30_push_arguments(nargs, args, sp, struct_return, struct_addr) | |
96 | int nargs; | |
97 | value_ptr * args; | |
98 | CORE_ADDR sp; | |
99 | int struct_return; | |
100 | CORE_ADDR struct_addr; | |
101 | { | |
102 | int argreg; | |
103 | int argnum; | |
104 | int stack_offset; | |
105 | struct stack_arg { | |
106 | char *val; | |
107 | int len; | |
108 | int offset; | |
109 | }; | |
110 | struct stack_arg *stack_args = | |
111 | (struct stack_arg*)alloca (nargs * sizeof (struct stack_arg)); | |
112 | int nstack_args = 0; | |
113 | ||
17139ec5 ZR |
114 | argreg = FIRST_ARGREG; |
115 | ||
116 | /* the struct_return pointer occupies the first parameter-passing reg */ | |
117 | if (struct_return) | |
118 | write_register (argreg++, struct_addr); | |
119 | ||
120 | #if(0) | |
121 | /* The offset onto the stack at which we will start copying parameters | |
122 | (after the registers are used up) begins at 16 in the old ABI. | |
123 | This leaves room for the "home" area for register parameters. */ | |
124 | stack_offset = REGISTER_SIZE * 4; | |
125 | #else | |
126 | /* XXX which ABI are we using ? Z.R. */ | |
127 | stack_offset = 0; | |
128 | #endif | |
129 | ||
130 | /* Process args from left to right. Store as many as allowed in | |
131 | registers, save the rest to be pushed on the stack */ | |
132 | for(argnum = 0; argnum < nargs; argnum++) | |
133 | { | |
134 | char * val; | |
135 | value_ptr arg = args[argnum]; | |
136 | struct type * arg_type = check_typedef (VALUE_TYPE (arg)); | |
137 | struct type * target_type = TYPE_TARGET_TYPE (arg_type); | |
138 | int len = TYPE_LENGTH (arg_type); | |
139 | enum type_code typecode = TYPE_CODE (arg_type); | |
140 | CORE_ADDR regval; | |
141 | int newarg; | |
142 | ||
143 | val = (char *) VALUE_CONTENTS (arg); | |
144 | ||
145 | { | |
146 | /* Copy the argument to general registers or the stack in | |
147 | register-sized pieces. Large arguments are split between | |
148 | registers and stack. */ | |
149 | while (len > 0) | |
150 | { | |
151 | if (argreg <= LAST_ARGREG) | |
152 | { | |
153 | int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; | |
154 | regval = extract_address (val, partial_len); | |
155 | ||
156 | /* It's a simple argument being passed in a general | |
157 | register. */ | |
158 | write_register (argreg, regval); | |
159 | argreg++; | |
160 | len -= partial_len; | |
161 | val += partial_len; | |
162 | } | |
163 | else | |
164 | { | |
165 | /* keep for later pushing */ | |
166 | stack_args[nstack_args].val = val; | |
167 | stack_args[nstack_args++].len = len; | |
168 | break; | |
169 | } | |
170 | } | |
171 | } | |
172 | } | |
173 | /* now do the real stack pushing, process args right to left */ | |
174 | while(nstack_args--) | |
175 | { | |
176 | sp -= stack_args[nstack_args].len; | |
177 | write_memory(sp, stack_args[nstack_args].val, | |
178 | stack_args[nstack_args].len); | |
179 | } | |
180 | ||
181 | /* Return adjusted stack pointer. */ | |
182 | return sp; | |
183 | } | |
184 | ||
185 | _initialize_fr30_tdep() | |
186 | { | |
187 | extern int print_insn_fr30(bfd_vma, disassemble_info *); | |
188 | ||
189 | tm_print_insn = print_insn_fr30; | |
190 | } | |
191 | ||
492eae09 ZR |
192 | /* Function: check_prologue_cache |
193 | Check if prologue for this frame's PC has already been scanned. | |
194 | If it has, copy the relevant information about that prologue and | |
195 | return non-zero. Otherwise do not copy anything and return zero. | |
196 | ||
197 | The information saved in the cache includes: | |
198 | * the frame register number; | |
199 | * the size of the stack frame; | |
200 | * the offsets of saved regs (relative to the old SP); and | |
201 | * the offset from the stack pointer to the frame pointer | |
202 | ||
203 | The cache contains only one entry, since this is adequate | |
204 | for the typical sequence of prologue scan requests we get. | |
205 | When performing a backtrace, GDB will usually ask to scan | |
206 | the same function twice in a row (once to get the frame chain, | |
207 | and once to fill in the extra frame information). | |
208 | */ | |
209 | ||
210 | static struct frame_info prologue_cache; | |
211 | ||
212 | static int | |
213 | check_prologue_cache (fi) | |
214 | struct frame_info * fi; | |
215 | { | |
216 | int i; | |
217 | ||
218 | if (fi->pc == prologue_cache.pc) | |
219 | { | |
220 | fi->framereg = prologue_cache.framereg; | |
221 | fi->framesize = prologue_cache.framesize; | |
222 | fi->frameoffset = prologue_cache.frameoffset; | |
223 | for (i = 0; i <= NUM_REGS; i++) | |
224 | fi->fsr.regs[i] = prologue_cache.fsr.regs[i]; | |
225 | return 1; | |
226 | } | |
227 | else | |
228 | return 0; | |
229 | } | |
17139ec5 | 230 | |
17139ec5 | 231 | |
492eae09 ZR |
232 | /* Function: save_prologue_cache |
233 | Copy the prologue information from fi to the prologue cache. | |
234 | */ | |
17139ec5 | 235 | |
492eae09 ZR |
236 | static void |
237 | save_prologue_cache (fi) | |
238 | struct frame_info * fi; | |
17139ec5 | 239 | { |
492eae09 ZR |
240 | int i; |
241 | ||
242 | prologue_cache.pc = fi->pc; | |
243 | prologue_cache.framereg = fi->framereg; | |
244 | prologue_cache.framesize = fi->framesize; | |
245 | prologue_cache.frameoffset = fi->frameoffset; | |
246 | ||
247 | for (i = 0; i <= NUM_REGS; i++) | |
248 | prologue_cache.fsr.regs[i] = fi->fsr.regs[i]; | |
249 | } | |
250 | ||
251 | ||
17139ec5 ZR |
252 | /* Function: scan_prologue |
253 | Scan the prologue of the function that contains PC, and record what | |
254 | we find in PI. PI->fsr must be zeroed by the called. Returns the | |
255 | pc after the prologue. Note that the addresses saved in pi->fsr | |
256 | are actually just frame relative (negative offsets from the frame | |
257 | pointer). This is because we don't know the actual value of the | |
258 | frame pointer yet. In some circumstances, the frame pointer can't | |
259 | be determined till after we have scanned the prologue. */ | |
260 | ||
492eae09 ZR |
261 | static void |
262 | fr30_scan_prologue (fi) | |
263 | struct frame_info * fi; | |
17139ec5 | 264 | { |
492eae09 ZR |
265 | int sp_offset, fp_offset; |
266 | CORE_ADDR prologue_start, prologue_end, current_pc; | |
17139ec5 | 267 | |
492eae09 ZR |
268 | /* Check if this function is already in the cache of frame information. */ |
269 | if (check_prologue_cache (fi)) | |
270 | return; | |
17139ec5 | 271 | |
492eae09 ZR |
272 | /* Assume there is no frame until proven otherwise. */ |
273 | fi->framereg = SP_REGNUM; | |
274 | fi->framesize = 0; | |
275 | fi->frameoffset = 0; | |
17139ec5 | 276 | |
492eae09 ZR |
277 | /* Find the function prologue. If we can't find the function in |
278 | the symbol table, peek in the stack frame to find the PC. */ | |
279 | if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) | |
280 | { | |
281 | /* Assume the prologue is everything between the first instruction | |
282 | in the function and the first source line. */ | |
283 | struct symtab_and_line sal = find_pc_line (prologue_start, 0); | |
284 | ||
285 | if (sal.line == 0) /* no line info, use current PC */ | |
286 | prologue_end = fi->pc; | |
287 | else if (sal.end < prologue_end) /* next line begins after fn end */ | |
288 | prologue_end = sal.end; /* (probably means no prologue) */ | |
17139ec5 ZR |
289 | } |
290 | else | |
492eae09 ZR |
291 | { |
292 | T("NIY", 0); | |
293 | /* XXX ??? Z.R. Get address of the stmfd in the prologue of the callee; the saved | |
294 | PC is the address of the stmfd + 12. */ | |
295 | prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12; | |
296 | prologue_end = prologue_start + 40; /* FIXME: should be big enough */ | |
17139ec5 ZR |
297 | } |
298 | ||
492eae09 ZR |
299 | /* Now search the prologue looking for instructions that set up the |
300 | frame pointer, adjust the stack pointer, and save registers. */ | |
17139ec5 | 301 | |
492eae09 ZR |
302 | sp_offset = fp_offset = 0; |
303 | for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2) | |
17139ec5 | 304 | { |
492eae09 | 305 | unsigned int insn; |
17139ec5 ZR |
306 | |
307 | insn = read_memory_unsigned_integer (current_pc, 2); | |
308 | ||
492eae09 ZR |
309 | if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */ |
310 | { | |
311 | int reg, mask = insn & 0xff; | |
312 | ||
313 | /* scan in one sweep - create virtual 16-bit mask from either insn's mask */ | |
314 | if((insn & 0x0100) == 0) | |
315 | { | |
316 | mask <<= 8; /* stm0 - move to upper byte in virtual mask */ | |
317 | } | |
318 | ||
319 | /* Calculate offsets of saved registers (to be turned later into addresses). */ | |
320 | for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++) | |
321 | if (mask & (1 << (15 - reg))) | |
322 | { | |
323 | sp_offset -= 4; | |
324 | fi->fsr.regs[reg] = sp_offset; | |
325 | } | |
17139ec5 | 326 | } |
492eae09 ZR |
327 | else if((insn & 0xff00) == 0x0f00) /* enter */ |
328 | { | |
329 | fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4; | |
330 | sp_offset -= 4 * (insn & 0xff); | |
331 | fi->framereg = FP_REGNUM; | |
17139ec5 | 332 | } |
492eae09 | 333 | else if(insn == 0x1781) /* st rp,@-sp */ |
17139ec5 | 334 | { |
492eae09 ZR |
335 | sp_offset -= 4; |
336 | fi->fsr.regs[RP_REGNUM] = sp_offset; | |
17139ec5 | 337 | } |
492eae09 | 338 | else if(insn == 0x170e) /* st fp,@-sp */ |
17139ec5 | 339 | { |
492eae09 ZR |
340 | sp_offset -= 4; |
341 | fi->fsr.regs[FP_REGNUM] = sp_offset; | |
17139ec5 | 342 | } |
492eae09 | 343 | else if(insn == 0x8bfe) /* mov sp,fp */ |
17139ec5 | 344 | { |
492eae09 | 345 | fi->framereg = FP_REGNUM; |
17139ec5 | 346 | } |
492eae09 | 347 | else if((insn & 0xff00) == 0xa300) /* addsp xx */ |
17139ec5 | 348 | { |
492eae09 ZR |
349 | sp_offset += 4 * (signed char)(insn & 0xff); |
350 | } | |
351 | else if((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */ | |
352 | read_memory_unsigned_integer(current_pc+4, 2) | |
353 | == 0xac0f) /* sub r0,sp */ | |
354 | { | |
355 | /* large stack adjustment */ | |
356 | sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer(current_pc+2, 2)); | |
357 | current_pc += 4; | |
358 | } | |
359 | else if(insn == 0x9f80 && /* ldi:32 xx,r0 */ | |
360 | read_memory_unsigned_integer(current_pc+6, 2) | |
361 | == 0xac0f) /* sub r0,sp */ | |
362 | { | |
363 | /* large stack adjustment */ | |
364 | sp_offset -= | |
365 | (read_memory_unsigned_integer(current_pc+2, 2) << 16 | | |
366 | read_memory_unsigned_integer(current_pc+4, 2)); | |
367 | current_pc += 6; | |
17139ec5 | 368 | } |
17139ec5 ZR |
369 | } |
370 | ||
492eae09 ZR |
371 | /* The frame size is just the negative of the offset (from the original SP) |
372 | of the last thing thing we pushed on the stack. The frame offset is | |
373 | [new FP] - [new SP]. */ | |
374 | fi->framesize = -sp_offset; | |
375 | fi->frameoffset = fp_offset - sp_offset; | |
376 | ||
377 | save_prologue_cache (fi); | |
17139ec5 ZR |
378 | } |
379 | ||
380 | /* Function: init_extra_frame_info | |
381 | Setup the frame's frame pointer, pc, and frame addresses for saved | |
382 | registers. Most of the work is done in scan_prologue(). | |
383 | ||
384 | Note that when we are called for the last frame (currently active frame), | |
385 | that fi->pc and fi->frame will already be setup. However, fi->frame will | |
386 | be valid only if this routine uses FP. For previous frames, fi-frame will | |
5198e746 | 387 | always be correct (since that is derived from fr30_frame_chain ()). |
17139ec5 ZR |
388 | |
389 | We can be called with the PC in the call dummy under two circumstances. | |
390 | First, during normal backtracing, second, while figuring out the frame | |
391 | pointer just prior to calling the target function (see run_stack_dummy). */ | |
392 | ||
393 | void | |
5198e746 | 394 | fr30_init_extra_frame_info (fi) |
492eae09 | 395 | struct frame_info * fi; |
17139ec5 | 396 | { |
17139ec5 ZR |
397 | int reg; |
398 | ||
399 | if (fi->next) | |
400 | fi->pc = FRAME_SAVED_PC (fi->next); | |
401 | ||
402 | memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); | |
403 | ||
17139ec5 | 404 | if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) |
17139ec5 | 405 | { |
492eae09 ZR |
406 | /* We need to setup fi->frame here because run_stack_dummy gets it wrong |
407 | by assuming it's always FP. */ | |
408 | fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); | |
409 | fi->framesize = 0; | |
410 | fi->frameoffset = 0; | |
411 | return; | |
17139ec5 | 412 | } |
492eae09 ZR |
413 | fr30_scan_prologue (fi); |
414 | ||
415 | if (!fi->next) /* this is the innermost frame? */ | |
416 | fi->frame = read_register (fi->framereg); | |
417 | else /* not the innermost frame */ | |
418 | /* If we have an FP, the callee saved it. */ | |
419 | if (fi->framereg == FP_REGNUM) | |
420 | if (fi->next->fsr.regs[fi->framereg] != 0) | |
421 | fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg], | |
422 | 4); | |
423 | ||
424 | /* Calculate actual addresses of saved registers using offsets determined | |
425 | by fr30_scan_prologue. */ | |
426 | for (reg = 0; reg < NUM_REGS; reg++) | |
427 | if (fi->fsr.regs[reg] != 0) | |
428 | fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset; | |
17139ec5 ZR |
429 | } |
430 | ||
17139ec5 ZR |
431 | /* Function: find_callers_reg |
432 | Find REGNUM on the stack. Otherwise, it's in an active register. | |
433 | One thing we might want to do here is to check REGNUM against the | |
434 | clobber mask, and somehow flag it as invalid if it isn't saved on | |
435 | the stack somewhere. This would provide a graceful failure mode | |
436 | when trying to get the value of caller-saves registers for an inner | |
437 | frame. */ | |
438 | ||
439 | CORE_ADDR | |
5198e746 | 440 | fr30_find_callers_reg (fi, regnum) |
17139ec5 ZR |
441 | struct frame_info *fi; |
442 | int regnum; | |
443 | { | |
444 | for (; fi; fi = fi->next) | |
445 | if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) | |
446 | return generic_read_register_dummy (fi->pc, fi->frame, regnum); | |
447 | else if (fi->fsr.regs[regnum] != 0) | |
448 | return read_memory_unsigned_integer (fi->fsr.regs[regnum], | |
449 | REGISTER_RAW_SIZE(regnum)); | |
450 | ||
451 | return read_register (regnum); | |
452 | } | |
453 | ||
5198e746 ZR |
454 | |
455 | /* Function: frame_chain | |
456 | Figure out the frame prior to FI. Unfortunately, this involves | |
457 | scanning the prologue of the caller, which will also be done | |
458 | shortly by fr30_init_extra_frame_info. For the dummy frame, we | |
459 | just return the stack pointer that was in use at the time the | |
460 | function call was made. */ | |
17139ec5 | 461 | |
492eae09 | 462 | |
17139ec5 | 463 | CORE_ADDR |
5198e746 | 464 | fr30_frame_chain (fi) |
492eae09 | 465 | struct frame_info * fi; |
17139ec5 | 466 | { |
492eae09 ZR |
467 | CORE_ADDR fn_start, callers_pc, fp; |
468 | struct frame_info caller_fi; | |
469 | int framereg; | |
17139ec5 | 470 | |
492eae09 ZR |
471 | /* is this a dummy frame? */ |
472 | if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) | |
473 | return fi->frame; /* dummy frame same as caller's frame */ | |
474 | ||
475 | /* is caller-of-this a dummy frame? */ | |
476 | callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */ | |
5198e746 | 477 | fp = fr30_find_callers_reg (fi, FP_REGNUM); |
492eae09 ZR |
478 | if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) |
479 | return fp; /* dummy frame's frame may bear no relation to ours */ | |
17139ec5 | 480 | |
492eae09 ZR |
481 | if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) |
482 | if (fn_start == entry_point_address ()) | |
483 | return 0; /* in _start fn, don't chain further */ | |
17139ec5 | 484 | |
492eae09 | 485 | framereg = fi->framereg; |
17139ec5 | 486 | |
492eae09 ZR |
487 | /* If the caller is the startup code, we're at the end of the chain. */ |
488 | if (find_pc_partial_function (callers_pc, 0, &fn_start, 0)) | |
489 | if (fn_start == entry_point_address ()) | |
490 | return 0; | |
17139ec5 | 491 | |
492eae09 ZR |
492 | memset (& caller_fi, 0, sizeof (caller_fi)); |
493 | caller_fi.pc = callers_pc; | |
494 | fr30_scan_prologue (& caller_fi); | |
495 | framereg = caller_fi.framereg; | |
17139ec5 | 496 | |
492eae09 ZR |
497 | /* If the caller used a frame register, return its value. |
498 | Otherwise, return the caller's stack pointer. */ | |
499 | if (framereg == FP_REGNUM) | |
500 | return fr30_find_callers_reg (fi, framereg); | |
501 | else | |
502 | return fi->frame + fi->framesize; | |
17139ec5 | 503 | } |
492eae09 | 504 | |
17139ec5 ZR |
505 | /* Function: push_arguments |
506 | Setup arguments and RP for a call to the target. First four args | |
492eae09 | 507 | go in R4->R7, subsequent args go on stack... Structs |
17139ec5 ZR |
508 | are passed by reference. 64 bit quantities (doubles and long |
509 | longs) may be split between the regs and the stack. When calling a | |
510 | function that returns a struct, a pointer to the struct is passed | |
511 | in as a secret first argument (always in R6). | |
512 | ||
513 | Stack space for the args has NOT been allocated: that job is up to us. | |
514 | */ | |
515 | ||
5198e746 | 516 | #if(0) /* Z.R. XXX */ |
17139ec5 | 517 | CORE_ADDR |
5198e746 | 518 | fr30_push_arguments (nargs, args, sp, struct_return, struct_addr) |
17139ec5 ZR |
519 | int nargs; |
520 | value_ptr *args; | |
521 | CORE_ADDR sp; | |
522 | unsigned char struct_return; | |
523 | CORE_ADDR struct_addr; | |
524 | { | |
525 | int argreg; | |
526 | int argnum; | |
527 | int len = 0; | |
528 | int stack_offset; | |
529 | ||
530 | /* First, just for safety, make sure stack is aligned */ | |
531 | sp &= ~3; | |
532 | ||
533 | /* Now make space on the stack for the args. */ | |
534 | for (argnum = 0; argnum < nargs; argnum++) | |
535 | len += ((TYPE_LENGTH(VALUE_TYPE(args[argnum])) + 3) & ~3); | |
536 | sp -= len; /* possibly over-allocating, but it works... */ | |
537 | /* (you might think we could allocate 16 bytes */ | |
538 | /* less, but the ABI seems to use it all! ) */ | |
539 | argreg = ARG0_REGNUM; | |
540 | ||
541 | /* the struct_return pointer occupies the first parameter-passing reg */ | |
542 | if (struct_return) | |
543 | write_register (argreg++, struct_addr); | |
544 | ||
545 | stack_offset = 16; | |
546 | /* The offset onto the stack at which we will start copying parameters | |
547 | (after the registers are used up) begins at 16 rather than at zero. | |
548 | I don't really know why, that's just the way it seems to work. */ | |
549 | ||
550 | /* Now load as many as possible of the first arguments into | |
551 | registers, and push the rest onto the stack. There are 16 bytes | |
552 | in four registers available. Loop thru args from first to last. */ | |
553 | for (argnum = 0; argnum < nargs; argnum++) | |
554 | { | |
555 | int len; | |
556 | char *val; | |
557 | char valbuf[REGISTER_RAW_SIZE(ARG0_REGNUM)]; | |
558 | ||
559 | if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT | |
560 | && TYPE_LENGTH (VALUE_TYPE (*args)) > 8) | |
561 | { | |
562 | store_address (valbuf, 4, VALUE_ADDRESS (*args)); | |
563 | len = 4; | |
564 | val = valbuf; | |
565 | } | |
566 | else | |
567 | { | |
568 | len = TYPE_LENGTH (VALUE_TYPE (*args)); | |
569 | val = (char *)VALUE_CONTENTS (*args); | |
570 | } | |
571 | ||
572 | while (len > 0) | |
573 | if (argreg <= ARGLAST_REGNUM) | |
574 | { | |
575 | CORE_ADDR regval; | |
576 | ||
577 | regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); | |
578 | write_register (argreg, regval); | |
579 | ||
580 | len -= REGISTER_RAW_SIZE (argreg); | |
581 | val += REGISTER_RAW_SIZE (argreg); | |
582 | argreg++; | |
583 | } | |
584 | else | |
585 | { | |
586 | write_memory (sp + stack_offset, val, 4); | |
587 | ||
588 | len -= 4; | |
589 | val += 4; | |
590 | stack_offset += 4; | |
591 | } | |
592 | args++; | |
593 | } | |
594 | return sp; | |
595 | } | |
5198e746 | 596 | #endif /* Z.R. */ |
17139ec5 ZR |
597 | |
598 | /* Function: push_return_address (pc) | |
599 | Set up the return address for the inferior function call. | |
600 | Needed for targets where we don't actually execute a JSR/BSR instruction */ | |
601 | ||
602 | CORE_ADDR | |
5198e746 | 603 | fr30_push_return_address (pc, sp) |
17139ec5 ZR |
604 | CORE_ADDR pc; |
605 | CORE_ADDR sp; | |
606 | { | |
607 | write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); | |
608 | return sp; | |
609 | } | |
610 | ||
611 | /* Function: frame_saved_pc | |
612 | Find the caller of this frame. We do this by seeing if RP_REGNUM | |
613 | is saved in the stack anywhere, otherwise we get it from the | |
614 | registers. If the inner frame is a dummy frame, return its PC | |
615 | instead of RP, because that's where "caller" of the dummy-frame | |
616 | will be found. */ | |
617 | ||
618 | CORE_ADDR | |
5198e746 | 619 | fr30_frame_saved_pc (fi) |
17139ec5 ZR |
620 | struct frame_info *fi; |
621 | { | |
622 | if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame)) | |
623 | return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM); | |
624 | else | |
5198e746 | 625 | return fr30_find_callers_reg (fi, RP_REGNUM); |
17139ec5 ZR |
626 | } |
627 | ||
5198e746 | 628 | #if(0) /* Z.R. XXX */ |
17139ec5 ZR |
629 | void |
630 | get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) | |
631 | char *raw_buffer; | |
632 | int *optimized; | |
633 | CORE_ADDR *addrp; | |
634 | struct frame_info *frame; | |
635 | int regnum; | |
636 | enum lval_type *lval; | |
637 | { | |
638 | generic_get_saved_register (raw_buffer, optimized, addrp, | |
639 | frame, regnum, lval); | |
640 | } | |
5198e746 | 641 | #endif /* Z.R. */ |
17139ec5 ZR |
642 | |
643 | ||
644 | /* Function: fix_call_dummy | |
645 | Pokes the callee function's address into the CALL_DUMMY assembly stub. | |
646 | Assumes that the CALL_DUMMY looks like this: | |
647 | jarl <offset24>, r31 | |
648 | trap | |
649 | */ | |
650 | ||
651 | int | |
5198e746 | 652 | fr30_fix_call_dummy (dummy, sp, fun, nargs, args, type, gcc_p) |
17139ec5 ZR |
653 | char *dummy; |
654 | CORE_ADDR sp; | |
655 | CORE_ADDR fun; | |
656 | int nargs; | |
657 | value_ptr *args; | |
658 | struct type *type; | |
659 | int gcc_p; | |
660 | { | |
661 | long offset24; | |
662 | ||
663 | offset24 = (long) fun - (long) entry_point_address (); | |
664 | offset24 &= 0x3fffff; | |
665 | offset24 |= 0xff800000; /* jarl <offset24>, r31 */ | |
666 | ||
667 | store_unsigned_integer ((unsigned int *)&dummy[2], 2, offset24 & 0xffff); | |
668 | store_unsigned_integer ((unsigned int *)&dummy[0], 2, offset24 >> 16); | |
669 | return 0; | |
670 | } | |
671 |