1 /* Print NS 32000 instructions for GDB, the GNU debugger.
2 Copyright 1986, 1988, 1991, 1992, 1994, 1995
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 _initialize_ns32k_tdep ()
26 tm_print_insn
= print_insn_ns32k
;
29 /* Advance PC across any function entry prologue instructions
30 to reach some "real" code. */
33 merlin_skip_prologue (pc
)
36 register int op
= read_memory_integer (pc
, 1);
39 op
= read_memory_integer (pc
+2,1);
42 else if ((op
& 0xc0) == 0x80)
50 umax_skip_prologue (pc
)
53 register unsigned char op
= read_memory_integer (pc
, 1);
56 op
= read_memory_integer (pc
+2,1);
59 else if ((op
& 0xc0) == 0x80)
67 /* Return number of args passed to a frame.
68 Can return -1, meaning no way to tell. */
71 merlin_frame_num_args (fi
)
72 struct frame_info
*fi
;
80 pc
= FRAME_SAVED_PC (fi
);
81 insn
= read_memory_integer (pc
,2);
82 addr_mode
= (insn
>> 11) & 0x1f;
84 if ((insn
& 0x7fc) == 0x57c
85 && addr_mode
== 0x14) /* immediate */
87 if (insn
== 0x57c) /* adjspb */
89 else if (insn
== 0x57d) /* adjspw */
91 else if (insn
== 0x57f) /* adjspd */
93 numargs
= read_memory_integer (pc
+2,width
);
95 flip_bytes (&numargs
, width
);
96 numargs
= - sign_extend (numargs
, width
*8) / 4;
104 umax_frame_num_args (fi
)
105 struct frame_info
*fi
;
109 CORE_ADDR enter_addr
;
111 unsigned int addr_mode
;
115 enter_addr
= ns32k_get_enter_addr ((fi
)->pc
);
118 pc
= ((enter_addr
== 1)
119 ? SAVED_PC_AFTER_CALL (fi
)
120 : FRAME_SAVED_PC (fi
));
121 insn
= read_memory_integer (pc
,2);
122 addr_mode
= (insn
>> 11) & 0x1f;
124 if ((insn
& 0x7fc) == 0x57c
125 && addr_mode
== 0x14) /* immediate */
127 if (insn
== 0x57c) /* adjspb */
129 else if (insn
== 0x57d) /* adjspw */
131 else if (insn
== 0x57f) /* adjspd */
133 numargs
= read_memory_integer (pc
+2,width
);
135 flip_bytes (&numargs
, width
);
136 numargs
= - sign_extend (numargs
, width
*8) / 4;
143 sign_extend (value
, bits
)
145 value
= value
& ((1 << bits
) - 1);
146 return (value
& (1 << (bits
-1))
147 ? value
| (~((1 << bits
) - 1))
152 flip_bytes (ptr
, count
)
161 ptr
[0] = ptr
[count
-1];
168 /* Return the number of locals in the current frame given a pc
169 pointing to the enter instruction. This is used in the macro
170 FRAME_FIND_SAVED_REGS. */
173 ns32k_localcount (enter_pc
)
176 unsigned char localtype
;
179 localtype
= read_memory_integer (enter_pc
+2, 1);
180 if ((localtype
& 0x80) == 0)
181 localcount
= localtype
;
182 else if ((localtype
& 0xc0) == 0x80)
183 localcount
= (((localtype
& 0x3f) << 8)
184 | (read_memory_integer (enter_pc
+3, 1) & 0xff));
186 localcount
= (((localtype
& 0x3f) << 24)
187 | ((read_memory_integer (enter_pc
+3, 1) & 0xff) << 16)
188 | ((read_memory_integer (enter_pc
+4, 1) & 0xff) << 8 )
189 | (read_memory_integer (enter_pc
+5, 1) & 0xff));
194 /* Nonzero if instruction at PC is a return instruction. */
197 ns32k_about_to_return (pc
)
200 return (read_memory_integer (pc
, 1) == 0x12);
205 * Get the address of the enter opcode for the function
206 * containing PC, if there is an enter for the function,
207 * and if the pc is between the enter and exit.
208 * Returns positive address if pc is between enter/exit,
209 * 1 if pc before enter or after exit, 0 otherwise.
213 ns32k_get_enter_addr (pc
)
216 CORE_ADDR enter_addr
;
222 if (ns32k_about_to_return (pc
))
223 return 1; /* after exit */
225 enter_addr
= get_pc_function_start (pc
);
227 if (pc
== enter_addr
)
228 return 1; /* before enter */
230 op
= read_memory_integer (enter_addr
, 1);
233 return 0; /* function has no enter/exit */
235 return enter_addr
; /* pc is between enter and exit */