]>
Commit | Line | Data |
---|---|---|
3dab9e15 SB |
1 | /* Target-dependent code for the Z80. |
2 | ||
1d506c26 | 3 | Copyright (C) 1986-2024 Free Software Foundation, Inc. |
3dab9e15 SB |
4 | |
5 | This file is part of GDB. | |
6 | ||
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 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
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. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "arch-utils.h" | |
22 | #include "dis-asm.h" | |
23 | #include "frame.h" | |
24 | #include "frame-unwind.h" | |
25 | #include "frame-base.h" | |
26 | #include "trad-frame.h" | |
27 | #include "gdbcmd.h" | |
28 | #include "gdbcore.h" | |
29 | #include "gdbtypes.h" | |
30 | #include "inferior.h" | |
31 | #include "objfiles.h" | |
32 | #include "symfile.h" | |
76eb8ef1 | 33 | #include "gdbarch.h" |
3dab9e15 SB |
34 | |
35 | #include "z80-tdep.h" | |
36 | #include "features/z80.c" | |
37 | ||
38 | /* You need to define __gdb_break_handler symbol pointing to the breakpoint | |
39 | handler. The value of the symbol will be used to determine the instruction | |
40 | for software breakpoint. If __gdb_break_handler points to one of standard | |
41 | RST addresses (0x00, 0x08, 0x10,... 0x38) then RST __gdb_break_handler | |
42 | instruction will be used, else CALL __gdb_break_handler | |
43 | ||
44 | ;breakpoint handler | |
45 | .globl __gdb_break_handler | |
46 | .org 8 | |
47 | __gdb_break_handler: | |
48 | jp _debug_swbreak | |
49 | ||
50 | */ | |
51 | ||
52 | /* Meaning of terms "previous" and "next": | |
53 | previous frame - frame of callee, which is called by current function | |
54 | current frame - frame of current function which has called callee | |
55 | next frame - frame of caller, which has called current function | |
56 | */ | |
57 | ||
ab25d9bb | 58 | struct z80_gdbarch_tdep : gdbarch_tdep_base |
3dab9e15 SB |
59 | { |
60 | /* Number of bytes used for address: | |
61 | 2 bytes for all Z80 family | |
62 | 3 bytes for eZ80 CPUs operating in ADL mode */ | |
345bd07c | 63 | int addr_length = 0; |
3dab9e15 SB |
64 | |
65 | /* Type for void. */ | |
345bd07c SM |
66 | struct type *void_type = nullptr; |
67 | ||
3dab9e15 | 68 | /* Type for a function returning void. */ |
345bd07c SM |
69 | struct type *func_void_type = nullptr; |
70 | ||
3dab9e15 | 71 | /* Type for a pointer to a function. Used for the type of PC. */ |
345bd07c | 72 | struct type *pc_type = nullptr; |
3dab9e15 SB |
73 | }; |
74 | ||
75 | /* At any time stack frame contains following parts: | |
76 | [<current PC>] | |
77 | [<temporaries, y bytes>] | |
78 | [<local variables, x bytes> | |
79 | <next frame FP>] | |
80 | [<saved state (critical or interrupt functions), 2 or 10 bytes>] | |
81 | In simplest case <next PC> is pointer to the call instruction | |
82 | (or call __call_hl). There are more difficult cases: interrupt handler or | |
83 | push/ret and jp; but they are untrackable. | |
84 | */ | |
85 | ||
86 | struct z80_unwind_cache | |
87 | { | |
88 | /* The previous frame's inner most stack address (SP after call executed), | |
89 | it is current frame's frame_id. */ | |
90 | CORE_ADDR prev_sp; | |
91 | ||
92 | /* Size of the frame, prev_sp + size = next_frame.prev_sp */ | |
93 | ULONGEST size; | |
94 | ||
95 | /* size of saved state (including frame pointer and return address), | |
96 | assume: prev_sp + size = IX + state_size */ | |
97 | ULONGEST state_size; | |
98 | ||
99 | struct | |
100 | { | |
07f28593 SM |
101 | unsigned int called : 1; /* there is return address on stack */ |
102 | unsigned int load_args : 1; /* prologues loads args using POPs */ | |
103 | unsigned int fp_sdcc : 1; /* prologue saves and adjusts frame pointer IX */ | |
104 | unsigned int interrupt : 1; /* __interrupt handler */ | |
105 | unsigned int critical : 1; /* __critical function */ | |
3dab9e15 SB |
106 | } prologue_type; |
107 | ||
108 | /* Table indicating the location of each and every register. */ | |
109 | struct trad_frame_saved_reg *saved_regs; | |
110 | }; | |
111 | ||
cc55e4ef | 112 | enum z80_instruction_type |
3dab9e15 SB |
113 | { |
114 | insn_default, | |
115 | insn_z80, | |
116 | insn_adl, | |
117 | insn_z80_ed, | |
118 | insn_adl_ed, | |
119 | insn_z80_ddfd, | |
120 | insn_adl_ddfd, | |
121 | insn_djnz_d, | |
122 | insn_jr_d, | |
123 | insn_jr_cc_d, | |
124 | insn_jp_nn, | |
125 | insn_jp_rr, | |
126 | insn_jp_cc_nn, | |
127 | insn_call_nn, | |
128 | insn_call_cc_nn, | |
129 | insn_rst_n, | |
130 | insn_ret, | |
131 | insn_ret_cc, | |
132 | insn_push_rr, | |
133 | insn_pop_rr, | |
134 | insn_dec_sp, | |
135 | insn_inc_sp, | |
136 | insn_ld_sp_nn, | |
137 | insn_ld_sp_6nn9, /* ld sp, (nn) */ | |
138 | insn_ld_sp_rr, | |
139 | insn_force_nop /* invalid opcode prefix */ | |
140 | }; | |
141 | ||
13143093 | 142 | struct z80_insn_info |
3dab9e15 SB |
143 | { |
144 | gdb_byte code; | |
145 | gdb_byte mask; | |
146 | gdb_byte size; /* without prefix(es) */ | |
cc55e4ef | 147 | enum z80_instruction_type type; |
3dab9e15 SB |
148 | }; |
149 | ||
150 | /* Constants */ | |
151 | ||
13143093 | 152 | static const struct z80_insn_info * |
3dab9e15 SB |
153 | z80_get_insn_info (struct gdbarch *gdbarch, const gdb_byte *buf, int *size); |
154 | ||
155 | static const char *z80_reg_names[] = | |
156 | { | |
157 | /* 24 bit on eZ80, else 16 bit */ | |
158 | "af", "bc", "de", "hl", | |
159 | "sp", "pc", "ix", "iy", | |
160 | "af'", "bc'", "de'", "hl'", | |
161 | "ir", | |
162 | /* eZ80 only */ | |
163 | "sps" | |
164 | }; | |
165 | ||
166 | /* Return the name of register REGNUM. */ | |
167 | static const char * | |
168 | z80_register_name (struct gdbarch *gdbarch, int regnum) | |
169 | { | |
9b9e61c7 | 170 | if (regnum < ARRAY_SIZE (z80_reg_names)) |
3dab9e15 SB |
171 | return z80_reg_names[regnum]; |
172 | ||
9b9e61c7 | 173 | return ""; |
3dab9e15 SB |
174 | } |
175 | ||
176 | /* Return the type of a register specified by the architecture. Only | |
177 | the register cache should call this function directly; others should | |
178 | use "register_type". */ | |
179 | static struct type * | |
180 | z80_register_type (struct gdbarch *gdbarch, int reg_nr) | |
181 | { | |
182 | return builtin_type (gdbarch)->builtin_data_ptr; | |
183 | } | |
184 | ||
185 | /* The next 2 functions check BUF for instruction. If it is pop/push rr, then | |
186 | it returns register number OR'ed with 0x100 */ | |
187 | static int | |
188 | z80_is_pop_rr (const gdb_byte buf[], int *size) | |
189 | { | |
190 | switch (buf[0]) | |
191 | { | |
192 | case 0xc1: | |
193 | *size = 1; | |
194 | return Z80_BC_REGNUM | 0x100; | |
195 | case 0xd1: | |
196 | *size = 1; | |
197 | return Z80_DE_REGNUM | 0x100; | |
198 | case 0xe1: | |
199 | *size = 1; | |
200 | return Z80_HL_REGNUM | 0x100; | |
201 | case 0xf1: | |
202 | *size = 1; | |
203 | return Z80_AF_REGNUM | 0x100; | |
204 | case 0xdd: | |
205 | *size = 2; | |
206 | return (buf[1] == 0xe1) ? (Z80_IX_REGNUM | 0x100) : 0; | |
207 | case 0xfd: | |
208 | *size = 2; | |
209 | return (buf[1] == 0xe1) ? (Z80_IY_REGNUM | 0x100) : 0; | |
210 | } | |
211 | *size = 0; | |
212 | return 0; | |
213 | } | |
214 | ||
215 | static int | |
216 | z80_is_push_rr (const gdb_byte buf[], int *size) | |
217 | { | |
218 | switch (buf[0]) | |
219 | { | |
220 | case 0xc5: | |
221 | *size = 1; | |
222 | return Z80_BC_REGNUM | 0x100; | |
223 | case 0xd5: | |
224 | *size = 1; | |
225 | return Z80_DE_REGNUM | 0x100; | |
226 | case 0xe5: | |
227 | *size = 1; | |
228 | return Z80_HL_REGNUM | 0x100; | |
229 | case 0xf5: | |
230 | *size = 1; | |
231 | return Z80_AF_REGNUM | 0x100; | |
232 | case 0xdd: | |
233 | *size = 2; | |
234 | return (buf[1] == 0xe5) ? (Z80_IX_REGNUM | 0x100) : 0; | |
235 | case 0xfd: | |
236 | *size = 2; | |
237 | return (buf[1] == 0xe5) ? (Z80_IY_REGNUM | 0x100) : 0; | |
238 | } | |
239 | *size = 0; | |
240 | return 0; | |
241 | } | |
242 | ||
243 | /* Function: z80_scan_prologue | |
244 | ||
245 | This function decodes a function prologue to determine: | |
246 | 1) the size of the stack frame | |
247 | 2) which registers are saved on it | |
248 | 3) the offsets of saved regs | |
249 | This information is stored in the z80_unwind_cache structure. | |
250 | Small SDCC functions may just load args using POP instructions in prologue: | |
251 | pop af | |
252 | pop de | |
253 | pop hl | |
254 | pop bc | |
255 | push bc | |
256 | push hl | |
257 | push de | |
258 | push af | |
259 | SDCC function prologue may have up to 3 sections (all are optional): | |
260 | 1) save state | |
261 | a) __critical functions: | |
262 | ld a,i | |
263 | di | |
264 | push af | |
265 | b) __interrupt (both int and nmi) functions: | |
266 | push af | |
267 | push bc | |
268 | push de | |
269 | push hl | |
270 | push iy | |
271 | 2) save and adjust frame pointer | |
272 | a) call to special function (size optimization) | |
273 | call ___sdcc_enter_ix | |
274 | b) inline (speed optimization) | |
275 | push ix | |
276 | ld ix, #0 | |
277 | add ix, sp | |
278 | c) without FP, but saving it (IX is optimized out) | |
279 | push ix | |
280 | 3) allocate local variables | |
281 | a) via series of PUSH AF and optional DEC SP (size optimization) | |
282 | push af | |
283 | ... | |
284 | push af | |
285 | dec sp ;optional, if allocated odd numbers of bytes | |
286 | b) via SP decrements | |
287 | dec sp | |
288 | ... | |
289 | dec sp | |
290 | c) via addition (for large frames: 5+ for speed and 9+ for size opt.) | |
291 | ld hl, #xxxx ;size of stack frame | |
292 | add hl, sp | |
293 | ld sp, hl | |
294 | d) same, but using register IY (arrays or for __z88dk_fastcall functions) | |
295 | ld iy, #xxxx ;size of stack frame | |
296 | add iy, sp | |
297 | ld sp, iy | |
298 | e) same as c, but for eZ80 | |
299 | lea hl, ix - #nn | |
300 | ld sp, hl | |
301 | f) same as d, but for eZ80 | |
302 | lea iy, ix - #nn | |
303 | ld sp, iy | |
304 | */ | |
305 | ||
306 | static int | |
307 | z80_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end, | |
308 | struct z80_unwind_cache *info) | |
309 | { | |
310 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | |
08106042 | 311 | z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch); |
345bd07c | 312 | int addr_len = tdep->addr_length; |
3dab9e15 SB |
313 | gdb_byte prologue[32]; /* max prologue is 24 bytes: __interrupt with local array */ |
314 | int pos = 0; | |
315 | int len; | |
316 | int reg; | |
317 | CORE_ADDR value; | |
318 | ||
319 | len = pc_end - pc_beg; | |
320 | if (len > (int)sizeof (prologue)) | |
321 | len = sizeof (prologue); | |
322 | ||
323 | read_memory (pc_beg, prologue, len); | |
324 | ||
325 | /* stage0: check for series of POPs and then PUSHs */ | |
326 | if ((reg = z80_is_pop_rr(prologue, &pos))) | |
327 | { | |
328 | int i; | |
329 | int size = pos; | |
330 | gdb_byte regs[8]; /* Z80 have only 6 register pairs */ | |
331 | regs[0] = reg & 0xff; | |
332 | for (i = 1; i < 8 && (regs[i] = z80_is_pop_rr (&prologue[pos], &size)); | |
333 | ++i, pos += size); | |
334 | /* now we expect series of PUSHs in reverse order */ | |
335 | for (--i; i >= 0 && regs[i] == z80_is_push_rr (&prologue[pos], &size); | |
336 | --i, pos += size); | |
337 | if (i == -1 && pos > 0) | |
338 | info->prologue_type.load_args = 1; | |
339 | else | |
340 | pos = 0; | |
341 | } | |
342 | /* stage1: check for __interrupt handlers and __critical functions */ | |
343 | else if (!memcmp (&prologue[pos], "\355\127\363\365", 4)) | |
344 | { /* ld a, i; di; push af */ | |
345 | info->prologue_type.critical = 1; | |
346 | pos += 4; | |
347 | info->state_size += addr_len; | |
348 | } | |
349 | else if (!memcmp (&prologue[pos], "\365\305\325\345\375\345", 6)) | |
350 | { /* push af; push bc; push de; push hl; push iy */ | |
351 | info->prologue_type.interrupt = 1; | |
352 | pos += 6; | |
353 | info->state_size += addr_len * 5; | |
354 | } | |
355 | ||
356 | /* stage2: check for FP saving scheme */ | |
357 | if (prologue[pos] == 0xcd) /* call nn */ | |
358 | { | |
359 | struct bound_minimal_symbol msymbol; | |
360 | msymbol = lookup_minimal_symbol ("__sdcc_enter_ix", NULL, NULL); | |
361 | if (msymbol.minsym) | |
362 | { | |
4aeddc50 | 363 | value = msymbol.value_address (); |
3dab9e15 SB |
364 | if (value == extract_unsigned_integer (&prologue[pos+1], addr_len, byte_order)) |
365 | { | |
366 | pos += 1 + addr_len; | |
367 | info->prologue_type.fp_sdcc = 1; | |
368 | } | |
369 | } | |
370 | } | |
371 | else if (!memcmp (&prologue[pos], "\335\345\335\041\000\000", 4+addr_len) && | |
372 | !memcmp (&prologue[pos+4+addr_len], "\335\071\335\371", 4)) | |
373 | { /* push ix; ld ix, #0; add ix, sp; ld sp, ix */ | |
374 | pos += 4 + addr_len + 4; | |
375 | info->prologue_type.fp_sdcc = 1; | |
376 | } | |
377 | else if (!memcmp (&prologue[pos], "\335\345", 2)) | |
378 | { /* push ix */ | |
379 | pos += 2; | |
380 | info->prologue_type.fp_sdcc = 1; | |
381 | } | |
382 | ||
383 | /* stage3: check for local variables allocation */ | |
384 | switch (prologue[pos]) | |
385 | { | |
386 | case 0xf5: /* push af */ | |
387 | info->size = 0; | |
388 | while (prologue[pos] == 0xf5) | |
389 | { | |
390 | info->size += addr_len; | |
391 | pos++; | |
392 | } | |
393 | if (prologue[pos] == 0x3b) /* dec sp */ | |
394 | { | |
395 | info->size++; | |
396 | pos++; | |
397 | } | |
398 | break; | |
399 | case 0x3b: /* dec sp */ | |
400 | info->size = 0; | |
401 | while (prologue[pos] == 0x3b) | |
402 | { | |
403 | info->size++; | |
404 | pos++; | |
405 | } | |
406 | break; | |
407 | case 0x21: /*ld hl, -nn */ | |
408 | if (prologue[pos+addr_len] == 0x39 && prologue[pos+addr_len] >= 0x80 && | |
409 | prologue[pos+addr_len+1] == 0xf9) | |
410 | { /* add hl, sp; ld sp, hl */ | |
411 | info->size = -extract_signed_integer(&prologue[pos+1], addr_len, byte_order); | |
412 | pos += 1 + addr_len + 2; | |
413 | } | |
414 | break; | |
415 | case 0xfd: /* ld iy, -nn */ | |
416 | if (prologue[pos+1] == 0x21 && prologue[pos+1+addr_len] >= 0x80 && | |
417 | !memcmp (&prologue[pos+2+addr_len], "\375\071\375\371", 4)) | |
418 | { | |
419 | info->size = -extract_signed_integer(&prologue[pos+2], addr_len, byte_order); | |
420 | pos += 2 + addr_len + 4; | |
421 | } | |
422 | break; | |
423 | case 0xed: /* check for lea xx, ix - n */ | |
424 | switch (prologue[pos+1]) | |
425 | { | |
426 | case 0x22: /* lea hl, ix - n */ | |
427 | if (prologue[pos+2] >= 0x80 && prologue[pos+3] == 0xf9) | |
428 | { /* ld sp, hl */ | |
429 | info->size = -extract_signed_integer(&prologue[pos+2], 1, byte_order); | |
430 | pos += 4; | |
431 | } | |
432 | break; | |
433 | case 0x55: /* lea iy, ix - n */ | |
434 | if (prologue[pos+2] >= 0x80 && prologue[pos+3] == 0xfd && | |
435 | prologue[pos+4] == 0xf9) | |
436 | { /* ld sp, iy */ | |
437 | info->size = -extract_signed_integer(&prologue[pos+2], 1, byte_order); | |
438 | pos += 5; | |
439 | } | |
440 | break; | |
441 | } | |
442 | break; | |
443 | } | |
444 | len = 0; | |
445 | ||
446 | if (info->prologue_type.interrupt) | |
447 | { | |
448 | info->saved_regs[Z80_AF_REGNUM].set_addr (len++); | |
449 | info->saved_regs[Z80_BC_REGNUM].set_addr (len++); | |
450 | info->saved_regs[Z80_DE_REGNUM].set_addr (len++); | |
451 | info->saved_regs[Z80_HL_REGNUM].set_addr (len++); | |
452 | info->saved_regs[Z80_IY_REGNUM].set_addr (len++); | |
453 | } | |
454 | ||
455 | if (info->prologue_type.critical) | |
456 | len++; /* just skip IFF2 saved state */ | |
457 | ||
458 | if (info->prologue_type.fp_sdcc) | |
459 | info->saved_regs[Z80_IX_REGNUM].set_addr (len++); | |
460 | ||
461 | info->state_size += len * addr_len; | |
462 | ||
463 | return pc_beg + pos; | |
464 | } | |
465 | ||
466 | static CORE_ADDR | |
467 | z80_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) | |
468 | { | |
469 | CORE_ADDR func_addr, func_end; | |
470 | CORE_ADDR prologue_end; | |
471 | ||
472 | if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) | |
473 | return pc; | |
474 | ||
475 | prologue_end = skip_prologue_using_sal (gdbarch, func_addr); | |
476 | if (prologue_end != 0) | |
477 | return std::max (pc, prologue_end); | |
478 | ||
479 | { | |
480 | struct z80_unwind_cache info = {0}; | |
481 | struct trad_frame_saved_reg saved_regs[Z80_NUM_REGS]; | |
482 | ||
483 | info.saved_regs = saved_regs; | |
484 | ||
485 | /* Need to run the prologue scanner to figure out if the function has a | |
486 | prologue. */ | |
487 | ||
488 | prologue_end = z80_scan_prologue (gdbarch, func_addr, func_end, &info); | |
489 | ||
490 | if (info.prologue_type.fp_sdcc || info.prologue_type.interrupt || | |
491 | info.prologue_type.critical) | |
492 | return std::max (pc, prologue_end); | |
493 | } | |
494 | ||
495 | if (prologue_end != 0) | |
496 | { | |
497 | struct symtab_and_line prologue_sal = find_pc_line (func_addr, 0); | |
c6159652 | 498 | struct compunit_symtab *compunit = prologue_sal.symtab->compunit (); |
422f1ea2 | 499 | const char *debug_format = compunit->debugformat (); |
3dab9e15 SB |
500 | |
501 | if (debug_format != NULL && | |
502 | !strncasecmp ("dwarf", debug_format, strlen("dwarf"))) | |
503 | return std::max (pc, prologue_end); | |
504 | } | |
505 | ||
506 | return pc; | |
507 | } | |
508 | ||
509 | /* Return the return-value convention that will be used by FUNCTION | |
510 | to return a value of type VALTYPE. FUNCTION may be NULL in which | |
511 | case the return convention is computed based only on VALTYPE. | |
512 | ||
513 | If READBUF is not NULL, extract the return value and save it in this buffer. | |
514 | ||
515 | If WRITEBUF is not NULL, it contains a return value which will be | |
516 | stored into the appropriate register. This can be used when we want | |
517 | to force the value returned by a function (see the "return" command | |
518 | for instance). */ | |
519 | static enum return_value_convention | |
520 | z80_return_value (struct gdbarch *gdbarch, struct value *function, | |
521 | struct type *valtype, struct regcache *regcache, | |
522 | gdb_byte *readbuf, const gdb_byte *writebuf) | |
523 | { | |
524 | /* Byte are returned in L, word in HL, dword in DEHL. */ | |
df86565b | 525 | int len = valtype->length (); |
3dab9e15 SB |
526 | |
527 | if ((valtype->code () == TYPE_CODE_STRUCT | |
528 | || valtype->code () == TYPE_CODE_UNION | |
529 | || valtype->code () == TYPE_CODE_ARRAY) | |
530 | && len > 4) | |
531 | return RETURN_VALUE_STRUCT_CONVENTION; | |
532 | ||
533 | if (writebuf != NULL) | |
534 | { | |
535 | if (len > 2) | |
536 | { | |
537 | regcache->cooked_write_part (Z80_DE_REGNUM, 0, len - 2, writebuf+2); | |
538 | len = 2; | |
539 | } | |
540 | regcache->cooked_write_part (Z80_HL_REGNUM, 0, len, writebuf); | |
541 | } | |
542 | ||
543 | if (readbuf != NULL) | |
544 | { | |
545 | if (len > 2) | |
546 | { | |
547 | regcache->cooked_read_part (Z80_DE_REGNUM, 0, len - 2, readbuf+2); | |
548 | len = 2; | |
549 | } | |
550 | regcache->cooked_read_part (Z80_HL_REGNUM, 0, len, readbuf); | |
551 | } | |
552 | ||
553 | return RETURN_VALUE_REGISTER_CONVENTION; | |
554 | } | |
555 | ||
556 | /* function unwinds current stack frame and returns next one */ | |
557 | static struct z80_unwind_cache * | |
bd2b40ac | 558 | z80_frame_unwind_cache (frame_info_ptr this_frame, |
3dab9e15 SB |
559 | void **this_prologue_cache) |
560 | { | |
561 | CORE_ADDR start_pc, current_pc; | |
562 | ULONGEST this_base; | |
563 | int i; | |
564 | gdb_byte buf[sizeof(void*)]; | |
565 | struct z80_unwind_cache *info; | |
566 | struct gdbarch *gdbarch = get_frame_arch (this_frame); | |
08106042 | 567 | z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch); |
345bd07c | 568 | int addr_len = tdep->addr_length; |
3dab9e15 SB |
569 | |
570 | if (*this_prologue_cache) | |
571 | return (struct z80_unwind_cache *) *this_prologue_cache; | |
572 | ||
573 | info = FRAME_OBSTACK_ZALLOC (struct z80_unwind_cache); | |
574 | memset (info, 0, sizeof (*info)); | |
575 | info->saved_regs = trad_frame_alloc_saved_regs (this_frame); | |
576 | *this_prologue_cache = info; | |
577 | ||
578 | start_pc = get_frame_func (this_frame); | |
579 | current_pc = get_frame_pc (this_frame); | |
580 | if ((start_pc > 0) && (start_pc <= current_pc)) | |
581 | z80_scan_prologue (get_frame_arch (this_frame), | |
582 | start_pc, current_pc, info); | |
583 | ||
584 | if (info->prologue_type.fp_sdcc) | |
585 | { | |
586 | /* With SDCC standard prologue, IX points to the end of current frame | |
587 | (where previous frame pointer and state are saved). */ | |
588 | this_base = get_frame_register_unsigned (this_frame, Z80_IX_REGNUM); | |
589 | info->prev_sp = this_base + info->size; | |
590 | } | |
591 | else | |
592 | { | |
593 | CORE_ADDR addr; | |
594 | CORE_ADDR sp; | |
595 | CORE_ADDR sp_mask = (1 << gdbarch_ptr_bit(gdbarch)) - 1; | |
596 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | |
597 | /* Assume that the FP is this frame's SP but with that pushed | |
598 | stack space added back. */ | |
599 | this_base = get_frame_register_unsigned (this_frame, Z80_SP_REGNUM); | |
600 | sp = this_base + info->size; | |
601 | for (;; ++sp) | |
602 | { | |
603 | sp &= sp_mask; | |
604 | if (sp < this_base) | |
605 | { /* overflow, looks like end of stack */ | |
606 | sp = this_base + info->size; | |
607 | break; | |
608 | } | |
609 | /* find return address */ | |
610 | read_memory (sp, buf, addr_len); | |
611 | addr = extract_unsigned_integer(buf, addr_len, byte_order); | |
612 | read_memory (addr-addr_len-1, buf, addr_len+1); | |
613 | if (buf[0] == 0xcd || (buf[0] & 0307) == 0304) /* Is it CALL */ | |
614 | { /* CALL nn or CALL cc,nn */ | |
615 | static const char *names[] = | |
616 | { | |
617 | "__sdcc_call_ix", "__sdcc_call_iy", "__sdcc_call_hl" | |
618 | }; | |
619 | addr = extract_unsigned_integer(buf+1, addr_len, byte_order); | |
620 | if (addr == start_pc) | |
621 | break; /* found */ | |
622 | for (i = sizeof(names)/sizeof(*names)-1; i >= 0; --i) | |
623 | { | |
624 | struct bound_minimal_symbol msymbol; | |
625 | msymbol = lookup_minimal_symbol (names[i], NULL, NULL); | |
626 | if (!msymbol.minsym) | |
627 | continue; | |
4aeddc50 | 628 | if (addr == msymbol.value_address ()) |
3dab9e15 SB |
629 | break; |
630 | } | |
631 | if (i >= 0) | |
632 | break; | |
633 | continue; | |
634 | } | |
635 | else | |
636 | continue; /* it is not call_nn, call_cc_nn */ | |
637 | } | |
638 | info->prev_sp = sp; | |
639 | } | |
640 | ||
641 | /* Adjust all the saved registers so that they contain addresses and not | |
642 | offsets. */ | |
643 | for (i = 0; i < gdbarch_num_regs (gdbarch) - 1; i++) | |
644 | if (info->saved_regs[i].addr () > 0) | |
645 | info->saved_regs[i].set_addr | |
646 | (info->prev_sp - info->saved_regs[i].addr () * addr_len); | |
647 | ||
648 | /* Except for the startup code, the return PC is always saved on | |
649 | the stack and is at the base of the frame. */ | |
650 | info->saved_regs[Z80_PC_REGNUM].set_addr (info->prev_sp); | |
651 | ||
652 | /* The previous frame's SP needed to be computed. Save the computed | |
653 | value. */ | |
654 | info->saved_regs[Z80_SP_REGNUM].set_value (info->prev_sp + addr_len); | |
655 | return info; | |
656 | } | |
657 | ||
658 | /* Given a GDB frame, determine the address of the calling function's | |
659 | frame. This will be used to create a new GDB frame struct. */ | |
660 | static void | |
bd2b40ac | 661 | z80_frame_this_id (frame_info_ptr this_frame, void **this_cache, |
3dab9e15 SB |
662 | struct frame_id *this_id) |
663 | { | |
664 | struct frame_id id; | |
665 | struct z80_unwind_cache *info; | |
666 | CORE_ADDR base; | |
667 | CORE_ADDR func; | |
668 | ||
669 | /* The FUNC is easy. */ | |
670 | func = get_frame_func (this_frame); | |
671 | ||
672 | info = z80_frame_unwind_cache (this_frame, this_cache); | |
673 | /* Hopefully the prologue analysis either correctly determined the | |
674 | frame's base (which is the SP from the previous frame), or set | |
675 | that base to "NULL". */ | |
676 | base = info->prev_sp; | |
677 | if (base == 0) | |
678 | return; | |
679 | ||
680 | id = frame_id_build (base, func); | |
681 | *this_id = id; | |
682 | } | |
683 | ||
684 | static struct value * | |
bd2b40ac | 685 | z80_frame_prev_register (frame_info_ptr this_frame, |
3dab9e15 SB |
686 | void **this_prologue_cache, int regnum) |
687 | { | |
688 | struct z80_unwind_cache *info | |
689 | = z80_frame_unwind_cache (this_frame, this_prologue_cache); | |
690 | ||
691 | if (regnum == Z80_PC_REGNUM) | |
692 | { | |
693 | if (info->saved_regs[Z80_PC_REGNUM].is_addr ()) | |
694 | { | |
695 | /* Reading the return PC from the PC register is slightly | |
696 | abnormal. */ | |
697 | ULONGEST pc; | |
698 | gdb_byte buf[3]; | |
699 | struct gdbarch *gdbarch = get_frame_arch (this_frame); | |
08106042 | 700 | z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch); |
3dab9e15 SB |
701 | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
702 | ||
703 | read_memory (info->saved_regs[Z80_PC_REGNUM].addr (), | |
704 | buf, tdep->addr_length); | |
705 | pc = extract_unsigned_integer (buf, tdep->addr_length, byte_order); | |
706 | return frame_unwind_got_constant (this_frame, regnum, pc); | |
707 | } | |
708 | ||
709 | return frame_unwind_got_optimized (this_frame, regnum); | |
710 | } | |
711 | ||
712 | return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); | |
713 | } | |
714 | ||
715 | /* Return the breakpoint kind for this target based on *PCPTR. */ | |
716 | static int | |
717 | z80_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) | |
718 | { | |
719 | static int addr = -1; | |
720 | if (addr == -1) | |
721 | { | |
722 | struct bound_minimal_symbol bh; | |
723 | bh = lookup_minimal_symbol ("_break_handler", NULL, NULL); | |
724 | if (bh.minsym) | |
4aeddc50 | 725 | addr = bh.value_address (); |
3dab9e15 SB |
726 | else |
727 | { | |
728 | warning(_("Unable to determine inferior's software breakpoint type: " | |
729 | "couldn't find `_break_handler' function in inferior. Will " | |
730 | "be used default software breakpoint instruction RST 0x08.")); | |
731 | addr = 0x0008; | |
732 | } | |
733 | } | |
734 | return addr; | |
735 | } | |
736 | ||
737 | /* Return the software breakpoint from KIND. KIND is just address of breakpoint | |
738 | handler. If address is on of standard RSTs, then RST n instruction is used | |
739 | as breakpoint. | |
740 | SIZE is set to the software breakpoint's length in memory. */ | |
741 | static const gdb_byte * | |
742 | z80_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) | |
743 | { | |
744 | static gdb_byte break_insn[8]; | |
745 | ||
746 | if ((kind & 070) == kind) | |
747 | { | |
748 | break_insn[0] = kind | 0307; | |
749 | *size = 1; | |
750 | } | |
33b5899f | 751 | else /* kind is non-RST address, use CALL instead, but it is dangerous */ |
3dab9e15 | 752 | { |
08106042 | 753 | z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch); |
3dab9e15 SB |
754 | gdb_byte *p = break_insn; |
755 | *p++ = 0xcd; | |
756 | *p++ = (kind >> 0) & 0xff; | |
757 | *p++ = (kind >> 8) & 0xff; | |
345bd07c | 758 | if (tdep->addr_length > 2) |
3dab9e15 SB |
759 | *p++ = (kind >> 16) & 0xff; |
760 | *size = p - break_insn; | |
761 | } | |
762 | return break_insn; | |
763 | } | |
764 | ||
765 | /* Return a vector of addresses on which the software single step | |
766 | breakpoints should be inserted. NULL means software single step is | |
767 | not used. | |
768 | Only one breakpoint address will be returned: conditional branches | |
769 | will be always evaluated. */ | |
770 | static std::vector<CORE_ADDR> | |
771 | z80_software_single_step (struct regcache *regcache) | |
772 | { | |
773 | static const int flag_mask[] = {1 << 6, 1 << 0, 1 << 2, 1 << 7}; | |
774 | gdb_byte buf[8]; | |
775 | ULONGEST t; | |
776 | ULONGEST addr; | |
777 | int opcode; | |
778 | int size; | |
13143093 | 779 | const struct z80_insn_info *info; |
3dab9e15 | 780 | std::vector<CORE_ADDR> ret (1); |
99d9c3b9 | 781 | gdbarch *gdbarch = current_inferior ()->arch (); |
3dab9e15 SB |
782 | |
783 | regcache->cooked_read (Z80_PC_REGNUM, &addr); | |
784 | read_memory (addr, buf, sizeof(buf)); | |
785 | info = z80_get_insn_info (gdbarch, buf, &size); | |
786 | ret[0] = addr + size; | |
787 | if (info == NULL) /* possible in case of double prefix */ | |
788 | { /* forced NOP, TODO: replace by NOP */ | |
789 | return ret; | |
790 | } | |
791 | opcode = buf[size - info->size]; /* take opcode instead of prefix */ | |
792 | /* stage 1: check for conditions */ | |
793 | switch (info->type) | |
794 | { | |
795 | case insn_djnz_d: | |
796 | regcache->cooked_read (Z80_BC_REGNUM, &t); | |
797 | if ((t & 0xff00) != 0x100) | |
798 | return ret; | |
799 | break; | |
800 | case insn_jr_cc_d: | |
801 | opcode &= 030; /* JR NZ,d has cc equal to 040, but others 000 */ | |
d182e398 | 802 | [[fallthrough]]; |
3dab9e15 SB |
803 | case insn_jp_cc_nn: |
804 | case insn_call_cc_nn: | |
805 | case insn_ret_cc: | |
806 | regcache->cooked_read (Z80_AF_REGNUM, &t); | |
807 | /* lower bit of condition inverts match, so invert flags if set */ | |
808 | if ((opcode & 010) != 0) | |
809 | t = ~t; | |
810 | /* two higher bits of condition field defines flag, so use them only | |
811 | to check condition of "not execute" */ | |
812 | if (t & flag_mask[(opcode >> 4) & 3]) | |
813 | return ret; | |
814 | break; | |
815 | } | |
816 | /* stage 2: compute address */ | |
817 | /* TODO: implement eZ80 MADL support */ | |
818 | switch (info->type) | |
819 | { | |
820 | default: | |
821 | return ret; | |
822 | case insn_djnz_d: | |
823 | case insn_jr_d: | |
824 | case insn_jr_cc_d: | |
825 | addr += size; | |
826 | addr += (signed char)buf[size-1]; | |
827 | break; | |
828 | case insn_jp_rr: | |
829 | if (size == 1) | |
830 | opcode = Z80_HL_REGNUM; | |
831 | else | |
832 | opcode = (buf[size-2] & 0x20) ? Z80_IY_REGNUM : Z80_IX_REGNUM; | |
833 | regcache->cooked_read (opcode, &addr); | |
834 | break; | |
835 | case insn_jp_nn: | |
836 | case insn_jp_cc_nn: | |
837 | case insn_call_nn: | |
838 | case insn_call_cc_nn: | |
839 | addr = buf[size-1] * 0x100 + buf[size-2]; | |
840 | if (info->size > 3) /* long instruction mode */ | |
841 | addr = addr * 0x100 + buf[size-3]; | |
842 | break; | |
843 | case insn_rst_n: | |
844 | addr = opcode & 070; | |
845 | break; | |
846 | case insn_ret: | |
847 | case insn_ret_cc: | |
848 | regcache->cooked_read (Z80_SP_REGNUM, &addr); | |
849 | read_memory (addr, buf, 3); | |
850 | addr = buf[1] * 0x100 + buf[0]; | |
851 | if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ez80_adl) | |
852 | addr = addr * 0x100 + buf[2]; | |
853 | break; | |
854 | } | |
855 | ret[0] = addr; | |
856 | return ret; | |
857 | } | |
858 | ||
859 | /* Cached, dynamically allocated copies of the target data structures: */ | |
860 | static unsigned (*cache_ovly_region_table)[3] = 0; | |
861 | static unsigned cache_novly_regions; | |
862 | static CORE_ADDR cache_ovly_region_table_base = 0; | |
c8e41b5f | 863 | enum z80_ovly_index |
3dab9e15 | 864 | { |
c8e41b5f | 865 | Z80_VMA, Z80_OSIZE, Z80_MAPPED_TO_LMA |
3dab9e15 SB |
866 | }; |
867 | ||
868 | static void | |
869 | z80_free_overlay_region_table (void) | |
870 | { | |
871 | if (cache_ovly_region_table) | |
872 | xfree (cache_ovly_region_table); | |
873 | cache_novly_regions = 0; | |
874 | cache_ovly_region_table = NULL; | |
875 | cache_ovly_region_table_base = 0; | |
876 | } | |
877 | ||
878 | /* Read an array of ints of size SIZE from the target into a local buffer. | |
879 | Convert to host order. LEN is number of ints. */ | |
880 | ||
881 | static void | |
882 | read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, | |
883 | int len, int size, enum bfd_endian byte_order) | |
884 | { | |
885 | /* alloca is safe here, because regions array is very small. */ | |
886 | gdb_byte *buf = (gdb_byte *) alloca (len * size); | |
887 | int i; | |
888 | ||
889 | read_memory (memaddr, buf, len * size); | |
890 | for (i = 0; i < len; i++) | |
891 | myaddr[i] = extract_unsigned_integer (size * i + buf, size, byte_order); | |
892 | } | |
893 | ||
894 | static int | |
895 | z80_read_overlay_region_table () | |
896 | { | |
897 | struct bound_minimal_symbol novly_regions_msym; | |
898 | struct bound_minimal_symbol ovly_region_table_msym; | |
899 | struct gdbarch *gdbarch; | |
900 | int word_size; | |
901 | enum bfd_endian byte_order; | |
902 | ||
903 | z80_free_overlay_region_table (); | |
904 | novly_regions_msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL); | |
905 | if (! novly_regions_msym.minsym) | |
906 | { | |
907 | error (_("Error reading inferior's overlay table: " | |
908 | "couldn't find `_novly_regions'\n" | |
909 | "variable in inferior. Use `overlay manual' mode.")); | |
910 | return 0; | |
911 | } | |
912 | ||
913 | ovly_region_table_msym = lookup_bound_minimal_symbol ("_ovly_region_table"); | |
914 | if (! ovly_region_table_msym.minsym) | |
915 | { | |
916 | error (_("Error reading inferior's overlay table: couldn't find " | |
917 | "`_ovly_region_table'\n" | |
918 | "array in inferior. Use `overlay manual' mode.")); | |
919 | return 0; | |
920 | } | |
921 | ||
922 | const enum overlay_debugging_state save_ovly_dbg = overlay_debugging; | |
923 | /* prevent infinite recurse */ | |
924 | overlay_debugging = ovly_off; | |
925 | ||
926 | gdbarch = ovly_region_table_msym.objfile->arch (); | |
927 | word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; | |
928 | byte_order = gdbarch_byte_order (gdbarch); | |
929 | ||
4aeddc50 | 930 | cache_novly_regions = read_memory_integer (novly_regions_msym.value_address (), |
287de656 | 931 | 4, byte_order); |
3dab9e15 SB |
932 | cache_ovly_region_table |
933 | = (unsigned int (*)[3]) xmalloc (cache_novly_regions * | |
934 | sizeof (*cache_ovly_region_table)); | |
935 | cache_ovly_region_table_base | |
4aeddc50 | 936 | = ovly_region_table_msym.value_address (); |
3dab9e15 SB |
937 | read_target_long_array (cache_ovly_region_table_base, |
938 | (unsigned int *) cache_ovly_region_table, | |
939 | cache_novly_regions * 3, word_size, byte_order); | |
940 | ||
941 | overlay_debugging = save_ovly_dbg; | |
942 | return 1; /* SUCCESS */ | |
943 | } | |
944 | ||
945 | static int | |
946 | z80_overlay_update_1 (struct obj_section *osect) | |
947 | { | |
948 | int i; | |
949 | asection *bsect = osect->the_bfd_section; | |
950 | unsigned lma; | |
951 | unsigned vma = bfd_section_vma (bsect); | |
952 | ||
953 | /* find region corresponding to the section VMA */ | |
954 | for (i = 0; i < cache_novly_regions; i++) | |
c8e41b5f | 955 | if (cache_ovly_region_table[i][Z80_VMA] == vma) |
3dab9e15 SB |
956 | break; |
957 | if (i == cache_novly_regions) | |
958 | return 0; /* no such region */ | |
959 | ||
c8e41b5f | 960 | lma = cache_ovly_region_table[i][Z80_MAPPED_TO_LMA]; |
3dab9e15 SB |
961 | i = 0; |
962 | ||
963 | /* we have interest for sections with same VMA */ | |
964 | for (objfile *objfile : current_program_space->objfiles ()) | |
5250cbc8 TT |
965 | for (obj_section *sect : objfile->sections ()) |
966 | if (section_is_overlay (sect)) | |
3dab9e15 | 967 | { |
5250cbc8 TT |
968 | sect->ovly_mapped = (lma == bfd_section_lma (sect->the_bfd_section)); |
969 | i |= sect->ovly_mapped; /* true, if at least one section is mapped */ | |
3dab9e15 SB |
970 | } |
971 | return i; | |
972 | } | |
973 | ||
974 | /* Refresh overlay mapped state for section OSECT. */ | |
975 | static void | |
976 | z80_overlay_update (struct obj_section *osect) | |
977 | { | |
978 | /* Always need to read the entire table anew. */ | |
979 | if (!z80_read_overlay_region_table ()) | |
980 | return; | |
981 | ||
982 | /* Were we given an osect to look up? NULL means do all of them. */ | |
983 | if (osect != nullptr && z80_overlay_update_1 (osect)) | |
984 | return; | |
985 | ||
986 | /* Update all sections, even if only one was requested. */ | |
987 | for (objfile *objfile : current_program_space->objfiles ()) | |
5250cbc8 | 988 | for (obj_section *sect : objfile->sections ()) |
3dab9e15 | 989 | { |
5250cbc8 | 990 | if (!section_is_overlay (sect)) |
3dab9e15 SB |
991 | continue; |
992 | ||
5250cbc8 | 993 | asection *bsect = sect->the_bfd_section; |
3dab9e15 SB |
994 | bfd_vma lma = bfd_section_lma (bsect); |
995 | bfd_vma vma = bfd_section_vma (bsect); | |
996 | ||
997 | for (int i = 0; i < cache_novly_regions; ++i) | |
c8e41b5f | 998 | if (cache_ovly_region_table[i][Z80_VMA] == vma) |
5250cbc8 | 999 | sect->ovly_mapped = |
c8e41b5f | 1000 | (cache_ovly_region_table[i][Z80_MAPPED_TO_LMA] == lma); |
3dab9e15 SB |
1001 | } |
1002 | } | |
1003 | ||
1004 | /* Return non-zero if the instruction at ADDR is a call; zero otherwise. */ | |
1005 | static int | |
1006 | z80_insn_is_call (struct gdbarch *gdbarch, CORE_ADDR addr) | |
1007 | { | |
1008 | gdb_byte buf[8]; | |
1009 | int size; | |
13143093 | 1010 | const struct z80_insn_info *info; |
3dab9e15 SB |
1011 | read_memory (addr, buf, sizeof(buf)); |
1012 | info = z80_get_insn_info (gdbarch, buf, &size); | |
1013 | if (info) | |
1014 | switch (info->type) | |
1015 | { | |
1016 | case insn_call_nn: | |
1017 | case insn_call_cc_nn: | |
1018 | case insn_rst_n: | |
1019 | return 1; | |
1020 | } | |
1021 | return 0; | |
1022 | } | |
1023 | ||
1024 | /* Return non-zero if the instruction at ADDR is a return; zero otherwise. */ | |
1025 | static int | |
1026 | z80_insn_is_ret (struct gdbarch *gdbarch, CORE_ADDR addr) | |
1027 | { | |
1028 | gdb_byte buf[8]; | |
1029 | int size; | |
13143093 | 1030 | const struct z80_insn_info *info; |
3dab9e15 SB |
1031 | read_memory (addr, buf, sizeof(buf)); |
1032 | info = z80_get_insn_info (gdbarch, buf, &size); | |
1033 | if (info) | |
1034 | switch (info->type) | |
1035 | { | |
1036 | case insn_ret: | |
1037 | case insn_ret_cc: | |
1038 | return 1; | |
1039 | } | |
1040 | return 0; | |
1041 | } | |
1042 | ||
1043 | /* Return non-zero if the instruction at ADDR is a jump; zero otherwise. */ | |
1044 | static int | |
1045 | z80_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr) | |
1046 | { | |
1047 | gdb_byte buf[8]; | |
1048 | int size; | |
13143093 | 1049 | const struct z80_insn_info *info; |
3dab9e15 SB |
1050 | read_memory (addr, buf, sizeof(buf)); |
1051 | info = z80_get_insn_info (gdbarch, buf, &size); | |
1052 | if (info) | |
1053 | switch (info->type) | |
1054 | { | |
1055 | case insn_jp_nn: | |
1056 | case insn_jp_cc_nn: | |
1057 | case insn_jp_rr: | |
1058 | case insn_jr_d: | |
1059 | case insn_jr_cc_d: | |
1060 | case insn_djnz_d: | |
1061 | return 1; | |
1062 | } | |
1063 | return 0; | |
1064 | } | |
1065 | ||
1066 | static const struct frame_unwind | |
1067 | z80_frame_unwind = | |
1068 | { | |
1069 | "z80", | |
1070 | NORMAL_FRAME, | |
1071 | default_frame_unwind_stop_reason, | |
1072 | z80_frame_this_id, | |
1073 | z80_frame_prev_register, | |
1074 | NULL, /*unwind_data*/ | |
1075 | default_frame_sniffer | |
1076 | /*dealloc_cache*/ | |
1077 | /*prev_arch*/ | |
1078 | }; | |
1079 | ||
1080 | /* Initialize the gdbarch struct for the Z80 arch */ | |
1081 | static struct gdbarch * | |
1082 | z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |
1083 | { | |
3dab9e15 SB |
1084 | struct gdbarch_list *best_arch; |
1085 | tdesc_arch_data_up tdesc_data; | |
1086 | unsigned long mach = info.bfd_arch_info->mach; | |
1087 | const struct target_desc *tdesc = info.target_desc; | |
1088 | ||
1089 | if (!tdesc_has_registers (tdesc)) | |
1090 | /* Pick a default target description. */ | |
1091 | tdesc = tdesc_z80; | |
1092 | ||
1093 | /* Check any target description for validity. */ | |
1094 | if (tdesc_has_registers (tdesc)) | |
1095 | { | |
1096 | const struct tdesc_feature *feature; | |
1097 | int valid_p; | |
1098 | ||
1099 | feature = tdesc_find_feature (tdesc, "org.gnu.gdb.z80.cpu"); | |
1100 | if (feature == NULL) | |
1101 | return NULL; | |
1102 | ||
1103 | tdesc_data = tdesc_data_alloc (); | |
1104 | ||
1105 | valid_p = 1; | |
1106 | ||
1107 | for (unsigned i = 0; i < Z80_NUM_REGS; i++) | |
1108 | valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i, | |
1109 | z80_reg_names[i]); | |
1110 | ||
1111 | if (!valid_p) | |
1112 | return NULL; | |
1113 | } | |
1114 | ||
1115 | /* If there is already a candidate, use it. */ | |
1116 | for (best_arch = gdbarch_list_lookup_by_info (arches, &info); | |
1117 | best_arch != NULL; | |
1118 | best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info)) | |
1119 | { | |
1120 | if (mach == gdbarch_bfd_arch_info (best_arch->gdbarch)->mach) | |
1121 | return best_arch->gdbarch; | |
1122 | } | |
1123 | ||
1124 | /* None found, create a new architecture from the information provided. */ | |
2b16913c SM |
1125 | gdbarch *gdbarch |
1126 | = gdbarch_alloc (&info, gdbarch_tdep_up (new z80_gdbarch_tdep)); | |
1127 | z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch); | |
3dab9e15 SB |
1128 | |
1129 | if (mach == bfd_mach_ez80_adl) | |
1130 | { | |
1131 | tdep->addr_length = 3; | |
1132 | set_gdbarch_max_insn_length (gdbarch, 6); | |
1133 | } | |
1134 | else | |
1135 | { | |
1136 | tdep->addr_length = 2; | |
1137 | set_gdbarch_max_insn_length (gdbarch, 4); | |
1138 | } | |
1139 | ||
1140 | /* Create a type for PC. We can't use builtin types here, as they may not | |
1141 | be defined. */ | |
cc495054 TT |
1142 | type_allocator alloc (gdbarch); |
1143 | tdep->void_type = alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, | |
1144 | "void"); | |
3dab9e15 | 1145 | tdep->func_void_type = make_function_type (tdep->void_type, NULL); |
9c794d2d | 1146 | tdep->pc_type = init_pointer_type (alloc, |
3dab9e15 SB |
1147 | tdep->addr_length * TARGET_CHAR_BIT, |
1148 | NULL, tdep->func_void_type); | |
1149 | ||
1150 | set_gdbarch_short_bit (gdbarch, TARGET_CHAR_BIT); | |
1151 | set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT); | |
1152 | set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT); | |
1153 | set_gdbarch_ptr_bit (gdbarch, tdep->addr_length * TARGET_CHAR_BIT); | |
1154 | set_gdbarch_addr_bit (gdbarch, tdep->addr_length * TARGET_CHAR_BIT); | |
1155 | ||
1156 | set_gdbarch_num_regs (gdbarch, (mach == bfd_mach_ez80_adl) ? EZ80_NUM_REGS | |
1157 | : Z80_NUM_REGS); | |
1158 | set_gdbarch_sp_regnum (gdbarch, Z80_SP_REGNUM); | |
1159 | set_gdbarch_pc_regnum (gdbarch, Z80_PC_REGNUM); | |
1160 | ||
1161 | set_gdbarch_register_name (gdbarch, z80_register_name); | |
1162 | set_gdbarch_register_type (gdbarch, z80_register_type); | |
1163 | ||
1164 | /* TODO: get FP type from binary (extra flags required) */ | |
1165 | set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); | |
1166 | set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); | |
1167 | set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); | |
1168 | set_gdbarch_float_format (gdbarch, floatformats_ieee_single); | |
1169 | set_gdbarch_double_format (gdbarch, floatformats_ieee_single); | |
1170 | set_gdbarch_long_double_format (gdbarch, floatformats_ieee_single); | |
1171 | ||
1172 | set_gdbarch_return_value (gdbarch, z80_return_value); | |
1173 | ||
1174 | set_gdbarch_skip_prologue (gdbarch, z80_skip_prologue); | |
1175 | set_gdbarch_inner_than (gdbarch, core_addr_lessthan); // falling stack | |
1176 | ||
1177 | set_gdbarch_software_single_step (gdbarch, z80_software_single_step); | |
1178 | set_gdbarch_breakpoint_kind_from_pc (gdbarch, z80_breakpoint_kind_from_pc); | |
1179 | set_gdbarch_sw_breakpoint_from_kind (gdbarch, z80_sw_breakpoint_from_kind); | |
1180 | set_gdbarch_insn_is_call (gdbarch, z80_insn_is_call); | |
1181 | set_gdbarch_insn_is_jump (gdbarch, z80_insn_is_jump); | |
1182 | set_gdbarch_insn_is_ret (gdbarch, z80_insn_is_ret); | |
1183 | ||
1184 | set_gdbarch_overlay_update (gdbarch, z80_overlay_update); | |
1185 | ||
1186 | frame_unwind_append_unwinder (gdbarch, &z80_frame_unwind); | |
1187 | if (tdesc_data) | |
1188 | tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data)); | |
1189 | ||
1190 | return gdbarch; | |
1191 | } | |
1192 | ||
1193 | /* Table to disassemble machine codes without prefix. */ | |
13143093 | 1194 | static const struct z80_insn_info |
3dab9e15 SB |
1195 | ez80_main_insn_table[] = |
1196 | { /* table with double prefix check */ | |
1197 | { 0100, 0377, 0, insn_force_nop}, //double prefix | |
1198 | { 0111, 0377, 0, insn_force_nop}, //double prefix | |
1199 | { 0122, 0377, 0, insn_force_nop}, //double prefix | |
1200 | { 0133, 0377, 0, insn_force_nop}, //double prefix | |
1201 | /* initial table for eZ80_z80 */ | |
1202 | { 0100, 0377, 1, insn_z80 }, //eZ80 mode prefix | |
1203 | { 0111, 0377, 1, insn_z80 }, //eZ80 mode prefix | |
1204 | { 0122, 0377, 1, insn_adl }, //eZ80 mode prefix | |
1205 | { 0133, 0377, 1, insn_adl }, //eZ80 mode prefix | |
1206 | /* here common Z80/Z180/eZ80 opcodes */ | |
1207 | { 0000, 0367, 1, insn_default }, //"nop", "ex af,af'" | |
1208 | { 0061, 0377, 3, insn_ld_sp_nn }, //"ld sp,nn" | |
1209 | { 0001, 0317, 3, insn_default }, //"ld rr,nn" | |
1210 | { 0002, 0347, 1, insn_default }, //"ld (rr),a", "ld a,(rr)" | |
1211 | { 0042, 0347, 3, insn_default }, //"ld (nn),hl/a", "ld hl/a,(nn)" | |
1212 | { 0063, 0377, 1, insn_inc_sp }, //"inc sp" | |
1213 | { 0073, 0377, 1, insn_dec_sp }, //"dec sp" | |
1214 | { 0003, 0303, 1, insn_default }, //"inc rr", "dec rr", ... | |
1215 | { 0004, 0307, 1, insn_default }, //"inc/dec r/(hl)" | |
1216 | { 0006, 0307, 2, insn_default }, //"ld r,n", "ld (hl),n" | |
1217 | { 0020, 0377, 2, insn_djnz_d }, //"djnz dis" | |
1218 | { 0030, 0377, 2, insn_jr_d }, //"jr dis" | |
1219 | { 0040, 0347, 2, insn_jr_cc_d }, //"jr cc,dis" | |
1220 | { 0100, 0300, 1, insn_default }, //"ld r,r", "halt" | |
1221 | { 0200, 0300, 1, insn_default }, //"alu_op a,r" | |
1222 | { 0300, 0307, 1, insn_ret_cc }, //"ret cc" | |
1223 | { 0301, 0317, 1, insn_pop_rr }, //"pop rr" | |
1224 | { 0302, 0307, 3, insn_jp_cc_nn }, //"jp cc,nn" | |
1225 | { 0303, 0377, 3, insn_jp_nn }, //"jp nn" | |
1226 | { 0304, 0307, 3, insn_call_cc_nn}, //"call cc,nn" | |
1227 | { 0305, 0317, 1, insn_push_rr }, //"push rr" | |
1228 | { 0306, 0307, 2, insn_default }, //"alu_op a,n" | |
1229 | { 0307, 0307, 1, insn_rst_n }, //"rst n" | |
1230 | { 0311, 0377, 1, insn_ret }, //"ret" | |
1231 | { 0313, 0377, 2, insn_default }, //CB prefix | |
1232 | { 0315, 0377, 3, insn_call_nn }, //"call nn" | |
1233 | { 0323, 0367, 2, insn_default }, //"out (n),a", "in a,(n)" | |
1234 | { 0335, 0337, 1, insn_z80_ddfd }, //DD/FD prefix | |
1235 | { 0351, 0377, 1, insn_jp_rr }, //"jp (hl)" | |
1236 | { 0355, 0377, 1, insn_z80_ed }, //ED prefix | |
1237 | { 0371, 0377, 1, insn_ld_sp_rr }, //"ld sp,hl" | |
1238 | { 0000, 0000, 1, insn_default } //others | |
1239 | } ; | |
1240 | ||
13143093 | 1241 | static const struct z80_insn_info |
3dab9e15 SB |
1242 | ez80_adl_main_insn_table[] = |
1243 | { /* table with double prefix check */ | |
1244 | { 0100, 0377, 0, insn_force_nop}, //double prefix | |
1245 | { 0111, 0377, 0, insn_force_nop}, //double prefix | |
1246 | { 0122, 0377, 0, insn_force_nop}, //double prefix | |
1247 | { 0133, 0377, 0, insn_force_nop}, //double prefix | |
1248 | /* initial table for eZ80_adl */ | |
1249 | { 0000, 0367, 1, insn_default }, //"nop", "ex af,af'" | |
1250 | { 0061, 0377, 4, insn_ld_sp_nn }, //"ld sp,Mmn" | |
1251 | { 0001, 0317, 4, insn_default }, //"ld rr,Mmn" | |
1252 | { 0002, 0347, 1, insn_default }, //"ld (rr),a", "ld a,(rr)" | |
1253 | { 0042, 0347, 4, insn_default }, //"ld (Mmn),hl/a", "ld hl/a,(Mmn)" | |
1254 | { 0063, 0377, 1, insn_inc_sp }, //"inc sp" | |
1255 | { 0073, 0377, 1, insn_dec_sp }, //"dec sp" | |
1256 | { 0003, 0303, 1, insn_default }, //"inc rr", "dec rr", ... | |
1257 | { 0004, 0307, 1, insn_default }, //"inc/dec r/(hl)" | |
1258 | { 0006, 0307, 2, insn_default }, //"ld r,n", "ld (hl),n" | |
1259 | { 0020, 0377, 2, insn_djnz_d }, //"djnz dis" | |
1260 | { 0030, 0377, 2, insn_jr_d }, //"jr dis" | |
1261 | { 0040, 0347, 2, insn_jr_cc_d }, //"jr cc,dis" | |
1262 | { 0100, 0377, 1, insn_z80 }, //eZ80 mode prefix (short instruction) | |
1263 | { 0111, 0377, 1, insn_z80 }, //eZ80 mode prefix (short instruction) | |
1264 | { 0122, 0377, 1, insn_adl }, //eZ80 mode prefix (long instruction) | |
1265 | { 0133, 0377, 1, insn_adl }, //eZ80 mode prefix (long instruction) | |
1266 | { 0100, 0300, 1, insn_default }, //"ld r,r", "halt" | |
1267 | { 0200, 0300, 1, insn_default }, //"alu_op a,r" | |
1268 | { 0300, 0307, 1, insn_ret_cc }, //"ret cc" | |
1269 | { 0301, 0317, 1, insn_pop_rr }, //"pop rr" | |
1270 | { 0302, 0307, 4, insn_jp_cc_nn }, //"jp cc,nn" | |
1271 | { 0303, 0377, 4, insn_jp_nn }, //"jp nn" | |
1272 | { 0304, 0307, 4, insn_call_cc_nn}, //"call cc,Mmn" | |
1273 | { 0305, 0317, 1, insn_push_rr }, //"push rr" | |
1274 | { 0306, 0307, 2, insn_default }, //"alu_op a,n" | |
1275 | { 0307, 0307, 1, insn_rst_n }, //"rst n" | |
1276 | { 0311, 0377, 1, insn_ret }, //"ret" | |
1277 | { 0313, 0377, 2, insn_default }, //CB prefix | |
1278 | { 0315, 0377, 4, insn_call_nn }, //"call Mmn" | |
1279 | { 0323, 0367, 2, insn_default }, //"out (n),a", "in a,(n)" | |
1280 | { 0335, 0337, 1, insn_adl_ddfd }, //DD/FD prefix | |
1281 | { 0351, 0377, 1, insn_jp_rr }, //"jp (hl)" | |
1282 | { 0355, 0377, 1, insn_adl_ed }, //ED prefix | |
1283 | { 0371, 0377, 1, insn_ld_sp_rr }, //"ld sp,hl" | |
1284 | { 0000, 0000, 1, insn_default } //others | |
1285 | }; | |
1286 | ||
1287 | /* ED prefix opcodes table. | |
1288 | Note the instruction length does include the ED prefix (+ 1 byte) | |
1289 | */ | |
13143093 | 1290 | static const struct z80_insn_info |
3dab9e15 SB |
1291 | ez80_ed_insn_table[] = |
1292 | { | |
1293 | /* eZ80 only instructions */ | |
1294 | { 0002, 0366, 2, insn_default }, //"lea rr,ii+d" | |
1295 | { 0124, 0376, 2, insn_default }, //"lea ix,iy+d", "lea iy,ix+d" | |
1296 | { 0145, 0377, 2, insn_default }, //"pea ix+d" | |
1297 | { 0146, 0377, 2, insn_default }, //"pea iy+d" | |
1298 | { 0164, 0377, 2, insn_default }, //"tstio n" | |
1299 | /* Z180/eZ80 only instructions */ | |
1300 | { 0060, 0376, 1, insn_default }, //not an instruction | |
1301 | { 0000, 0306, 2, insn_default }, //"in0 r,(n)", "out0 (n),r" | |
1302 | { 0144, 0377, 2, insn_default }, //"tst a, n" | |
1303 | /* common instructions */ | |
1304 | { 0173, 0377, 3, insn_ld_sp_6nn9 }, //"ld sp,(nn)" | |
1305 | { 0103, 0307, 3, insn_default }, //"ld (nn),rr", "ld rr,(nn)" | |
1306 | { 0105, 0317, 1, insn_ret }, //"retn", "reti" | |
1307 | { 0000, 0000, 1, insn_default } | |
1308 | }; | |
1309 | ||
13143093 | 1310 | static const struct z80_insn_info |
3dab9e15 SB |
1311 | ez80_adl_ed_insn_table[] = |
1312 | { | |
1313 | { 0002, 0366, 2, insn_default }, //"lea rr,ii+d" | |
1314 | { 0124, 0376, 2, insn_default }, //"lea ix,iy+d", "lea iy,ix+d" | |
1315 | { 0145, 0377, 2, insn_default }, //"pea ix+d" | |
1316 | { 0146, 0377, 2, insn_default }, //"pea iy+d" | |
1317 | { 0164, 0377, 2, insn_default }, //"tstio n" | |
1318 | { 0060, 0376, 1, insn_default }, //not an instruction | |
1319 | { 0000, 0306, 2, insn_default }, //"in0 r,(n)", "out0 (n),r" | |
1320 | { 0144, 0377, 2, insn_default }, //"tst a, n" | |
1321 | { 0173, 0377, 4, insn_ld_sp_6nn9 }, //"ld sp,(nn)" | |
1322 | { 0103, 0307, 4, insn_default }, //"ld (nn),rr", "ld rr,(nn)" | |
1323 | { 0105, 0317, 1, insn_ret }, //"retn", "reti" | |
1324 | { 0000, 0000, 1, insn_default } | |
1325 | }; | |
1326 | ||
1327 | /* table for FD and DD prefixed instructions */ | |
13143093 | 1328 | static const struct z80_insn_info |
3dab9e15 SB |
1329 | ez80_ddfd_insn_table[] = |
1330 | { | |
1331 | /* ez80 only instructions */ | |
1332 | { 0007, 0307, 2, insn_default }, //"ld rr,(ii+d)" | |
1333 | { 0061, 0377, 2, insn_default }, //"ld ii,(ii+d)" | |
1334 | /* common instructions */ | |
1335 | { 0011, 0367, 2, insn_default }, //"add ii,rr" | |
1336 | { 0041, 0377, 3, insn_default }, //"ld ii,nn" | |
1337 | { 0042, 0367, 3, insn_default }, //"ld (nn),ii", "ld ii,(nn)" | |
1338 | { 0043, 0367, 1, insn_default }, //"inc ii", "dec ii" | |
1339 | { 0044, 0366, 1, insn_default }, //"inc/dec iih/iil" | |
1340 | { 0046, 0367, 2, insn_default }, //"ld iih,n", "ld iil,n" | |
1341 | { 0064, 0376, 2, insn_default }, //"inc (ii+d)", "dec (ii+d)" | |
1342 | { 0066, 0377, 2, insn_default }, //"ld (ii+d),n" | |
1343 | { 0166, 0377, 0, insn_default }, //not an instruction | |
1344 | { 0160, 0370, 2, insn_default }, //"ld (ii+d),r" | |
1345 | { 0104, 0306, 1, insn_default }, //"ld r,iih", "ld r,iil" | |
1346 | { 0106, 0307, 2, insn_default }, //"ld r,(ii+d)" | |
1347 | { 0140, 0360, 1, insn_default }, //"ld iih,r", "ld iil,r" | |
1348 | { 0204, 0306, 1, insn_default }, //"alu_op a,iih", "alu_op a,iil" | |
1349 | { 0206, 0307, 2, insn_default }, //"alu_op a,(ii+d)" | |
1350 | { 0313, 0377, 3, insn_default }, //DD/FD CB dd oo instructions | |
1351 | { 0335, 0337, 0, insn_force_nop}, //double DD/FD prefix, exec DD/FD as NOP | |
1352 | { 0341, 0373, 1, insn_default }, //"pop ii", "push ii" | |
1353 | { 0343, 0377, 1, insn_default }, //"ex (sp),ii" | |
1354 | { 0351, 0377, 1, insn_jp_rr }, //"jp (ii)" | |
1355 | { 0371, 0377, 1, insn_ld_sp_rr}, //"ld sp,ii" | |
1356 | { 0000, 0000, 0, insn_default } //not an instruction, exec DD/FD as NOP | |
1357 | }; | |
1358 | ||
13143093 | 1359 | static const struct z80_insn_info |
3dab9e15 SB |
1360 | ez80_adl_ddfd_insn_table[] = |
1361 | { | |
1362 | { 0007, 0307, 2, insn_default }, //"ld rr,(ii+d)" | |
1363 | { 0061, 0377, 2, insn_default }, //"ld ii,(ii+d)" | |
1364 | { 0011, 0367, 1, insn_default }, //"add ii,rr" | |
1365 | { 0041, 0377, 4, insn_default }, //"ld ii,nn" | |
1366 | { 0042, 0367, 4, insn_default }, //"ld (nn),ii", "ld ii,(nn)" | |
1367 | { 0043, 0367, 1, insn_default }, //"inc ii", "dec ii" | |
1368 | { 0044, 0366, 1, insn_default }, //"inc/dec iih/iil" | |
1369 | { 0046, 0367, 2, insn_default }, //"ld iih,n", "ld iil,n" | |
1370 | { 0064, 0376, 2, insn_default }, //"inc (ii+d)", "dec (ii+d)" | |
1371 | { 0066, 0377, 3, insn_default }, //"ld (ii+d),n" | |
1372 | { 0166, 0377, 0, insn_default }, //not an instruction | |
1373 | { 0160, 0370, 2, insn_default }, //"ld (ii+d),r" | |
1374 | { 0104, 0306, 1, insn_default }, //"ld r,iih", "ld r,iil" | |
1375 | { 0106, 0307, 2, insn_default }, //"ld r,(ii+d)" | |
1376 | { 0140, 0360, 1, insn_default }, //"ld iih,r", "ld iil,r" | |
1377 | { 0204, 0306, 1, insn_default }, //"alu_op a,iih", "alu_op a,iil" | |
1378 | { 0206, 0307, 2, insn_default }, //"alu_op a,(ii+d)" | |
1379 | { 0313, 0377, 3, insn_default }, //DD/FD CB dd oo instructions | |
1380 | { 0335, 0337, 0, insn_force_nop}, //double DD/FD prefix, exec DD/FD as NOP | |
1381 | { 0341, 0373, 1, insn_default }, //"pop ii", "push ii" | |
1382 | { 0343, 0377, 1, insn_default }, //"ex (sp),ii" | |
1383 | { 0351, 0377, 1, insn_jp_rr }, //"jp (ii)" | |
1384 | { 0371, 0377, 1, insn_ld_sp_rr}, //"ld sp,ii" | |
1385 | { 0000, 0000, 0, insn_default } //not an instruction, exec DD/FD as NOP | |
1386 | }; | |
1387 | ||
1388 | /* Return pointer to instruction information structure corresponded to opcode | |
1389 | in buf. */ | |
13143093 | 1390 | static const struct z80_insn_info * |
3dab9e15 SB |
1391 | z80_get_insn_info (struct gdbarch *gdbarch, const gdb_byte *buf, int *size) |
1392 | { | |
1393 | int code; | |
13143093 | 1394 | const struct z80_insn_info *info; |
3dab9e15 SB |
1395 | unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach; |
1396 | *size = 0; | |
1397 | switch (mach) | |
1398 | { | |
1399 | case bfd_mach_ez80_z80: | |
1400 | info = &ez80_main_insn_table[4]; /* skip force_nops */ | |
1401 | break; | |
1402 | case bfd_mach_ez80_adl: | |
1403 | info = &ez80_adl_main_insn_table[4]; /* skip force_nops */ | |
1404 | break; | |
1405 | default: | |
3bfdcabb | 1406 | info = &ez80_main_insn_table[8]; /* skip eZ80 prefixes and force_nops */ |
3dab9e15 SB |
1407 | break; |
1408 | } | |
1409 | do | |
1410 | { | |
1411 | for (; ((code = buf[*size]) & info->mask) != info->code; ++info) | |
1412 | ; | |
1413 | *size += info->size; | |
1414 | /* process instruction type */ | |
1415 | switch (info->type) | |
1416 | { | |
1417 | case insn_z80: | |
1418 | if (mach == bfd_mach_ez80_z80 || mach == bfd_mach_ez80_adl) | |
1419 | info = &ez80_main_insn_table[0]; | |
1420 | else | |
1421 | info = &ez80_main_insn_table[8]; | |
1422 | break; | |
1423 | case insn_adl: | |
1424 | info = &ez80_adl_main_insn_table[0]; | |
1425 | break; | |
1426 | /* These two (for GameBoy Z80 & Z80 Next CPUs) haven't been tested. | |
1427 | ||
1428 | case bfd_mach_gbz80: | |
1429 | info = &gbz80_main_insn_table[0]; | |
1430 | break; | |
1431 | case bfd_mach_z80n: | |
1432 | info = &z80n_main_insn_table[0]; | |
1433 | break; | |
1434 | */ | |
1435 | case insn_z80_ddfd: | |
1436 | if (mach == bfd_mach_ez80_z80 || mach == bfd_mach_ez80_adl) | |
1437 | info = &ez80_ddfd_insn_table[0]; | |
1438 | else | |
1439 | info = &ez80_ddfd_insn_table[2]; | |
1440 | break; | |
1441 | case insn_adl_ddfd: | |
1442 | info = &ez80_adl_ddfd_insn_table[0]; | |
1443 | break; | |
1444 | case insn_z80_ed: | |
1445 | info = &ez80_ed_insn_table[0]; | |
1446 | break; | |
1447 | case insn_adl_ed: | |
1448 | info = &ez80_adl_ed_insn_table[0]; | |
1449 | break; | |
1450 | case insn_force_nop: | |
1451 | return NULL; | |
1452 | default: | |
1453 | return info; | |
1454 | } | |
1455 | } | |
1456 | while (1); | |
1457 | } | |
1458 | ||
1459 | extern initialize_file_ftype _initialize_z80_tdep; | |
1460 | ||
1461 | void | |
1462 | _initialize_z80_tdep () | |
1463 | { | |
ec29a63c | 1464 | gdbarch_register (bfd_arch_z80, z80_gdbarch_init); |
3dab9e15 SB |
1465 | initialize_tdesc_z80 (); |
1466 | } |