1ee684603Skettenis /* Target-dependent code for the Motorola 88000 series.
2ee684603Skettenis
3ee684603Skettenis Copyright 2004 Free Software Foundation, Inc.
4ee684603Skettenis
5ee684603Skettenis This file is part of GDB.
6ee684603Skettenis
7ee684603Skettenis This program is free software; you can redistribute it and/or modify
8ee684603Skettenis it under the terms of the GNU General Public License as published by
9ee684603Skettenis the Free Software Foundation; either version 2 of the License, or
10ee684603Skettenis (at your option) any later version.
11ee684603Skettenis
12ee684603Skettenis This program is distributed in the hope that it will be useful,
13ee684603Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14ee684603Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15ee684603Skettenis GNU General Public License for more details.
16ee684603Skettenis
17ee684603Skettenis You should have received a copy of the GNU General Public License
18ee684603Skettenis along with this program; if not, write to the Free Software
19ee684603Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20ee684603Skettenis Boston, MA 02111-1307, USA. */
21ee684603Skettenis
22ee684603Skettenis #include "defs.h"
23ee684603Skettenis #include "arch-utils.h"
24ee684603Skettenis #include "dis-asm.h"
25ee684603Skettenis #include "frame.h"
26ee684603Skettenis #include "frame-base.h"
27ee684603Skettenis #include "frame-unwind.h"
28ee684603Skettenis #include "gdbcore.h"
29ee684603Skettenis #include "gdbtypes.h"
30ee684603Skettenis #include "regcache.h"
31ee684603Skettenis #include "regset.h"
32ee684603Skettenis #include "symtab.h"
33ee684603Skettenis #include "trad-frame.h"
34ee684603Skettenis #include "value.h"
35ee684603Skettenis
36ee684603Skettenis #include "gdb_assert.h"
37ee684603Skettenis #include "gdb_string.h"
38ee684603Skettenis
39ee684603Skettenis #include "m88k-tdep.h"
40ee684603Skettenis
41ee684603Skettenis /* Fetch the instruction at PC. */
42ee684603Skettenis
43ee684603Skettenis static unsigned long
m88k_fetch_instruction(CORE_ADDR pc)44ee684603Skettenis m88k_fetch_instruction (CORE_ADDR pc)
45ee684603Skettenis {
46ee684603Skettenis return read_memory_unsigned_integer (pc, 4);
47ee684603Skettenis }
48ee684603Skettenis
49ee684603Skettenis /* Register information. */
50ee684603Skettenis
51ee684603Skettenis /* Return the name of register REGNUM. */
52ee684603Skettenis
53ee684603Skettenis static const char *
m88k_register_name(int regnum)54ee684603Skettenis m88k_register_name (int regnum)
55ee684603Skettenis {
56ee684603Skettenis static char *register_names[] =
57ee684603Skettenis {
58ee684603Skettenis "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
59ee684603Skettenis "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
60ee684603Skettenis "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
61ee684603Skettenis "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
62ee684603Skettenis "epsr", "fpsr", "fpcr", "sxip", "snip", "sfip"
63ee684603Skettenis };
64ee684603Skettenis
65ee684603Skettenis if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
66ee684603Skettenis return register_names[regnum];
67ee684603Skettenis
68ee684603Skettenis return NULL;
69ee684603Skettenis }
70ee684603Skettenis
71ee684603Skettenis /* Return the GDB type object for the "standard" data type of data in
72ee684603Skettenis register REGNUM. */
73ee684603Skettenis
74ee684603Skettenis static struct type *
m88k_register_type(struct gdbarch * gdbarch,int regnum)75ee684603Skettenis m88k_register_type (struct gdbarch *gdbarch, int regnum)
76ee684603Skettenis {
77ee684603Skettenis /* SXIP, SNIP, SFIP and R1 contain code addresses. */
78ee684603Skettenis if ((regnum >= M88K_SXIP_REGNUM && regnum <= M88K_SFIP_REGNUM)
79ee684603Skettenis || regnum == M88K_R1_REGNUM)
80ee684603Skettenis return builtin_type_void_func_ptr;
81ee684603Skettenis
82ee684603Skettenis /* R30 and R31 typically contains data addresses. */
83ee684603Skettenis if (regnum == M88K_R30_REGNUM || regnum == M88K_R31_REGNUM)
84ee684603Skettenis return builtin_type_void_data_ptr;
85ee684603Skettenis
86ee684603Skettenis return builtin_type_int32;
87ee684603Skettenis }
88ee684603Skettenis
89ee684603Skettenis
90ee684603Skettenis static CORE_ADDR
m88k_addr_bits_remove(CORE_ADDR addr)91ee684603Skettenis m88k_addr_bits_remove (CORE_ADDR addr)
92ee684603Skettenis {
93ee684603Skettenis /* All instructures are 4-byte aligned. The lower 2 bits of SXIP,
94ee684603Skettenis SNIP and SFIP are used for special purposes: bit 0 is the
95ee684603Skettenis exception bit and bit 1 is the valid bit. */
96ee684603Skettenis return addr & ~0x3;
97ee684603Skettenis }
98ee684603Skettenis
99ee684603Skettenis /* Use the program counter to determine the contents and size of a
100ee684603Skettenis breakpoint instruction. Return a pointer to a string of bytes that
101ee684603Skettenis encode a breakpoint instruction, store the length of the string in
102ee684603Skettenis *LEN and optionally adjust *PC to point to the correct memory
103ee684603Skettenis location for inserting the breakpoint. */
104ee684603Skettenis
105ee684603Skettenis static const unsigned char *
m88k_breakpoint_from_pc(CORE_ADDR * pc,int * len)106ee684603Skettenis m88k_breakpoint_from_pc (CORE_ADDR *pc, int *len)
107ee684603Skettenis {
108ee684603Skettenis /* tb 0,r0,511 */
109ee684603Skettenis static unsigned char break_insn[] = { 0xf0, 0x00, 0xd1, 0xff };
110ee684603Skettenis
111ee684603Skettenis *len = sizeof (break_insn);
112ee684603Skettenis return break_insn;
113ee684603Skettenis }
114ee684603Skettenis
115ee684603Skettenis static CORE_ADDR
m88k_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)116ee684603Skettenis m88k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
117ee684603Skettenis {
118ee684603Skettenis CORE_ADDR pc;
119ee684603Skettenis
120ee684603Skettenis pc = frame_unwind_register_unsigned (next_frame, M88K_SXIP_REGNUM);
121ee684603Skettenis return m88k_addr_bits_remove (pc);
122ee684603Skettenis }
123ee684603Skettenis
124ee684603Skettenis static void
m88k_write_pc(CORE_ADDR pc,ptid_t ptid)125ee684603Skettenis m88k_write_pc (CORE_ADDR pc, ptid_t ptid)
126ee684603Skettenis {
127ee684603Skettenis /* According to the MC88100 RISC Microprocessor User's Manual,
128ee684603Skettenis section 6.4.3.1.2:
129ee684603Skettenis
130ee684603Skettenis "... can be made to return to a particular instruction by placing
131ee684603Skettenis a valid instruction address in the SNIP and the next sequential
132ee684603Skettenis instruction address in the SFIP (with V bits set and E bits
133ee684603Skettenis clear). The rte resumes execution at the instruction pointed to
134ee684603Skettenis by the SNIP, then the SFIP."
135ee684603Skettenis
136ee684603Skettenis The E bit is the least significant bit (bit 0). The V (valid)
137ee684603Skettenis bit is bit 1. This is why we logical or 2 into the values we are
138ee684603Skettenis writing below. It turns out that SXIP plays no role when
139ee684603Skettenis returning from an exception so nothing special has to be done
140ee684603Skettenis with it. We could even (presumably) give it a totally bogus
141ee684603Skettenis value. */
142ee684603Skettenis
143ee684603Skettenis write_register_pid (M88K_SXIP_REGNUM, pc, ptid);
144ee684603Skettenis write_register_pid (M88K_SNIP_REGNUM, pc | 2, ptid);
145ee684603Skettenis write_register_pid (M88K_SFIP_REGNUM, (pc + 4) | 2, ptid);
146ee684603Skettenis }
147ee684603Skettenis
148ee684603Skettenis
149ee684603Skettenis /* The functions on this page are intended to be used to classify
150ee684603Skettenis function arguments. */
151ee684603Skettenis
152ee684603Skettenis /* Check whether TYPE is "Integral or Pointer". */
153ee684603Skettenis
154ee684603Skettenis static int
m88k_integral_or_pointer_p(const struct type * type)155ee684603Skettenis m88k_integral_or_pointer_p (const struct type *type)
156ee684603Skettenis {
157ee684603Skettenis switch (TYPE_CODE (type))
158ee684603Skettenis {
159ee684603Skettenis case TYPE_CODE_INT:
160ee684603Skettenis case TYPE_CODE_BOOL:
161ee684603Skettenis case TYPE_CODE_CHAR:
162ee684603Skettenis case TYPE_CODE_ENUM:
163ee684603Skettenis case TYPE_CODE_RANGE:
164ee684603Skettenis {
165ee684603Skettenis /* We have byte, half-word, word and extended-word/doubleword
166ee684603Skettenis integral types. */
167ee684603Skettenis int len = TYPE_LENGTH (type);
168ee684603Skettenis return (len == 1 || len == 2 || len == 4 || len == 8);
169ee684603Skettenis }
170ee684603Skettenis return 1;
171ee684603Skettenis case TYPE_CODE_PTR:
172ee684603Skettenis case TYPE_CODE_REF:
173ee684603Skettenis {
174ee684603Skettenis /* Allow only 32-bit pointers. */
175ee684603Skettenis return (TYPE_LENGTH (type) == 4);
176ee684603Skettenis }
177ee684603Skettenis return 1;
178ee684603Skettenis default:
179ee684603Skettenis break;
180ee684603Skettenis }
181ee684603Skettenis
182ee684603Skettenis return 0;
183ee684603Skettenis }
184ee684603Skettenis
185ee684603Skettenis /* Check whether TYPE is "Floating". */
186ee684603Skettenis
187ee684603Skettenis static int
m88k_floating_p(const struct type * type)188ee684603Skettenis m88k_floating_p (const struct type *type)
189ee684603Skettenis {
190ee684603Skettenis switch (TYPE_CODE (type))
191ee684603Skettenis {
192ee684603Skettenis case TYPE_CODE_FLT:
193ee684603Skettenis {
194ee684603Skettenis int len = TYPE_LENGTH (type);
195ee684603Skettenis return (len == 4 || len == 8);
196ee684603Skettenis }
197ee684603Skettenis default:
198ee684603Skettenis break;
199ee684603Skettenis }
200ee684603Skettenis
201ee684603Skettenis return 0;
202ee684603Skettenis }
203ee684603Skettenis
204ee684603Skettenis /* Check whether TYPE is "Structure or Union". */
205ee684603Skettenis
206ee684603Skettenis static int
m88k_structure_or_union_p(const struct type * type)207ee684603Skettenis m88k_structure_or_union_p (const struct type *type)
208ee684603Skettenis {
209ee684603Skettenis switch (TYPE_CODE (type))
210ee684603Skettenis {
211ee684603Skettenis case TYPE_CODE_STRUCT:
212ee684603Skettenis case TYPE_CODE_UNION:
213ee684603Skettenis return 1;
214ee684603Skettenis default:
215ee684603Skettenis break;
216ee684603Skettenis }
217ee684603Skettenis
218ee684603Skettenis return 0;
219ee684603Skettenis }
220ee684603Skettenis
221ee684603Skettenis /* Check whether TYPE has 8-byte alignment. */
222ee684603Skettenis
223ee684603Skettenis static int
m88k_8_byte_align_p(struct type * type)224ee684603Skettenis m88k_8_byte_align_p (struct type *type)
225ee684603Skettenis {
226ee684603Skettenis if (m88k_structure_or_union_p (type))
227ee684603Skettenis {
228ee684603Skettenis int i;
229ee684603Skettenis
230ee684603Skettenis for (i = 0; i < TYPE_NFIELDS (type); i++)
231ee684603Skettenis {
232ee684603Skettenis struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
233ee684603Skettenis
234ee684603Skettenis if (m88k_8_byte_align_p (subtype))
235ee684603Skettenis return 1;
236ee684603Skettenis }
237ee684603Skettenis }
238ee684603Skettenis
239ee684603Skettenis if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
240ee684603Skettenis return (TYPE_LENGTH (type) == 8);
241ee684603Skettenis
242ee684603Skettenis return 0;
243ee684603Skettenis }
244ee684603Skettenis
245ee684603Skettenis /* Check whether TYPE can be passed in a register. */
246ee684603Skettenis
247ee684603Skettenis static int
m88k_in_register_p(struct type * type)248ee684603Skettenis m88k_in_register_p (struct type *type)
249ee684603Skettenis {
250ee684603Skettenis if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
251ee684603Skettenis return 1;
252ee684603Skettenis
253ee684603Skettenis if (m88k_structure_or_union_p (type) && TYPE_LENGTH (type) == 4)
254ee684603Skettenis return 1;
255ee684603Skettenis
256ee684603Skettenis return 0;
257ee684603Skettenis }
258ee684603Skettenis
259ee684603Skettenis static CORE_ADDR
m88k_store_arguments(struct regcache * regcache,int nargs,struct value ** args,CORE_ADDR sp)260ee684603Skettenis m88k_store_arguments (struct regcache *regcache, int nargs,
261ee684603Skettenis struct value **args, CORE_ADDR sp)
262ee684603Skettenis {
263ee684603Skettenis int num_register_words = 0;
264ee684603Skettenis int num_stack_words = 0;
265ee684603Skettenis int i;
266ee684603Skettenis
267ee684603Skettenis for (i = 0; i < nargs; i++)
268ee684603Skettenis {
269ee684603Skettenis struct type *type = VALUE_TYPE (args[i]);
270ee684603Skettenis int len = TYPE_LENGTH (type);
271ee684603Skettenis
272ee684603Skettenis if (m88k_integral_or_pointer_p (type) && len < 4)
273ee684603Skettenis {
274ee684603Skettenis args[i] = value_cast (builtin_type_int32, args[i]);
275ee684603Skettenis type = VALUE_TYPE (args[i]);
276ee684603Skettenis len = TYPE_LENGTH (type);
277ee684603Skettenis }
278ee684603Skettenis
279ee684603Skettenis if (m88k_in_register_p (type))
280ee684603Skettenis {
281ee684603Skettenis int num_words = 0;
282ee684603Skettenis
283ee684603Skettenis if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type))
284ee684603Skettenis num_words++;
285ee684603Skettenis
286ee684603Skettenis num_words += ((len + 3) / 4);
287ee684603Skettenis if (num_register_words + num_words <= 8)
288ee684603Skettenis {
289ee684603Skettenis num_register_words += num_words;
290ee684603Skettenis continue;
291ee684603Skettenis }
292ee684603Skettenis
293ee684603Skettenis /* We've run out of available registers. Pass the argument
294ee684603Skettenis on the stack. */
295ee684603Skettenis }
296ee684603Skettenis
297ee684603Skettenis if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type))
298ee684603Skettenis num_stack_words++;
299ee684603Skettenis
300ee684603Skettenis num_stack_words += ((len + 3) / 4);
301ee684603Skettenis }
302ee684603Skettenis
303ee684603Skettenis /* Allocate stack space. */
304ee684603Skettenis sp = align_down (sp - 32 - num_stack_words * 4, 16);
305ee684603Skettenis num_stack_words = num_register_words = 0;
306ee684603Skettenis
307ee684603Skettenis for (i = 0; i < nargs; i++)
308ee684603Skettenis {
309ee684603Skettenis char *valbuf = VALUE_CONTENTS (args[i]);
310ee684603Skettenis struct type *type = VALUE_TYPE (args[i]);
311ee684603Skettenis int len = TYPE_LENGTH (type);
312ee684603Skettenis int stack_word = num_stack_words;
313ee684603Skettenis
314ee684603Skettenis if (m88k_in_register_p (type))
315ee684603Skettenis {
316ee684603Skettenis int register_word = num_register_words;
317ee684603Skettenis
318ee684603Skettenis if (register_word % 2 == 1 && m88k_8_byte_align_p (type))
319ee684603Skettenis register_word++;
320ee684603Skettenis
321ee684603Skettenis gdb_assert (len == 4 || len == 8);
322ee684603Skettenis
323ee684603Skettenis if (register_word + len / 8 < 8)
324ee684603Skettenis {
325ee684603Skettenis int regnum = M88K_R2_REGNUM + register_word;
326ee684603Skettenis
327ee684603Skettenis regcache_raw_write (regcache, regnum, valbuf);
328ee684603Skettenis if (len > 4)
329ee684603Skettenis regcache_raw_write (regcache, regnum + 1, valbuf + 4);
330ee684603Skettenis
331ee684603Skettenis num_register_words = (register_word + len / 4);
332ee684603Skettenis continue;
333ee684603Skettenis }
334ee684603Skettenis }
335ee684603Skettenis
336ee684603Skettenis if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
337ee684603Skettenis stack_word++;
338ee684603Skettenis
339ee684603Skettenis write_memory (sp + stack_word * 4, valbuf, len);
340ee684603Skettenis num_stack_words = (stack_word + (len + 3) / 4);
341ee684603Skettenis }
342ee684603Skettenis
343ee684603Skettenis return sp;
344ee684603Skettenis }
345ee684603Skettenis
346ee684603Skettenis static CORE_ADDR
m88k_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)34711efff7fSkettenis m88k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
348ee684603Skettenis struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
349ee684603Skettenis struct value **args, CORE_ADDR sp, int struct_return,
350ee684603Skettenis CORE_ADDR struct_addr)
351ee684603Skettenis {
352ee684603Skettenis /* Set up the function arguments. */
353ee684603Skettenis sp = m88k_store_arguments (regcache, nargs, args, sp);
354ee684603Skettenis gdb_assert (sp % 16 == 0);
355ee684603Skettenis
356ee684603Skettenis /* Store return value address. */
357ee684603Skettenis if (struct_return)
358ee684603Skettenis regcache_raw_write_unsigned (regcache, M88K_R12_REGNUM, struct_addr);
359ee684603Skettenis
360ee684603Skettenis /* Store the stack pointer and return address in the appropriate
361ee684603Skettenis registers. */
362ee684603Skettenis regcache_raw_write_unsigned (regcache, M88K_R31_REGNUM, sp);
363ee684603Skettenis regcache_raw_write_unsigned (regcache, M88K_R1_REGNUM, bp_addr);
364ee684603Skettenis
365ee684603Skettenis /* Return the stack pointer. */
366ee684603Skettenis return sp;
367ee684603Skettenis }
368ee684603Skettenis
369ee684603Skettenis static struct frame_id
m88k_unwind_dummy_id(struct gdbarch * arch,struct frame_info * next_frame)370ee684603Skettenis m88k_unwind_dummy_id (struct gdbarch *arch, struct frame_info *next_frame)
371ee684603Skettenis {
372ee684603Skettenis CORE_ADDR sp;
373ee684603Skettenis
374ee684603Skettenis sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
375ee684603Skettenis return frame_id_build (sp, frame_pc_unwind (next_frame));
376ee684603Skettenis }
377ee684603Skettenis
378ee684603Skettenis
379ee684603Skettenis /* Determine, for architecture GDBARCH, how a return value of TYPE
380ee684603Skettenis should be returned. If it is supposed to be returned in registers,
381ee684603Skettenis and READBUF is non-zero, read the appropriate value from REGCACHE,
382ee684603Skettenis and copy it into READBUF. If WRITEBUF is non-zero, write the value
383ee684603Skettenis from WRITEBUF into REGCACHE. */
384ee684603Skettenis
385ee684603Skettenis static enum return_value_convention
m88k_return_value(struct gdbarch * gdbarch,struct type * type,struct regcache * regcache,void * readbuf,const void * writebuf)386ee684603Skettenis m88k_return_value (struct gdbarch *gdbarch, struct type *type,
387ee684603Skettenis struct regcache *regcache, void *readbuf,
388ee684603Skettenis const void *writebuf)
389ee684603Skettenis {
390ee684603Skettenis int len = TYPE_LENGTH (type);
391ee684603Skettenis char buf[8];
392ee684603Skettenis
393ee684603Skettenis if (!m88k_integral_or_pointer_p (type) && !m88k_floating_p (type))
394ee684603Skettenis return RETURN_VALUE_STRUCT_CONVENTION;
395ee684603Skettenis
396ee684603Skettenis if (readbuf)
397ee684603Skettenis {
398ee684603Skettenis /* Read the contents of R2 and (if necessary) R3. */
399ee684603Skettenis regcache_cooked_read (regcache, M88K_R2_REGNUM, buf);
400ee684603Skettenis if (len > 4)
401ee684603Skettenis {
402ee684603Skettenis regcache_cooked_read (regcache, M88K_R3_REGNUM, buf + 4);
403ee684603Skettenis gdb_assert (len == 8);
404ee684603Skettenis memcpy (readbuf, buf, len);
405ee684603Skettenis }
406ee684603Skettenis else
407ee684603Skettenis {
408ee684603Skettenis /* Just stripping off any unused bytes should preserve the
409ee684603Skettenis signed-ness just fine. */
410ee684603Skettenis memcpy (readbuf, buf + 4 - len, len);
411ee684603Skettenis }
412ee684603Skettenis }
413ee684603Skettenis
414ee684603Skettenis if (writebuf)
415ee684603Skettenis {
416ee684603Skettenis /* Read the contents to R2 and (if necessary) R3. */
417ee684603Skettenis if (len > 4)
418ee684603Skettenis {
419ee684603Skettenis gdb_assert (len == 8);
420ee684603Skettenis memcpy (buf, writebuf, 8);
421ee684603Skettenis regcache_cooked_write (regcache, M88K_R3_REGNUM, buf + 4);
422ee684603Skettenis }
423ee684603Skettenis else
424ee684603Skettenis {
425ee684603Skettenis /* ??? Do we need to do any sign-extension here? */
426ee684603Skettenis memcpy (buf + 4 - len, writebuf, len);
427ee684603Skettenis }
428ee684603Skettenis regcache_cooked_write (regcache, M88K_R2_REGNUM, buf);
429ee684603Skettenis }
430ee684603Skettenis
431ee684603Skettenis return RETURN_VALUE_REGISTER_CONVENTION;
432ee684603Skettenis }
433ee684603Skettenis
434ee684603Skettenis /* Default frame unwinder. */
435ee684603Skettenis
436ee684603Skettenis struct m88k_frame_cache
437ee684603Skettenis {
438ee684603Skettenis /* Base address. */
439ee684603Skettenis CORE_ADDR base;
440ee684603Skettenis CORE_ADDR pc;
441ee684603Skettenis
442ee684603Skettenis int sp_offset;
443ee684603Skettenis int fp_offset;
444ee684603Skettenis
445ee684603Skettenis /* Table of saved registers. */
446ee684603Skettenis struct trad_frame_saved_reg *saved_regs;
447ee684603Skettenis };
448ee684603Skettenis
449ee684603Skettenis /* Prologue analysis. */
450ee684603Skettenis
451ee684603Skettenis /* Macros for extracting fields from instructions. */
452ee684603Skettenis
453ee684603Skettenis #define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
454ee684603Skettenis #define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
455ee684603Skettenis #define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
456ee684603Skettenis #define ST_OFFSET(x) ((unsigned)((x) & 0xFFFF))
457ee684603Skettenis #define ST_SRC(x) EXTRACT_FIELD ((x), 21, 5)
458ee684603Skettenis #define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
459ee684603Skettenis
460ee684603Skettenis /* Possible actions to be taken by the prologue analyzer for the
461ee684603Skettenis instructions it encounters. */
462ee684603Skettenis
463ee684603Skettenis enum m88k_prologue_insn_action
464ee684603Skettenis {
465ee684603Skettenis M88K_PIA_SKIP, /* Ignore. */
466ee684603Skettenis M88K_PIA_NOTE_ST, /* Note register store. */
467ee684603Skettenis M88K_PIA_NOTE_STD, /* Note register pair store. */
468ee684603Skettenis M88K_PIA_NOTE_SP_ADJUSTMENT, /* Note stack pointer adjustment. */
469ee684603Skettenis M88K_PIA_NOTE_FP_ASSIGNMENT, /* Note frame pointer assignment. */
470ee684603Skettenis M88K_PIA_NOTE_BRANCH, /* Note branch. */
471ee684603Skettenis M88K_PIA_NOTE_PROLOGUE_END /* Note end of prologue. */
472ee684603Skettenis };
473ee684603Skettenis
474ee684603Skettenis /* Table of instructions that may comprise a function prologue. */
475ee684603Skettenis
476ee684603Skettenis struct m88k_prologue_insn
477ee684603Skettenis {
478ee684603Skettenis unsigned long insn;
479ee684603Skettenis unsigned long mask;
480ee684603Skettenis enum m88k_prologue_insn_action action;
481ee684603Skettenis };
482ee684603Skettenis
483ee684603Skettenis struct m88k_prologue_insn m88k_prologue_insn_table[] =
484ee684603Skettenis {
485ee684603Skettenis /* Various register move instructions. */
486ee684603Skettenis { 0x58000000, 0xf800ffff, M88K_PIA_SKIP }, /* or/or.u with immed of 0 */
487ee684603Skettenis { 0xf4005800, 0xfc1fffe0, M88K_PIA_SKIP }, /* or rd,r0,rs */
488ee684603Skettenis { 0xf4005800, 0xfc00ffff, M88K_PIA_SKIP }, /* or rd,rs,r0 */
489ee684603Skettenis
490ee684603Skettenis /* Various other instructions. */
491ee684603Skettenis { 0x58000000, 0xf8000000, M88K_PIA_SKIP }, /* or/or.u */
492ee684603Skettenis
493ee684603Skettenis /* Stack pointer setup: "subu sp,sp,n" where n is a multiple of 8. */
494ee684603Skettenis { 0x67ff0000, 0xffff0007, M88K_PIA_NOTE_SP_ADJUSTMENT },
495ee684603Skettenis
496ee684603Skettenis /* Frame pointer assignment: "addu r30,r31,n". */
497ee684603Skettenis { 0x63df0000, 0xffff0000, M88K_PIA_NOTE_FP_ASSIGNMENT },
498ee684603Skettenis
499ee684603Skettenis /* Store to stack instructions; either "st rx,sp,n" or "st.d rx,sp,n". */
500ee684603Skettenis { 0x241f0000, 0xfc1f0000, M88K_PIA_NOTE_ST }, /* st rx,sp,n */
501ee684603Skettenis { 0x201f0000, 0xfc1f0000, M88K_PIA_NOTE_STD }, /* st.d rs,sp,n */
502ee684603Skettenis
503ee684603Skettenis /* Instructions needed for setting up r25 for pic code. */
504ee684603Skettenis { 0x5f200000, 0xffff0000, M88K_PIA_SKIP }, /* or.u r25,r0,offset_high */
505ee684603Skettenis { 0xcc000002, 0xffffffff, M88K_PIA_SKIP }, /* bsr.n Lab */
506ee684603Skettenis { 0x5b390000, 0xffff0000, M88K_PIA_SKIP }, /* or r25,r25,offset_low */
507ee684603Skettenis { 0xf7396001, 0xffffffff, M88K_PIA_SKIP }, /* Lab: addu r25,r25,r1 */
508ee684603Skettenis
509ee684603Skettenis /* Various branch or jump instructions which have a delay slot --
510ee684603Skettenis these do not form part of the prologue, but the instruction in
511ee684603Skettenis the delay slot might be a store instruction which should be
512ee684603Skettenis noted. */
513ee684603Skettenis { 0xc4000000, 0xe4000000, M88K_PIA_NOTE_BRANCH },
514ee684603Skettenis /* br.n, bsr.n, bb0.n, or bb1.n */
515ee684603Skettenis { 0xec000000, 0xfc000000, M88K_PIA_NOTE_BRANCH }, /* bcnd.n */
516ee684603Skettenis { 0xf400c400, 0xfffff7e0, M88K_PIA_NOTE_BRANCH }, /* jmp.n or jsr.n */
517ee684603Skettenis
518ee684603Skettenis /* Catch all. Ends prologue analysis. */
519ee684603Skettenis { 0x00000000, 0x00000000, M88K_PIA_NOTE_PROLOGUE_END }
520ee684603Skettenis };
521ee684603Skettenis
522ee684603Skettenis /* Do a full analysis of the function prologue at PC and update CACHE
523ee684603Skettenis accordingly. Bail out early if LIMIT is reached. Return the
524ee684603Skettenis address where the analysis stopped. If LIMIT points beyond the
525ee684603Skettenis function prologue, the return address should be the end of the
526ee684603Skettenis prologue. */
527ee684603Skettenis
528ee684603Skettenis static CORE_ADDR
m88k_analyze_prologue(CORE_ADDR pc,CORE_ADDR limit,struct m88k_frame_cache * cache)529ee684603Skettenis m88k_analyze_prologue (CORE_ADDR pc, CORE_ADDR limit,
530ee684603Skettenis struct m88k_frame_cache *cache)
531ee684603Skettenis {
532ee684603Skettenis CORE_ADDR end = limit;
533ee684603Skettenis
534ee684603Skettenis /* Provide a dummy cache if necessary. */
535ee684603Skettenis if (cache == NULL)
536ee684603Skettenis {
537ee684603Skettenis size_t sizeof_saved_regs =
538ee684603Skettenis (M88K_R31_REGNUM + 1) * sizeof (struct trad_frame_saved_reg);
539ee684603Skettenis
540ee684603Skettenis cache = alloca (sizeof (struct m88k_frame_cache));
541ee684603Skettenis cache->saved_regs = alloca (sizeof_saved_regs);
542ee684603Skettenis
543ee684603Skettenis /* We only initialize the members we care about. */
544ee684603Skettenis cache->saved_regs[M88K_R1_REGNUM].addr = -1;
545ee684603Skettenis cache->fp_offset = -1;
546ee684603Skettenis }
547ee684603Skettenis
548ee684603Skettenis while (pc < limit)
549ee684603Skettenis {
550ee684603Skettenis struct m88k_prologue_insn *pi = m88k_prologue_insn_table;
551ee684603Skettenis unsigned long insn = m88k_fetch_instruction (pc);
552ee684603Skettenis
553ee684603Skettenis while ((insn & pi->mask) != pi->insn)
554ee684603Skettenis pi++;
555ee684603Skettenis
556ee684603Skettenis switch (pi->action)
557ee684603Skettenis {
558ee684603Skettenis case M88K_PIA_SKIP:
559ee684603Skettenis /* If we have a frame pointer, and R1 has been saved,
560ee684603Skettenis consider this instruction as not being part of the
561ee684603Skettenis prologue. */
562ee684603Skettenis if (cache->fp_offset != -1
563ee684603Skettenis && cache->saved_regs[M88K_R1_REGNUM].addr != -1)
564ee684603Skettenis return min (pc, end);
565ee684603Skettenis break;
566ee684603Skettenis
567ee684603Skettenis case M88K_PIA_NOTE_ST:
568ee684603Skettenis case M88K_PIA_NOTE_STD:
569ee684603Skettenis /* If no frame has been allocated, the stores aren't part of
570ee684603Skettenis the prologue. */
571ee684603Skettenis if (cache->sp_offset == 0)
572ee684603Skettenis return min (pc, end);
573ee684603Skettenis
574ee684603Skettenis /* Record location of saved registers. */
575ee684603Skettenis {
576ee684603Skettenis int regnum = ST_SRC (insn) + M88K_R0_REGNUM;
577ee684603Skettenis ULONGEST offset = ST_OFFSET (insn);
578ee684603Skettenis
579ee684603Skettenis cache->saved_regs[regnum].addr = offset;
580ee684603Skettenis if (pi->action == M88K_PIA_NOTE_STD && regnum < M88K_R31_REGNUM)
581ee684603Skettenis cache->saved_regs[regnum + 1].addr = offset + 4;
582ee684603Skettenis }
583ee684603Skettenis break;
584ee684603Skettenis
585ee684603Skettenis case M88K_PIA_NOTE_SP_ADJUSTMENT:
586ee684603Skettenis /* A second stack pointer adjustment isn't part of the
587ee684603Skettenis prologue. */
588ee684603Skettenis if (cache->sp_offset != 0)
589ee684603Skettenis return min (pc, end);
590ee684603Skettenis
591ee684603Skettenis /* Store stack pointer adjustment. */
592ee684603Skettenis cache->sp_offset = -SUBU_OFFSET (insn);
593ee684603Skettenis break;
594ee684603Skettenis
595ee684603Skettenis case M88K_PIA_NOTE_FP_ASSIGNMENT:
596ee684603Skettenis /* A second frame pointer assignment isn't part of the
597ee684603Skettenis prologue. */
598ee684603Skettenis if (cache->fp_offset != -1)
599ee684603Skettenis return min (pc, end);
600ee684603Skettenis
601ee684603Skettenis /* Record frame pointer assignment. */
602ee684603Skettenis cache->fp_offset = ADDU_OFFSET (insn);
603ee684603Skettenis break;
604ee684603Skettenis
605ee684603Skettenis case M88K_PIA_NOTE_BRANCH:
606ee684603Skettenis /* The branch instruction isn't part of the prologue, but
607ee684603Skettenis the instruction in the delay slot might be. Limit the
608ee684603Skettenis prologue analysis to the delay slot and record the branch
609ee684603Skettenis instruction as the end of the prologue. */
61028cbedccSkettenis limit = min (limit, pc + 2 * M88K_INSN_SIZE);
611ee684603Skettenis end = pc;
612ee684603Skettenis break;
613ee684603Skettenis
614ee684603Skettenis case M88K_PIA_NOTE_PROLOGUE_END:
615ee684603Skettenis return min (pc, end);
616ee684603Skettenis }
617ee684603Skettenis
618ee684603Skettenis pc += M88K_INSN_SIZE;
619ee684603Skettenis }
620ee684603Skettenis
621ee684603Skettenis return end;
622ee684603Skettenis }
623ee684603Skettenis
624ee684603Skettenis /* An upper limit to the size of the prologue. */
625ee684603Skettenis const int m88k_max_prologue_size = 128 * M88K_INSN_SIZE;
626ee684603Skettenis
627ee684603Skettenis /* Return the address of first real instruction of the function
628ee684603Skettenis starting at PC. */
629ee684603Skettenis
630ee684603Skettenis static CORE_ADDR
m88k_skip_prologue(CORE_ADDR pc)631ee684603Skettenis m88k_skip_prologue (CORE_ADDR pc)
632ee684603Skettenis {
633ee684603Skettenis struct symtab_and_line sal;
634ee684603Skettenis CORE_ADDR func_start, func_end;
635ee684603Skettenis
636ee684603Skettenis /* This is the preferred method, find the end of the prologue by
637ee684603Skettenis using the debugging information. */
638ee684603Skettenis if (find_pc_partial_function (pc, NULL, &func_start, &func_end))
639ee684603Skettenis {
640ee684603Skettenis sal = find_pc_line (func_start, 0);
641ee684603Skettenis
642ee684603Skettenis if (sal.end < func_end && pc <= sal.end)
643ee684603Skettenis return sal.end;
644ee684603Skettenis }
645ee684603Skettenis
646ee684603Skettenis return m88k_analyze_prologue (pc, pc + m88k_max_prologue_size, NULL);
647ee684603Skettenis }
648ee684603Skettenis
649ee684603Skettenis struct m88k_frame_cache *
m88k_frame_cache(struct frame_info * next_frame,void ** this_cache)650ee684603Skettenis m88k_frame_cache (struct frame_info *next_frame, void **this_cache)
651ee684603Skettenis {
652ee684603Skettenis struct m88k_frame_cache *cache;
653ee684603Skettenis CORE_ADDR frame_sp;
654ee684603Skettenis
655ee684603Skettenis if (*this_cache)
656ee684603Skettenis return *this_cache;
657ee684603Skettenis
658ee684603Skettenis cache = FRAME_OBSTACK_ZALLOC (struct m88k_frame_cache);
659ee684603Skettenis cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
660ee684603Skettenis cache->fp_offset = -1;
661ee684603Skettenis
662ee684603Skettenis cache->pc = frame_func_unwind (next_frame);
663ee684603Skettenis if (cache->pc != 0)
664ee684603Skettenis {
665ee684603Skettenis CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
666ee684603Skettenis m88k_analyze_prologue (cache->pc, addr_in_block, cache);
667ee684603Skettenis }
668ee684603Skettenis
669ee684603Skettenis /* Calculate the stack pointer used in the prologue. */
670ee684603Skettenis if (cache->fp_offset != -1)
671ee684603Skettenis {
672ee684603Skettenis CORE_ADDR fp;
673ee684603Skettenis
674ee684603Skettenis fp = frame_unwind_register_unsigned (next_frame, M88K_R30_REGNUM);
675ee684603Skettenis frame_sp = fp - cache->fp_offset;
676ee684603Skettenis }
677ee684603Skettenis else
678ee684603Skettenis {
679ee684603Skettenis /* If we know where the return address is saved, we can take a
680ee684603Skettenis solid guess at what the frame pointer should be. */
681ee684603Skettenis if (cache->saved_regs[M88K_R1_REGNUM].addr != -1)
682ee684603Skettenis cache->fp_offset = cache->saved_regs[M88K_R1_REGNUM].addr - 4;
683ee684603Skettenis frame_sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
684ee684603Skettenis }
685ee684603Skettenis
686ee684603Skettenis /* Now that we know the stack pointer, adjust the location of the
687ee684603Skettenis saved registers. */
688ee684603Skettenis {
689ee684603Skettenis int regnum;
690ee684603Skettenis
691ee684603Skettenis for (regnum = M88K_R0_REGNUM; regnum < M88K_R31_REGNUM; regnum ++)
692ee684603Skettenis if (cache->saved_regs[regnum].addr != -1)
693ee684603Skettenis cache->saved_regs[regnum].addr += frame_sp;
694ee684603Skettenis }
695ee684603Skettenis
696ee684603Skettenis /* Calculate the frame's base. */
697ee684603Skettenis cache->base = frame_sp - cache->sp_offset;
698ee684603Skettenis trad_frame_set_value (cache->saved_regs, M88K_R31_REGNUM, cache->base);
699ee684603Skettenis
700ee684603Skettenis /* Identify SXIP with the return address in R1. */
701ee684603Skettenis cache->saved_regs[M88K_SXIP_REGNUM] = cache->saved_regs[M88K_R1_REGNUM];
702ee684603Skettenis
703ee684603Skettenis *this_cache = cache;
704ee684603Skettenis return cache;
705ee684603Skettenis }
706ee684603Skettenis
707ee684603Skettenis static void
m88k_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)708ee684603Skettenis m88k_frame_this_id (struct frame_info *next_frame, void **this_cache,
709ee684603Skettenis struct frame_id *this_id)
710ee684603Skettenis {
711ee684603Skettenis struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
712ee684603Skettenis
713ee684603Skettenis /* This marks the outermost frame. */
714ee684603Skettenis if (cache->base == 0)
715ee684603Skettenis return;
716ee684603Skettenis
717ee684603Skettenis (*this_id) = frame_id_build (cache->base, cache->pc);
718ee684603Skettenis }
719ee684603Skettenis
720ee684603Skettenis static void
m88k_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)721ee684603Skettenis m88k_frame_prev_register (struct frame_info *next_frame, void **this_cache,
722ee684603Skettenis int regnum, int *optimizedp,
723ee684603Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
724ee684603Skettenis int *realnump, void *valuep)
725ee684603Skettenis {
726ee684603Skettenis struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
727ee684603Skettenis
728ee684603Skettenis if (regnum == M88K_SNIP_REGNUM || regnum == M88K_SFIP_REGNUM)
729ee684603Skettenis {
730ee684603Skettenis if (valuep)
731ee684603Skettenis {
732ee684603Skettenis CORE_ADDR pc;
733ee684603Skettenis
73411efff7fSkettenis trad_frame_get_prev_register (next_frame, cache->saved_regs,
735ee684603Skettenis M88K_SXIP_REGNUM, optimizedp,
736ee684603Skettenis lvalp, addrp, realnump, valuep);
737ee684603Skettenis
738ee684603Skettenis pc = extract_unsigned_integer (valuep, 4);
73928cbedccSkettenis if (regnum == M88K_SFIP_REGNUM)
740ee684603Skettenis pc += 4;
74128cbedccSkettenis store_unsigned_integer (valuep, 4, pc + 4);
742ee684603Skettenis }
743ee684603Skettenis
744ee684603Skettenis /* It's a computed value. */
745ee684603Skettenis *optimizedp = 0;
746ee684603Skettenis *lvalp = not_lval;
747ee684603Skettenis *addrp = 0;
748ee684603Skettenis *realnump = -1;
749ee684603Skettenis return;
750ee684603Skettenis }
751ee684603Skettenis
75211efff7fSkettenis trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
753ee684603Skettenis optimizedp, lvalp, addrp, realnump, valuep);
754ee684603Skettenis }
755ee684603Skettenis
756ee684603Skettenis static const struct frame_unwind m88k_frame_unwind =
757ee684603Skettenis {
758ee684603Skettenis NORMAL_FRAME,
759ee684603Skettenis m88k_frame_this_id,
760ee684603Skettenis m88k_frame_prev_register
761ee684603Skettenis };
762ee684603Skettenis
763ee684603Skettenis static const struct frame_unwind *
m88k_frame_sniffer(struct frame_info * next_frame)764ee684603Skettenis m88k_frame_sniffer (struct frame_info *next_frame)
765ee684603Skettenis {
766ee684603Skettenis return &m88k_frame_unwind;
767ee684603Skettenis }
768ee684603Skettenis
769ee684603Skettenis
770ee684603Skettenis static CORE_ADDR
m88k_frame_base_address(struct frame_info * next_frame,void ** this_cache)771ee684603Skettenis m88k_frame_base_address (struct frame_info *next_frame, void **this_cache)
772ee684603Skettenis {
773ee684603Skettenis struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
774ee684603Skettenis
775ee684603Skettenis if (cache->fp_offset != -1)
776ee684603Skettenis return cache->base + cache->sp_offset + cache->fp_offset;
777ee684603Skettenis
778ee684603Skettenis return 0;
779ee684603Skettenis }
780ee684603Skettenis
781ee684603Skettenis static const struct frame_base m88k_frame_base =
782ee684603Skettenis {
783ee684603Skettenis &m88k_frame_unwind,
784ee684603Skettenis m88k_frame_base_address,
785ee684603Skettenis m88k_frame_base_address,
786ee684603Skettenis m88k_frame_base_address
787ee684603Skettenis };
788ee684603Skettenis
789ee684603Skettenis
790ee684603Skettenis /* Core file support. */
791ee684603Skettenis
792ee684603Skettenis /* Supply register REGNUM from the buffer specified by GREGS and LEN
793ee684603Skettenis in the general-purpose register set REGSET to register cache
794ee684603Skettenis REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
795ee684603Skettenis
796ee684603Skettenis static void
m88k_supply_gregset(const struct regset * regset,struct regcache * regcache,int regnum,const void * gregs,size_t len)797ee684603Skettenis m88k_supply_gregset (const struct regset *regset,
798ee684603Skettenis struct regcache *regcache,
799ee684603Skettenis int regnum, const void *gregs, size_t len)
800ee684603Skettenis {
801ee684603Skettenis const char *regs = gregs;
802ee684603Skettenis int i;
803ee684603Skettenis
804ee684603Skettenis for (i = 0; i < M88K_NUM_REGS; i++)
805ee684603Skettenis {
806ee684603Skettenis if (regnum == i || regnum == -1)
807ee684603Skettenis regcache_raw_supply (regcache, i, regs + i * 4);
808ee684603Skettenis }
809ee684603Skettenis }
810ee684603Skettenis
811ee684603Skettenis /* Motorola 88000 register set. */
812ee684603Skettenis
813ee684603Skettenis static struct regset m88k_gregset =
814ee684603Skettenis {
815ee684603Skettenis NULL,
816ee684603Skettenis m88k_supply_gregset
817ee684603Skettenis };
818ee684603Skettenis
819ee684603Skettenis /* Return the appropriate register set for the core section identified
820ee684603Skettenis by SECT_NAME and SECT_SIZE. */
821ee684603Skettenis
822ee684603Skettenis static const struct regset *
m88k_regset_from_core_section(struct gdbarch * gdbarch,const char * sect_name,size_t sect_size)823ee684603Skettenis m88k_regset_from_core_section (struct gdbarch *gdbarch,
824ee684603Skettenis const char *sect_name, size_t sect_size)
825ee684603Skettenis {
826ee684603Skettenis if (strcmp (sect_name, ".reg") == 0 && sect_size >= M88K_NUM_REGS * 4)
827ee684603Skettenis return &m88k_gregset;
828ee684603Skettenis
829ee684603Skettenis return NULL;
830ee684603Skettenis }
831ee684603Skettenis
832ee684603Skettenis
833ee684603Skettenis static struct gdbarch *
m88k_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)834ee684603Skettenis m88k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
835ee684603Skettenis {
836ee684603Skettenis struct gdbarch *gdbarch;
837ee684603Skettenis
838ee684603Skettenis /* If there is already a candidate, use it. */
839ee684603Skettenis arches = gdbarch_list_lookup_by_info (arches, &info);
840ee684603Skettenis if (arches != NULL)
841ee684603Skettenis return arches->gdbarch;
842ee684603Skettenis
843ee684603Skettenis /* Allocate space for the new architecture. */
844ee684603Skettenis gdbarch = gdbarch_alloc (&info, NULL);
845ee684603Skettenis
846ee684603Skettenis /* There is no real `long double'. */
847ee684603Skettenis set_gdbarch_long_double_bit (gdbarch, 64);
848ee684603Skettenis set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
849ee684603Skettenis
850ee684603Skettenis set_gdbarch_num_regs (gdbarch, M88K_NUM_REGS);
851ee684603Skettenis set_gdbarch_register_name (gdbarch, m88k_register_name);
852ee684603Skettenis set_gdbarch_register_type (gdbarch, m88k_register_type);
853ee684603Skettenis
854ee684603Skettenis /* Register numbers of various important registers. */
855ee684603Skettenis set_gdbarch_sp_regnum (gdbarch, M88K_R31_REGNUM);
856ee684603Skettenis set_gdbarch_pc_regnum (gdbarch, M88K_SXIP_REGNUM);
857ee684603Skettenis
858ee684603Skettenis /* Core file support. */
859ee684603Skettenis set_gdbarch_regset_from_core_section
860ee684603Skettenis (gdbarch, m88k_regset_from_core_section);
861ee684603Skettenis
862ee684603Skettenis set_gdbarch_print_insn (gdbarch, print_insn_m88k);
863ee684603Skettenis
864ee684603Skettenis set_gdbarch_skip_prologue (gdbarch, m88k_skip_prologue);
865ee684603Skettenis
866ee684603Skettenis /* Stack grows downward. */
867ee684603Skettenis set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
868ee684603Skettenis
869ee684603Skettenis /* Call dummy code. */
870ee684603Skettenis set_gdbarch_push_dummy_call (gdbarch, m88k_push_dummy_call);
871ee684603Skettenis set_gdbarch_unwind_dummy_id (gdbarch, m88k_unwind_dummy_id);
872ee684603Skettenis
873ee684603Skettenis /* Return value info */
874ee684603Skettenis set_gdbarch_return_value (gdbarch, m88k_return_value);
875ee684603Skettenis
876ee684603Skettenis set_gdbarch_addr_bits_remove (gdbarch, m88k_addr_bits_remove);
877ee684603Skettenis set_gdbarch_breakpoint_from_pc (gdbarch, m88k_breakpoint_from_pc);
878ee684603Skettenis set_gdbarch_unwind_pc (gdbarch, m88k_unwind_pc);
879ee684603Skettenis set_gdbarch_write_pc (gdbarch, m88k_write_pc);
880ee684603Skettenis
881ee684603Skettenis frame_base_set_default (gdbarch, &m88k_frame_base);
882*d0a35373Smiod
883*d0a35373Smiod /* Hook in ABI-specific overrides, if they have been registered. */
884*d0a35373Smiod gdbarch_init_osabi (info, gdbarch);
885*d0a35373Smiod
886ee684603Skettenis frame_unwind_append_sniffer (gdbarch, m88k_frame_sniffer);
887ee684603Skettenis
888ee684603Skettenis return gdbarch;
889ee684603Skettenis }
890ee684603Skettenis
891ee684603Skettenis
892ee684603Skettenis /* Provide a prototype to silence -Wmissing-prototypes. */
893ee684603Skettenis void _initialize_m88k_tdep (void);
894ee684603Skettenis
895ee684603Skettenis void
_initialize_m88k_tdep(void)896ee684603Skettenis _initialize_m88k_tdep (void)
897ee684603Skettenis {
898ee684603Skettenis gdbarch_register (bfd_arch_m88k, m88k_gdbarch_init, NULL);
899ee684603Skettenis }
900