]>
Commit | Line | Data |
---|---|---|
52071915 AC |
1 | /* OBSOLETE /* Target-dependent code for the TI TMS320C80 (MVP) for GDB, the GNU debugger. */ |
2 | /* OBSOLETE Copyright 1996, 1997, 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 "value.h" */ | |
23 | /* OBSOLETE #include "frame.h" */ | |
24 | /* OBSOLETE #include "inferior.h" */ | |
25 | /* OBSOLETE #include "obstack.h" */ | |
26 | /* OBSOLETE #include "target.h" */ | |
27 | /* OBSOLETE #include "bfd.h" */ | |
28 | /* OBSOLETE #include "gdb_string.h" */ | |
29 | /* OBSOLETE #include "gdbcore.h" */ | |
30 | /* OBSOLETE #include "symfile.h" */ | |
31 | /* OBSOLETE #include "regcache.h" */ | |
32 | /* OBSOLETE */ | |
33 | /* OBSOLETE /* Function: frame_find_saved_regs */ | |
34 | /* OBSOLETE Return the frame_saved_regs structure for the frame. */ | |
35 | /* OBSOLETE Doesn't really work for dummy frames, but it does pass back */ | |
36 | /* OBSOLETE an empty frame_saved_regs, so I guess that's better than total failure */ */ | |
37 | /* OBSOLETE */ | |
38 | /* OBSOLETE void */ | |
39 | /* OBSOLETE tic80_frame_find_saved_regs (struct frame_info *fi, */ | |
40 | /* OBSOLETE struct frame_saved_regs *regaddr) */ | |
41 | /* OBSOLETE { */ | |
42 | /* OBSOLETE memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs)); */ | |
43 | /* OBSOLETE } */ | |
44 | /* OBSOLETE */ | |
45 | /* OBSOLETE /* Function: skip_prologue */ | |
46 | /* OBSOLETE Find end of function prologue. */ */ | |
47 | /* OBSOLETE */ | |
48 | /* OBSOLETE CORE_ADDR */ | |
49 | /* OBSOLETE tic80_skip_prologue (CORE_ADDR pc) */ | |
50 | /* OBSOLETE { */ | |
51 | /* OBSOLETE CORE_ADDR func_addr, func_end; */ | |
52 | /* OBSOLETE struct symtab_and_line sal; */ | |
53 | /* OBSOLETE */ | |
54 | /* OBSOLETE /* See what the symbol table says */ */ | |
55 | /* OBSOLETE */ | |
56 | /* OBSOLETE if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) */ | |
57 | /* OBSOLETE { */ | |
58 | /* OBSOLETE sal = find_pc_line (func_addr, 0); */ | |
59 | /* OBSOLETE */ | |
60 | /* OBSOLETE if (sal.line != 0 && sal.end < func_end) */ | |
61 | /* OBSOLETE return sal.end; */ | |
62 | /* OBSOLETE else */ | |
63 | /* OBSOLETE /* Either there's no line info, or the line after the prologue is after */ | |
64 | /* OBSOLETE the end of the function. In this case, there probably isn't a */ | |
65 | /* OBSOLETE prologue. */ */ | |
66 | /* OBSOLETE return pc; */ | |
67 | /* OBSOLETE } */ | |
68 | /* OBSOLETE */ | |
69 | /* OBSOLETE /* We can't find the start of this function, so there's nothing we can do. */ */ | |
70 | /* OBSOLETE return pc; */ | |
71 | /* OBSOLETE } */ | |
72 | /* OBSOLETE */ | |
73 | /* OBSOLETE /* Function: tic80_scan_prologue */ | |
74 | /* OBSOLETE This function decodes the target function prologue to determine: */ | |
75 | /* OBSOLETE 1) the size of the stack frame */ | |
76 | /* OBSOLETE 2) which registers are saved on it */ | |
77 | /* OBSOLETE 3) the offsets of saved regs */ | |
78 | /* OBSOLETE 4) the frame size */ | |
79 | /* OBSOLETE This information is stored in the "extra" fields of the frame_info. */ */ | |
80 | /* OBSOLETE */ | |
81 | /* OBSOLETE static void */ | |
82 | /* OBSOLETE tic80_scan_prologue (struct frame_info *fi) */ | |
83 | /* OBSOLETE { */ | |
84 | /* OBSOLETE struct symtab_and_line sal; */ | |
85 | /* OBSOLETE CORE_ADDR prologue_start, prologue_end, current_pc; */ | |
86 | /* OBSOLETE */ | |
87 | /* OBSOLETE /* Assume there is no frame until proven otherwise. */ */ | |
88 | /* OBSOLETE fi->framereg = SP_REGNUM; */ | |
89 | /* OBSOLETE fi->framesize = 0; */ | |
90 | /* OBSOLETE fi->frameoffset = 0; */ | |
91 | /* OBSOLETE */ | |
92 | /* OBSOLETE /* this code essentially duplicates skip_prologue, */ | |
93 | /* OBSOLETE but we need the start address below. */ */ | |
94 | /* OBSOLETE */ | |
95 | /* OBSOLETE if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) */ | |
96 | /* OBSOLETE { */ | |
97 | /* OBSOLETE sal = find_pc_line (prologue_start, 0); */ | |
98 | /* OBSOLETE */ | |
99 | /* OBSOLETE if (sal.line == 0) /* no line info, use current PC */ */ | |
100 | /* OBSOLETE if (prologue_start != entry_point_address ()) */ | |
101 | /* OBSOLETE prologue_end = fi->pc; */ | |
102 | /* OBSOLETE else */ | |
103 | /* OBSOLETE return; /* _start has no frame or prologue */ */ | |
104 | /* OBSOLETE else if (sal.end < prologue_end) /* next line begins after fn end */ */ | |
105 | /* OBSOLETE prologue_end = sal.end; /* (probably means no prologue) */ */ | |
106 | /* OBSOLETE } */ | |
107 | /* OBSOLETE else */ | |
108 | /* OBSOLETE /* FIXME */ */ | |
109 | /* OBSOLETE prologue_end = prologue_start + 40; /* We're in the boondocks: allow for */ */ | |
110 | /* OBSOLETE /* 16 pushes, an add, and "mv fp,sp" */ */ | |
111 | /* OBSOLETE */ | |
112 | /* OBSOLETE prologue_end = min (prologue_end, fi->pc); */ | |
113 | /* OBSOLETE */ | |
114 | /* OBSOLETE /* Now search the prologue looking for instructions that set up the */ | |
115 | /* OBSOLETE frame pointer, adjust the stack pointer, and save registers. */ */ | |
116 | /* OBSOLETE */ | |
117 | /* OBSOLETE for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 4) */ | |
118 | /* OBSOLETE { */ | |
119 | /* OBSOLETE unsigned int insn; */ | |
120 | /* OBSOLETE int regno; */ | |
121 | /* OBSOLETE int offset = 0; */ | |
122 | /* OBSOLETE */ | |
123 | /* OBSOLETE insn = read_memory_unsigned_integer (current_pc, 4); */ | |
124 | /* OBSOLETE */ | |
125 | /* OBSOLETE if ((insn & 0x301000) == 0x301000) /* Long immediate? */ */ | |
126 | /* OBSOLETE /* FIXME - set offset for long immediate instructions */ */ | |
127 | /* OBSOLETE current_pc += 4; */ | |
128 | /* OBSOLETE else */ | |
129 | /* OBSOLETE { */ | |
130 | /* OBSOLETE offset = insn & 0x7fff; /* extract 15-bit offset */ */ | |
131 | /* OBSOLETE if (offset & 0x4000) /* if negative, sign-extend */ */ | |
132 | /* OBSOLETE offset = -(0x8000 - offset); */ | |
133 | /* OBSOLETE } */ | |
134 | /* OBSOLETE */ | |
135 | /* OBSOLETE if ((insn & 0x7fd0000) == 0x590000) /* st.{w,d} reg, xx(r1) */ */ | |
136 | /* OBSOLETE { */ | |
137 | /* OBSOLETE regno = ((insn >> 27) & 0x1f); */ | |
138 | /* OBSOLETE fi->fsr.regs[regno] = offset; */ | |
139 | /* OBSOLETE if (insn & 0x8000) /* 64-bit store (st.d)? */ */ | |
140 | /* OBSOLETE fi->fsr.regs[regno + 1] = offset + 4; */ | |
141 | /* OBSOLETE } */ | |
142 | /* OBSOLETE else if ((insn & 0xffff8000) == 0x086c8000) /* addu xx, r1, r1 */ */ | |
143 | /* OBSOLETE fi->framesize = -offset; */ | |
144 | /* OBSOLETE else if ((insn & 0xffff8000) == 0xf06c8000) /* addu xx, r1, r30 */ */ | |
145 | /* OBSOLETE { */ | |
146 | /* OBSOLETE fi->framereg = FP_REGNUM; /* fp is now valid */ */ | |
147 | /* OBSOLETE fi->frameoffset = offset; */ | |
148 | /* OBSOLETE break; /* end of stack adjustments */ */ | |
149 | /* OBSOLETE } */ | |
150 | /* OBSOLETE else if (insn == 0xf03b2001) /* addu r1, r0, r30 */ */ | |
151 | /* OBSOLETE { */ | |
152 | /* OBSOLETE fi->framereg = FP_REGNUM; /* fp is now valid */ */ | |
153 | /* OBSOLETE fi->frameoffset = 0; */ | |
154 | /* OBSOLETE break; /* end of stack adjustments */ */ | |
155 | /* OBSOLETE } */ | |
156 | /* OBSOLETE else */ | |
157 | /* OBSOLETE /* FIXME - handle long immediate instructions */ */ | |
158 | /* OBSOLETE break; /* anything else isn't prologue */ */ | |
159 | /* OBSOLETE } */ | |
160 | /* OBSOLETE } */ | |
161 | /* OBSOLETE */ | |
162 | /* OBSOLETE /* Function: init_extra_frame_info */ | |
163 | /* OBSOLETE This function actually figures out the frame address for a given pc and */ | |
164 | /* OBSOLETE sp. This is tricky on the c80 because we sometimes don't use an explicit */ | |
165 | /* OBSOLETE frame pointer, and the previous stack pointer isn't necessarily recorded */ | |
166 | /* OBSOLETE on the stack. The only reliable way to get this info is to */ | |
167 | /* OBSOLETE examine the prologue. */ */ | |
168 | /* OBSOLETE */ | |
169 | /* OBSOLETE void */ | |
170 | /* OBSOLETE tic80_init_extra_frame_info (struct frame_info *fi) */ | |
171 | /* OBSOLETE { */ | |
172 | /* OBSOLETE int reg; */ | |
173 | /* OBSOLETE */ | |
174 | /* OBSOLETE if (fi->next) */ | |
175 | /* OBSOLETE fi->pc = FRAME_SAVED_PC (fi->next); */ | |
176 | /* OBSOLETE */ | |
177 | /* OBSOLETE /* Because zero is a valid register offset relative to SP, we initialize */ | |
178 | /* OBSOLETE the offsets to -1 to indicate unused entries. */ */ | |
179 | /* OBSOLETE for (reg = 0; reg < NUM_REGS; reg++) */ | |
180 | /* OBSOLETE fi->fsr.regs[reg] = -1; */ | |
181 | /* OBSOLETE */ | |
182 | /* OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) */ | |
183 | /* OBSOLETE { */ | |
184 | /* OBSOLETE /* We need to setup fi->frame here because run_stack_dummy gets it wrong */ | |
185 | /* OBSOLETE by assuming it's always FP. */ */ | |
186 | /* OBSOLETE fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); */ | |
187 | /* OBSOLETE fi->framesize = 0; */ | |
188 | /* OBSOLETE fi->frameoffset = 0; */ | |
189 | /* OBSOLETE return; */ | |
190 | /* OBSOLETE } */ | |
191 | /* OBSOLETE else */ | |
192 | /* OBSOLETE { */ | |
193 | /* OBSOLETE tic80_scan_prologue (fi); */ | |
194 | /* OBSOLETE */ | |
195 | /* OBSOLETE if (!fi->next) /* this is the innermost frame? */ */ | |
196 | /* OBSOLETE fi->frame = read_register (fi->framereg); */ | |
197 | /* OBSOLETE else */ | |
198 | /* OBSOLETE /* not the innermost frame */ */ | |
199 | /* OBSOLETE /* If this function uses FP as the frame register, and the function */ | |
200 | /* OBSOLETE it called saved the FP, get the saved FP. */ if (fi->framereg == FP_REGNUM && */ | |
201 | /* OBSOLETE fi->next->fsr.regs[FP_REGNUM] != (unsigned) -1) */ | |
202 | /* OBSOLETE fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); */ | |
203 | /* OBSOLETE */ | |
204 | /* OBSOLETE /* Convert SP-relative offsets of saved registers to real addresses. */ */ | |
205 | /* OBSOLETE for (reg = 0; reg < NUM_REGS; reg++) */ | |
206 | /* OBSOLETE if (fi->fsr.regs[reg] == (unsigned) -1) */ | |
207 | /* OBSOLETE fi->fsr.regs[reg] = 0; /* unused entry */ */ | |
208 | /* OBSOLETE else */ | |
209 | /* OBSOLETE fi->fsr.regs[reg] += fi->frame - fi->frameoffset; */ | |
210 | /* OBSOLETE } */ | |
211 | /* OBSOLETE } */ | |
212 | /* OBSOLETE */ | |
213 | /* OBSOLETE /* Function: find_callers_reg */ | |
214 | /* OBSOLETE Find REGNUM on the stack. Otherwise, it's in an active register. One thing */ | |
215 | /* OBSOLETE we might want to do here is to check REGNUM against the clobber mask, and */ | |
216 | /* OBSOLETE somehow flag it as invalid if it isn't saved on the stack somewhere. This */ | |
217 | /* OBSOLETE would provide a graceful failure mode when trying to get the value of */ | |
218 | /* OBSOLETE caller-saves registers for an inner frame. */ */ | |
219 | /* OBSOLETE */ | |
220 | /* OBSOLETE CORE_ADDR */ | |
221 | /* OBSOLETE tic80_find_callers_reg (struct frame_info *fi, int regnum) */ | |
222 | /* OBSOLETE { */ | |
223 | /* OBSOLETE for (; fi; fi = fi->next) */ | |
224 | /* OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) */ | |
225 | /* OBSOLETE return generic_read_register_dummy (fi->pc, fi->frame, regnum); */ | |
226 | /* OBSOLETE else if (fi->fsr.regs[regnum] != 0) */ | |
227 | /* OBSOLETE return read_memory_integer (fi->fsr.regs[regnum], */ | |
228 | /* OBSOLETE REGISTER_RAW_SIZE (regnum)); */ | |
229 | /* OBSOLETE return read_register (regnum); */ | |
230 | /* OBSOLETE } */ | |
231 | /* OBSOLETE */ | |
232 | /* OBSOLETE /* Function: frame_chain */ | |
233 | /* OBSOLETE Given a GDB frame, determine the address of the calling function's frame. */ | |
234 | /* OBSOLETE This will be used to create a new GDB frame struct, and then */ | |
235 | /* OBSOLETE INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. */ | |
236 | /* OBSOLETE For c80, we save the frame size when we initialize the frame_info. */ */ | |
237 | /* OBSOLETE */ | |
238 | /* OBSOLETE CORE_ADDR */ | |
239 | /* OBSOLETE tic80_frame_chain (struct frame_info *fi) */ | |
240 | /* OBSOLETE { */ | |
241 | /* OBSOLETE CORE_ADDR fn_start, callers_pc, fp; */ | |
242 | /* OBSOLETE */ | |
243 | /* OBSOLETE /* is this a dummy frame? */ */ | |
244 | /* OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) */ | |
245 | /* OBSOLETE return fi->frame; /* dummy frame same as caller's frame */ */ | |
246 | /* OBSOLETE */ | |
247 | /* OBSOLETE /* is caller-of-this a dummy frame? */ */ | |
248 | /* OBSOLETE callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ */ | |
249 | /* OBSOLETE fp = tic80_find_callers_reg (fi, FP_REGNUM); */ | |
250 | /* OBSOLETE if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) */ | |
251 | /* OBSOLETE return fp; /* dummy frame's frame may bear no relation to ours */ */ | |
252 | /* OBSOLETE */ | |
253 | /* OBSOLETE if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) */ | |
254 | /* OBSOLETE if (fn_start == entry_point_address ()) */ | |
255 | /* OBSOLETE return 0; /* in _start fn, don't chain further */ */ | |
256 | /* OBSOLETE */ | |
257 | /* OBSOLETE if (fi->framereg == FP_REGNUM) */ | |
258 | /* OBSOLETE return tic80_find_callers_reg (fi, FP_REGNUM); */ | |
259 | /* OBSOLETE else */ | |
260 | /* OBSOLETE return fi->frame + fi->framesize; */ | |
261 | /* OBSOLETE } */ | |
262 | /* OBSOLETE */ | |
263 | /* OBSOLETE /* Function: pop_frame */ | |
264 | /* OBSOLETE Discard from the stack the innermost frame, */ | |
265 | /* OBSOLETE restoring all saved registers. */ */ | |
266 | /* OBSOLETE */ | |
267 | /* OBSOLETE struct frame_info * */ | |
268 | /* OBSOLETE tic80_pop_frame (struct frame_info *frame) */ | |
269 | /* OBSOLETE { */ | |
270 | /* OBSOLETE int regnum; */ | |
271 | /* OBSOLETE */ | |
272 | /* OBSOLETE if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) */ | |
273 | /* OBSOLETE generic_pop_dummy_frame (); */ | |
274 | /* OBSOLETE else */ | |
275 | /* OBSOLETE { */ | |
276 | /* OBSOLETE for (regnum = 0; regnum < NUM_REGS; regnum++) */ | |
277 | /* OBSOLETE if (frame->fsr.regs[regnum] != 0) */ | |
278 | /* OBSOLETE write_register (regnum, */ | |
279 | /* OBSOLETE read_memory_integer (frame->fsr.regs[regnum], 4)); */ | |
280 | /* OBSOLETE */ | |
281 | /* OBSOLETE write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); */ | |
282 | /* OBSOLETE write_register (SP_REGNUM, read_register (FP_REGNUM)); */ | |
283 | /* OBSOLETE #if 0 */ | |
284 | /* OBSOLETE if (read_register (PSW_REGNUM) & 0x80) */ | |
285 | /* OBSOLETE write_register (SPU_REGNUM, read_register (SP_REGNUM)); */ | |
286 | /* OBSOLETE else */ | |
287 | /* OBSOLETE write_register (SPI_REGNUM, read_register (SP_REGNUM)); */ | |
288 | /* OBSOLETE #endif */ | |
289 | /* OBSOLETE } */ | |
290 | /* OBSOLETE flush_cached_frames (); */ | |
291 | /* OBSOLETE return NULL; */ | |
292 | /* OBSOLETE } */ | |
293 | /* OBSOLETE */ | |
294 | /* OBSOLETE /* Function: frame_saved_pc */ | |
295 | /* OBSOLETE Find the caller of this frame. We do this by seeing if LR_REGNUM is saved */ | |
296 | /* OBSOLETE in the stack anywhere, otherwise we get it from the registers. */ */ | |
297 | /* OBSOLETE */ | |
298 | /* OBSOLETE CORE_ADDR */ | |
299 | /* OBSOLETE tic80_frame_saved_pc (struct frame_info *fi) */ | |
300 | /* OBSOLETE { */ | |
301 | /* OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) */ | |
302 | /* OBSOLETE return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); */ | |
303 | /* OBSOLETE else */ | |
304 | /* OBSOLETE return tic80_find_callers_reg (fi, LR_REGNUM); */ | |
305 | /* OBSOLETE } */ | |
306 | /* OBSOLETE */ | |
307 | /* OBSOLETE /* Function: tic80_push_return_address (pc, sp) */ | |
308 | /* OBSOLETE Set up the return address for the inferior function call. */ | |
309 | /* OBSOLETE Necessary for targets that don't actually execute a JSR/BSR instruction */ | |
310 | /* OBSOLETE (ie. when using an empty CALL_DUMMY) */ */ | |
311 | /* OBSOLETE */ | |
312 | /* OBSOLETE CORE_ADDR */ | |
313 | /* OBSOLETE tic80_push_return_address (CORE_ADDR pc, CORE_ADDR sp) */ | |
314 | /* OBSOLETE { */ | |
315 | /* OBSOLETE write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ()); */ | |
316 | /* OBSOLETE return sp; */ | |
317 | /* OBSOLETE } */ | |
318 | /* OBSOLETE */ | |
319 | /* OBSOLETE */ | |
320 | /* OBSOLETE /* Function: push_arguments */ | |
321 | /* OBSOLETE Setup the function arguments for calling a function in the inferior. */ | |
322 | /* OBSOLETE */ | |
323 | /* OBSOLETE On the TI C80 architecture, there are six register pairs (R2/R3 to R12/13) */ | |
324 | /* OBSOLETE which are dedicated for passing function arguments. Up to the first six */ | |
325 | /* OBSOLETE arguments (depending on size) may go into these registers. */ | |
326 | /* OBSOLETE The rest go on the stack. */ | |
327 | /* OBSOLETE */ | |
328 | /* OBSOLETE Arguments that are smaller than 4 bytes will still take up a whole */ | |
329 | /* OBSOLETE register or a whole 32-bit word on the stack, and will be */ | |
330 | /* OBSOLETE right-justified in the register or the stack word. This includes */ | |
331 | /* OBSOLETE chars, shorts, and small aggregate types. */ | |
332 | /* OBSOLETE */ | |
333 | /* OBSOLETE Arguments that are four bytes or less in size are placed in the */ | |
334 | /* OBSOLETE even-numbered register of a register pair, and the odd-numbered */ | |
335 | /* OBSOLETE register is not used. */ | |
336 | /* OBSOLETE */ | |
337 | /* OBSOLETE Arguments of 8 bytes size (such as floating point doubles) are placed */ | |
338 | /* OBSOLETE in a register pair. The least significant 32-bit word is placed in */ | |
339 | /* OBSOLETE the even-numbered register, and the most significant word in the */ | |
340 | /* OBSOLETE odd-numbered register. */ | |
341 | /* OBSOLETE */ | |
342 | /* OBSOLETE Aggregate types with sizes between 4 and 8 bytes are passed */ | |
343 | /* OBSOLETE entirely on the stack, and are left-justified within the */ | |
344 | /* OBSOLETE double-word (as opposed to aggregates smaller than 4 bytes */ | |
345 | /* OBSOLETE which are right-justified). */ | |
346 | /* OBSOLETE */ | |
347 | /* OBSOLETE Aggregates of greater than 8 bytes are first copied onto the stack, */ | |
348 | /* OBSOLETE and then a pointer to the copy is passed in the place of the normal */ | |
349 | /* OBSOLETE argument (either in a register if available, or on the stack). */ | |
350 | /* OBSOLETE */ | |
351 | /* OBSOLETE Functions that must return an aggregate type can return it in the */ | |
352 | /* OBSOLETE normal return value registers (R2 and R3) if its size is 8 bytes or */ | |
353 | /* OBSOLETE less. For larger return values, the caller must allocate space for */ | |
354 | /* OBSOLETE the callee to copy the return value to. A pointer to this space is */ | |
355 | /* OBSOLETE passed as an implicit first argument, always in R0. */ */ | |
356 | /* OBSOLETE */ | |
357 | /* OBSOLETE CORE_ADDR */ | |
358 | /* OBSOLETE tic80_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp, */ | |
359 | /* OBSOLETE unsigned char struct_return, CORE_ADDR struct_addr) */ | |
360 | /* OBSOLETE { */ | |
361 | /* OBSOLETE int stack_offset, stack_alloc; */ | |
362 | /* OBSOLETE int argreg; */ | |
363 | /* OBSOLETE int argnum; */ | |
364 | /* OBSOLETE struct type *type; */ | |
365 | /* OBSOLETE CORE_ADDR regval; */ | |
366 | /* OBSOLETE char *val; */ | |
367 | /* OBSOLETE char valbuf[4]; */ | |
368 | /* OBSOLETE int len; */ | |
369 | /* OBSOLETE int odd_sized_struct; */ | |
370 | /* OBSOLETE int is_struct; */ | |
371 | /* OBSOLETE */ | |
372 | /* OBSOLETE /* first force sp to a 4-byte alignment */ */ | |
373 | /* OBSOLETE sp = sp & ~3; */ | |
374 | /* OBSOLETE */ | |
375 | /* OBSOLETE argreg = ARG0_REGNUM; */ | |
376 | /* OBSOLETE /* The "struct return pointer" pseudo-argument goes in R0 */ */ | |
377 | /* OBSOLETE if (struct_return) */ | |
378 | /* OBSOLETE write_register (argreg++, struct_addr); */ | |
379 | /* OBSOLETE */ | |
380 | /* OBSOLETE /* Now make sure there's space on the stack */ */ | |
381 | /* OBSOLETE for (argnum = 0, stack_alloc = 0; */ | |
382 | /* OBSOLETE argnum < nargs; argnum++) */ | |
383 | /* OBSOLETE stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3); */ | |
384 | /* OBSOLETE sp -= stack_alloc; /* make room on stack for args */ */ | |
385 | /* OBSOLETE */ | |
386 | /* OBSOLETE */ | |
387 | /* OBSOLETE /* Now load as many as possible of the first arguments into */ | |
388 | /* OBSOLETE registers, and push the rest onto the stack. There are 16 bytes */ | |
389 | /* OBSOLETE in four registers available. Loop thru args from first to last. */ */ | |
390 | /* OBSOLETE */ | |
391 | /* OBSOLETE argreg = ARG0_REGNUM; */ | |
392 | /* OBSOLETE for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) */ | |
393 | /* OBSOLETE { */ | |
394 | /* OBSOLETE type = VALUE_TYPE (args[argnum]); */ | |
395 | /* OBSOLETE len = TYPE_LENGTH (type); */ | |
396 | /* OBSOLETE memset (valbuf, 0, sizeof (valbuf)); */ | |
397 | /* OBSOLETE val = (char *) VALUE_CONTENTS (args[argnum]); */ | |
398 | /* OBSOLETE */ | |
399 | /* OBSOLETE /* FIXME -- tic80 can take doubleword arguments in register pairs */ */ | |
400 | /* OBSOLETE is_struct = (type->code == TYPE_CODE_STRUCT); */ | |
401 | /* OBSOLETE odd_sized_struct = 0; */ | |
402 | /* OBSOLETE */ | |
403 | /* OBSOLETE if (!is_struct) */ | |
404 | /* OBSOLETE { */ | |
405 | /* OBSOLETE if (len < 4) */ | |
406 | /* OBSOLETE { /* value gets right-justified in the register or stack word */ */ | |
407 | /* OBSOLETE memcpy (valbuf + (4 - len), val, len); */ | |
408 | /* OBSOLETE val = valbuf; */ | |
409 | /* OBSOLETE } */ | |
410 | /* OBSOLETE if (len > 4 && (len & 3) != 0) */ | |
411 | /* OBSOLETE odd_sized_struct = 1; /* such structs go entirely on stack */ */ | |
412 | /* OBSOLETE } */ | |
413 | /* OBSOLETE else */ | |
414 | /* OBSOLETE { */ | |
415 | /* OBSOLETE /* Structs are always passed by reference. */ */ | |
416 | /* OBSOLETE write_register (argreg, sp + stack_offset); */ | |
417 | /* OBSOLETE argreg++; */ | |
418 | /* OBSOLETE } */ | |
419 | /* OBSOLETE */ | |
420 | /* OBSOLETE while (len > 0) */ | |
421 | /* OBSOLETE { */ | |
422 | /* OBSOLETE if (is_struct || argreg > ARGLAST_REGNUM || odd_sized_struct) */ | |
423 | /* OBSOLETE { /* must go on the stack */ */ | |
424 | /* OBSOLETE write_memory (sp + stack_offset, val, 4); */ | |
425 | /* OBSOLETE stack_offset += 4; */ | |
426 | /* OBSOLETE } */ | |
427 | /* OBSOLETE /* NOTE WELL!!!!! This is not an "else if" clause!!! */ | |
428 | /* OBSOLETE That's because some things get passed on the stack */ | |
429 | /* OBSOLETE AND in the registers! */ */ | |
430 | /* OBSOLETE if (!is_struct && argreg <= ARGLAST_REGNUM) */ | |
431 | /* OBSOLETE { /* there's room in a register */ */ | |
432 | /* OBSOLETE regval = extract_address (val, REGISTER_RAW_SIZE (argreg)); */ | |
433 | /* OBSOLETE write_register (argreg, regval); */ | |
434 | /* OBSOLETE argreg += 2; /* FIXME -- what about doubleword args? */ */ | |
435 | /* OBSOLETE } */ | |
436 | /* OBSOLETE /* Store the value 4 bytes at a time. This means that things */ | |
437 | /* OBSOLETE larger than 4 bytes may go partly in registers and partly */ | |
438 | /* OBSOLETE on the stack. */ */ | |
439 | /* OBSOLETE len -= REGISTER_RAW_SIZE (argreg); */ | |
440 | /* OBSOLETE val += REGISTER_RAW_SIZE (argreg); */ | |
441 | /* OBSOLETE } */ | |
442 | /* OBSOLETE } */ | |
443 | /* OBSOLETE return sp; */ | |
444 | /* OBSOLETE } */ | |
445 | /* OBSOLETE */ | |
446 | /* OBSOLETE /* Function: tic80_write_sp */ | |
447 | /* OBSOLETE Because SP is really a read-only register that mirrors either SPU or SPI, */ | |
448 | /* OBSOLETE we must actually write one of those two as well, depending on PSW. */ */ | |
449 | /* OBSOLETE */ | |
450 | /* OBSOLETE void */ | |
451 | /* OBSOLETE tic80_write_sp (CORE_ADDR val) */ | |
452 | /* OBSOLETE { */ | |
453 | /* OBSOLETE #if 0 */ | |
454 | /* OBSOLETE unsigned long psw = read_register (PSW_REGNUM); */ | |
455 | /* OBSOLETE */ | |
456 | /* OBSOLETE if (psw & 0x80) /* stack mode: user or interrupt */ */ | |
457 | /* OBSOLETE write_register (SPU_REGNUM, val); */ | |
458 | /* OBSOLETE else */ | |
459 | /* OBSOLETE write_register (SPI_REGNUM, val); */ | |
460 | /* OBSOLETE #endif */ | |
461 | /* OBSOLETE write_register (SP_REGNUM, val); */ | |
462 | /* OBSOLETE } */ | |
463 | /* OBSOLETE */ | |
464 | /* OBSOLETE void */ | |
465 | /* OBSOLETE _initialize_tic80_tdep (void) */ | |
466 | /* OBSOLETE { */ | |
467 | /* OBSOLETE tm_print_insn = print_insn_tic80; */ | |
468 | /* OBSOLETE } */ |