stack: fix gdb.dwarf2/dw2-undefined-ret-addr.exp regression
[deliverable/binutils-gdb.git] / gdb / moxie-tdep.c
CommitLineData
d7066cce
AG
1/* Target-dependent code for Moxie.
2
618f726f 3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
d7066cce
AG
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 "frame.h"
22#include "frame-unwind.h"
23#include "frame-base.h"
24#include "symtab.h"
25#include "gdbtypes.h"
26#include "gdbcmd.h"
27#include "gdbcore.h"
d7066cce
AG
28#include "value.h"
29#include "inferior.h"
30#include "symfile.h"
31#include "objfiles.h"
32#include "osabi.h"
33#include "language.h"
34#include "arch-utils.h"
35#include "regcache.h"
36#include "trad-frame.h"
37#include "dis-asm.h"
451fa05e 38#include "record.h"
d02ed0bb 39#include "record-full.h"
d7066cce 40
d7066cce 41#include "moxie-tdep.h"
325fac50 42#include <algorithm>
d7066cce
AG
43
44/* Local functions. */
45
46extern void _initialize_moxie_tdep (void);
47
48/* Use an invalid address value as 'not available' marker. */
49enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50
51struct moxie_frame_cache
52{
53 /* Base address. */
54 CORE_ADDR base;
55 CORE_ADDR pc;
56 LONGEST framesize;
57 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
58 CORE_ADDR saved_sp;
59};
60
61/* Implement the "frame_align" gdbarch method. */
62
63static CORE_ADDR
64moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65{
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
68 return sp & ~1;
69}
70
71/* Implement the "breakpoint_from_pc" gdbarch method. */
72
44d100c3 73static const unsigned char *
451fa05e 74moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
d7066cce
AG
75 CORE_ADDR *pcptr, int *lenptr)
76{
77 static unsigned char breakpoint[] = { 0x35, 0x00 };
78
79 *lenptr = sizeof (breakpoint);
80 return breakpoint;
81}
82
83/* Moxie register names. */
84
85char *moxie_register_names[] = {
86 "$fp", "$sp", "$r0", "$r1", "$r2",
87 "$r3", "$r4", "$r5", "$r6", "$r7",
88 "$r8", "$r9", "$r10", "$r11", "$r12",
89 "$r13", "$pc", "$cc" };
90
91/* Implement the "register_name" gdbarch method. */
92
93static const char *
94moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
95{
96 if (reg_nr < 0)
97 return NULL;
98 if (reg_nr >= MOXIE_NUM_REGS)
99 return NULL;
100 return moxie_register_names[reg_nr];
101}
102
103/* Implement the "register_type" gdbarch method. */
104
105static struct type *
106moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
107{
108 if (reg_nr == MOXIE_PC_REGNUM)
109 return builtin_type (gdbarch)->builtin_func_ptr;
110 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
111 return builtin_type (gdbarch)->builtin_data_ptr;
112 else
df4df182 113 return builtin_type (gdbarch)->builtin_int32;
d7066cce
AG
114}
115
116/* Write into appropriate registers a function return value
117 of type TYPE, given in virtual format. */
118
119static void
120moxie_store_return_value (struct type *type, struct regcache *regcache,
7c543f7b 121 const gdb_byte *valbuf)
d7066cce 122{
e17a4113
UW
123 struct gdbarch *gdbarch = get_regcache_arch (regcache);
124 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
125 CORE_ADDR regval;
126 int len = TYPE_LENGTH (type);
127
128 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
e17a4113 129 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
d7066cce
AG
130 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
131 if (len > 4)
132 {
7c543f7b 133 regval = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
d7066cce
AG
134 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
135 }
136}
137
138/* Decode the instructions within the given address range. Decide
139 when we must have reached the end of the function prologue. If a
140 frame_info pointer is provided, fill in its saved_regs etc.
141
142 Returns the address of the first instruction after the prologue. */
143
144static CORE_ADDR
145moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
99f75275
AG
146 struct moxie_frame_cache *cache,
147 struct gdbarch *gdbarch)
d7066cce 148{
e17a4113 149 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
150 CORE_ADDR next_addr;
151 ULONGEST inst, inst2;
152 LONGEST offset;
153 int regnum;
154
155 /* Record where the jsra instruction saves the PC and FP. */
156 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
157 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
158 cache->framesize = 0;
159
160 if (start_addr >= end_addr)
161 return end_addr;
162
163 for (next_addr = start_addr; next_addr < end_addr; )
164 {
e17a4113 165 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
d7066cce 166
5152ff90
AG
167 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
168 if (inst >= 0x0612 && inst <= 0x061f)
d7066cce
AG
169 {
170 regnum = inst & 0x000f;
171 cache->framesize += 4;
172 cache->saved_regs[regnum] = cache->framesize;
173 next_addr += 2;
174 }
4ee73e90
AG
175 else
176 break;
ce0bf488 177 }
d7066cce 178
ce0bf488 179 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
d7066cce 180
ce0bf488
AG
181 /* Optional stack allocation for args and local vars <= 4
182 byte. */
5152ff90 183 if (inst == 0x01e0) /* ldi.l $r12, X */
ce0bf488
AG
184 {
185 offset = read_memory_integer (next_addr + 2, 4, byte_order);
186 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
187
5152ff90 188 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
ce0bf488
AG
189 {
190 cache->framesize += offset;
191 }
192
193 return (next_addr + 8);
194 }
5152ff90 195 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
ce0bf488
AG
196 {
197 cache->framesize += (inst & 0x00ff);
198 next_addr += 2;
d7066cce 199
ce0bf488
AG
200 while (next_addr < end_addr)
201 {
202 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
5152ff90 203 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
ce0bf488
AG
204 break;
205 cache->framesize += (inst & 0x00ff);
206 next_addr += 2;
d7066cce 207 }
d7066cce
AG
208 }
209
210 return next_addr;
211}
212
213/* Find the end of function prologue. */
214
215static CORE_ADDR
216moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
217{
218 CORE_ADDR func_addr = 0, func_end = 0;
2c02bd72 219 const char *func_name;
d7066cce
AG
220
221 /* See if we can determine the end of the prologue via the symbol table.
222 If so, then return either PC, or the PC after the prologue, whichever
223 is greater. */
224 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
225 {
d80b854b
UW
226 CORE_ADDR post_prologue_pc
227 = skip_prologue_using_sal (gdbarch, func_addr);
d7066cce 228 if (post_prologue_pc != 0)
325fac50 229 return std::max (pc, post_prologue_pc);
d7066cce
AG
230 else
231 {
232 /* Can't determine prologue from the symbol table, need to examine
233 instructions. */
234 struct symtab_and_line sal;
235 struct symbol *sym;
236 struct moxie_frame_cache cache;
237 CORE_ADDR plg_end;
238
239 memset (&cache, 0, sizeof cache);
240
241 plg_end = moxie_analyze_prologue (func_addr,
99f75275 242 func_end, &cache, gdbarch);
d7066cce 243 /* Found a function. */
835a09d9 244 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
d7066cce 245 /* Don't use line number debug info for assembly source
025bb325 246 files. */
d7066cce
AG
247 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
248 {
249 sal = find_pc_line (func_addr, 0);
250 if (sal.end && sal.end < func_end)
251 {
252 /* Found a line number, use it as end of
253 prologue. */
254 return sal.end;
255 }
256 }
257 /* No useable line symbol. Use result of prologue parsing
258 method. */
259 return plg_end;
260 }
261 }
262
263 /* No function symbol -- just return the PC. */
264 return (CORE_ADDR) pc;
265}
266
267struct moxie_unwind_cache
268{
269 /* The previous frame's inner most stack address. Used as this
270 frame ID's stack_addr. */
271 CORE_ADDR prev_sp;
272 /* The frame's base, optionally used by the high-level debug info. */
273 CORE_ADDR base;
274 int size;
275 /* How far the SP and r13 (FP) have been offset from the start of
276 the stack frame (as defined by the previous frame's stack
277 pointer). */
278 LONGEST sp_offset;
279 LONGEST r13_offset;
280 int uses_frame;
281 /* Table indicating the location of each and every register. */
282 struct trad_frame_saved_reg *saved_regs;
283};
284
6ed1ff02
AG
285/* Read an unsigned integer from the inferior, and adjust
286 endianess. */
287static ULONGEST
288moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
289 int length, enum bfd_endian byte_order)
290{
291 if (target_read_memory (addr, buf, length))
292 {
293 if (record_debug)
294 printf_unfiltered (_("Process record: error reading memory at "
295 "addr 0x%s len = %d.\n"),
296 paddress (target_gdbarch (), addr), length);
297 return -1;
298 }
299
300 return extract_unsigned_integer (buf, length, byte_order);
301}
302
303
304/* Helper macro to extract the signed 10-bit offset from a 16-bit
305 branch instruction. */
306#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
307
308/* Insert a single step breakpoint. */
309
310static int
311moxie_software_single_step (struct frame_info *frame)
312{
313 struct gdbarch *gdbarch = get_frame_arch (frame);
314 struct address_space *aspace = get_frame_address_space (frame);
315 CORE_ADDR addr;
316 gdb_byte buf[4];
317 uint16_t inst;
318 uint32_t tmpu32;
319 ULONGEST fp;
320 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
321 struct regcache *regcache = get_current_regcache ();
322
323 addr = get_frame_pc (frame);
324
325 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
326
327 /* Decode instruction. */
328 if (inst & (1 << 15))
329 {
330 if (inst & (1 << 14))
331 {
332 /* This is a Form 3 instruction. */
333 int opcode = (inst >> 10 & 0xf);
334
335 switch (opcode)
336 {
337 case 0x00: /* beq */
338 case 0x01: /* bne */
339 case 0x02: /* blt */
340 case 0x03: /* bgt */
341 case 0x04: /* bltu */
342 case 0x05: /* bgtu */
343 case 0x06: /* bge */
344 case 0x07: /* ble */
345 case 0x08: /* bgeu */
346 case 0x09: /* bleu */
347 /* Insert breaks on both branches, because we can't currently tell
348 which way things will go. */
349 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
350 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
351 break;
352 default:
353 {
354 /* Do nothing. */
355 break;
356 }
357 }
358 }
359 else
360 {
361 /* This is a Form 2 instruction. They are all 16 bits. */
362 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
363 }
364 }
365 else
366 {
367 /* This is a Form 1 instruction. */
368 int opcode = inst >> 8;
369
370 switch (opcode)
371 {
372 /* 16-bit instructions. */
6441e6db 373 case 0x00: /* bad */
6ed1ff02
AG
374 case 0x02: /* mov (register-to-register) */
375 case 0x05: /* add.l */
376 case 0x06: /* push */
377 case 0x07: /* pop */
378 case 0x0a: /* ld.l (register indirect) */
379 case 0x0b: /* st.l */
380 case 0x0e: /* cmp */
6441e6db
AG
381 case 0x0f: /* nop */
382 case 0x10: /* sex.b */
383 case 0x11: /* sex.s */
384 case 0x12: /* zex.b */
385 case 0x13: /* zex.s */
386 case 0x14: /* umul.x */
387 case 0x15: /* mul.x */
6ed1ff02
AG
388 case 0x16:
389 case 0x17:
390 case 0x18:
391 case 0x1c: /* ld.b (register indirect) */
392 case 0x1e: /* st.b */
393 case 0x21: /* ld.s (register indirect) */
394 case 0x23: /* st.s */
395 case 0x26: /* and */
396 case 0x27: /* lshr */
397 case 0x28: /* ashl */
398 case 0x29: /* sub.l */
399 case 0x2a: /* neg */
400 case 0x2b: /* or */
401 case 0x2c: /* not */
402 case 0x2d: /* ashr */
403 case 0x2e: /* xor */
404 case 0x2f: /* mul.l */
405 case 0x31: /* div.l */
406 case 0x32: /* udiv.l */
407 case 0x33: /* mod.l */
408 case 0x34: /* umod.l */
409 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
410 break;
411
6441e6db
AG
412 /* 32-bit instructions. */
413 case 0x0c: /* ldo.l */
414 case 0x0d: /* sto.l */
415 case 0x36: /* ldo.b */
416 case 0x37: /* sto.b */
417 case 0x38: /* ldo.s */
418 case 0x39: /* sto.s */
419 insert_single_step_breakpoint (gdbarch, aspace, addr + 4);
420 break;
421
6ed1ff02
AG
422 /* 48-bit instructions. */
423 case 0x01: /* ldi.l (immediate) */
424 case 0x08: /* lda.l */
425 case 0x09: /* sta.l */
6ed1ff02
AG
426 case 0x1b: /* ldi.b (immediate) */
427 case 0x1d: /* lda.b */
428 case 0x1f: /* sta.b */
429 case 0x20: /* ldi.s (immediate) */
430 case 0x22: /* lda.s */
431 case 0x24: /* sta.s */
6ed1ff02
AG
432 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
433 break;
434
435 /* Control flow instructions. */
436 case 0x03: /* jsra */
437 case 0x1a: /* jmpa */
438 insert_single_step_breakpoint (gdbarch, aspace,
439 moxie_process_readu (addr + 2,
440 buf, 4,
441 byte_order));
442 break;
443
444 case 0x04: /* ret */
445 regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
446 insert_single_step_breakpoint (gdbarch, aspace,
447 moxie_process_readu (fp + 4,
448 buf, 4,
449 byte_order));
450 break;
451
452 case 0x19: /* jsr */
453 case 0x25: /* jmp */
454 regcache_raw_read (regcache,
455 (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
456 insert_single_step_breakpoint (gdbarch, aspace,
457 tmpu32);
458 break;
459
460 case 0x30: /* swi */
461 case 0x35: /* brk */
462 /* Unsupported, for now. */
463 break;
464 }
465 }
466
467 return 1;
468}
469
d7066cce
AG
470/* Implement the "read_pc" gdbarch method. */
471
472static CORE_ADDR
473moxie_read_pc (struct regcache *regcache)
474{
475 ULONGEST pc;
476
477 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
478 return pc;
479}
480
481/* Implement the "write_pc" gdbarch method. */
482
483static void
484moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
485{
486 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
487}
488
451fa05e 489/* Implement the "unwind_sp" gdbarch method. */
d7066cce
AG
490
491static CORE_ADDR
492moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
493{
494 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
495}
496
497/* Given a return value in `regbuf' with a type `valtype',
498 extract and copy its value into `valbuf'. */
499
500static void
501moxie_extract_return_value (struct type *type, struct regcache *regcache,
7c543f7b 502 gdb_byte *dst)
d7066cce 503{
e17a4113
UW
504 struct gdbarch *gdbarch = get_regcache_arch (regcache);
505 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d7066cce
AG
506 int len = TYPE_LENGTH (type);
507 ULONGEST tmp;
508
509 /* By using store_unsigned_integer we avoid having to do
510 anything special for small big-endian values. */
511 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
7c543f7b 512 store_unsigned_integer (dst, (len > 4 ? len - 4 : len), byte_order, tmp);
d7066cce
AG
513
514 /* Ignore return values more than 8 bytes in size because the moxie
515 returns anything more than 8 bytes in the stack. */
516 if (len > 4)
517 {
518 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
7c543f7b 519 store_unsigned_integer (dst + len - 4, 4, byte_order, tmp);
d7066cce
AG
520 }
521}
522
523/* Implement the "return_value" gdbarch method. */
524
525static enum return_value_convention
6a3a010b 526moxie_return_value (struct gdbarch *gdbarch, struct value *function,
d7066cce
AG
527 struct type *valtype, struct regcache *regcache,
528 gdb_byte *readbuf, const gdb_byte *writebuf)
529{
530 if (TYPE_LENGTH (valtype) > 8)
531 return RETURN_VALUE_STRUCT_CONVENTION;
532 else
533 {
534 if (readbuf != NULL)
535 moxie_extract_return_value (valtype, regcache, readbuf);
536 if (writebuf != NULL)
537 moxie_store_return_value (valtype, regcache, writebuf);
538 return RETURN_VALUE_REGISTER_CONVENTION;
539 }
540}
541
542/* Allocate and initialize a moxie_frame_cache object. */
543
544static struct moxie_frame_cache *
545moxie_alloc_frame_cache (void)
546{
547 struct moxie_frame_cache *cache;
548 int i;
549
550 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
551
552 cache->base = 0;
553 cache->saved_sp = 0;
554 cache->pc = 0;
555 cache->framesize = 0;
556 for (i = 0; i < MOXIE_NUM_REGS; ++i)
557 cache->saved_regs[i] = REG_UNAVAIL;
558
559 return cache;
560}
561
562/* Populate a moxie_frame_cache object for this_frame. */
563
564static struct moxie_frame_cache *
565moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
566{
567 struct moxie_frame_cache *cache;
568 CORE_ADDR current_pc;
569 int i;
570
571 if (*this_cache)
19ba03f4 572 return (struct moxie_frame_cache *) *this_cache;
d7066cce
AG
573
574 cache = moxie_alloc_frame_cache ();
575 *this_cache = cache;
576
577 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
578 if (cache->base == 0)
579 return cache;
580
581 cache->pc = get_frame_func (this_frame);
582 current_pc = get_frame_pc (this_frame);
583 if (cache->pc)
99f75275
AG
584 {
585 struct gdbarch *gdbarch = get_frame_arch (this_frame);
586 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
587 }
d7066cce
AG
588
589 cache->saved_sp = cache->base - cache->framesize;
590
591 for (i = 0; i < MOXIE_NUM_REGS; ++i)
592 if (cache->saved_regs[i] != REG_UNAVAIL)
593 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
594
595 return cache;
596}
597
598/* Implement the "unwind_pc" gdbarch method. */
599
600static CORE_ADDR
601moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
602{
603 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
604}
605
606/* Given a GDB frame, determine the address of the calling function's
607 frame. This will be used to create a new GDB frame struct. */
608
609static void
610moxie_frame_this_id (struct frame_info *this_frame,
611 void **this_prologue_cache, struct frame_id *this_id)
612{
613 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
614 this_prologue_cache);
615
616 /* This marks the outermost frame. */
617 if (cache->base == 0)
618 return;
619
620 *this_id = frame_id_build (cache->saved_sp, cache->pc);
621}
622
623/* Get the value of register regnum in the previous stack frame. */
624
625static struct value *
626moxie_frame_prev_register (struct frame_info *this_frame,
627 void **this_prologue_cache, int regnum)
628{
629 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
630 this_prologue_cache);
631
632 gdb_assert (regnum >= 0);
633
634 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
635 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
636
637 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
638 return frame_unwind_got_memory (this_frame, regnum,
639 cache->saved_regs[regnum]);
640
641 return frame_unwind_got_register (this_frame, regnum, regnum);
642}
643
644static const struct frame_unwind moxie_frame_unwind = {
645 NORMAL_FRAME,
8fbca658 646 default_frame_unwind_stop_reason,
d7066cce
AG
647 moxie_frame_this_id,
648 moxie_frame_prev_register,
649 NULL,
650 default_frame_sniffer
651};
652
653/* Return the base address of this_frame. */
654
655static CORE_ADDR
656moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
657{
658 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
659 this_cache);
660
661 return cache->base;
662}
663
664static const struct frame_base moxie_frame_base = {
665 &moxie_frame_unwind,
666 moxie_frame_base_address,
667 moxie_frame_base_address,
668 moxie_frame_base_address
669};
670
671static struct frame_id
672moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
673{
674 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
675
676 return frame_id_build (sp, get_frame_pc (this_frame));
677}
678
451fa05e
AG
679/* Parse the current instruction and record the values of the registers and
680 memory that will be changed in current instruction to "record_arch_list".
025bb325 681 Return -1 if something wrong. */
451fa05e 682
693be288 683static int
451fa05e
AG
684moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
685 CORE_ADDR addr)
686{
687 gdb_byte buf[4];
688 uint16_t inst;
689 uint32_t tmpu32;
690 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
691
692 if (record_debug > 1)
693 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
694 "addr = 0x%s\n",
f5656ead 695 paddress (target_gdbarch (), addr));
451fa05e
AG
696
697 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
698
699 /* Decode instruction. */
700 if (inst & (1 << 15))
701 {
702 if (inst & (1 << 14))
703 {
704 /* This is a Form 3 instruction. */
705 int opcode = (inst >> 10 & 0xf);
706
707 switch (opcode)
708 {
709 case 0x00: /* beq */
710 case 0x01: /* bne */
711 case 0x02: /* blt */
712 case 0x03: /* bgt */
713 case 0x04: /* bltu */
714 case 0x05: /* bgtu */
715 case 0x06: /* bge */
716 case 0x07: /* ble */
717 case 0x08: /* bgeu */
718 case 0x09: /* bleu */
719 /* Do nothing. */
720 break;
721 default:
722 {
723 /* Do nothing. */
724 break;
725 }
726 }
727 }
728 else
729 {
730 /* This is a Form 2 instruction. */
731 int opcode = (inst >> 12 & 0x3);
732 switch (opcode)
733 {
734 case 0x00: /* inc */
735 case 0x01: /* dec */
736 case 0x02: /* gsr */
737 {
738 int reg = (inst >> 8) & 0xf;
25ea693b 739 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
740 return -1;
741 }
742 break;
743 case 0x03: /* ssr */
744 {
745 /* Do nothing until GDB learns about moxie's special
746 registers. */
747 }
748 break;
749 default:
750 /* Do nothing. */
751 break;
752 }
753 }
754 }
755 else
756 {
757 /* This is a Form 1 instruction. */
758 int opcode = inst >> 8;
759
760 switch (opcode)
761 {
762 case 0x00: /* nop */
763 /* Do nothing. */
764 break;
765 case 0x01: /* ldi.l (immediate) */
766 case 0x02: /* mov (register-to-register) */
767 {
768 int reg = (inst >> 4) & 0xf;
25ea693b 769 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
770 return -1;
771 }
772 break;
773 case 0x03: /* jsra */
774 {
775 regcache_raw_read (regcache,
776 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
777 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
778 4, byte_order);
25ea693b
MM
779 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
780 || (record_full_arch_list_add_reg (regcache,
781 MOXIE_SP_REGNUM))
782 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
451fa05e
AG
783 return -1;
784 }
785 break;
786 case 0x04: /* ret */
787 {
25ea693b
MM
788 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
789 || (record_full_arch_list_add_reg (regcache,
790 MOXIE_SP_REGNUM)))
451fa05e
AG
791 return -1;
792 }
793 break;
794 case 0x05: /* add.l */
795 {
796 int reg = (inst >> 4) & 0xf;
25ea693b 797 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
798 return -1;
799 }
800 break;
801 case 0x06: /* push */
802 {
803 int reg = (inst >> 4) & 0xf;
804 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
805 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
806 4, byte_order);
25ea693b
MM
807 if (record_full_arch_list_add_reg (regcache, reg)
808 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
451fa05e
AG
809 return -1;
810 }
811 break;
812 case 0x07: /* pop */
813 {
814 int a = (inst >> 4) & 0xf;
815 int b = inst & 0xf;
25ea693b
MM
816 if (record_full_arch_list_add_reg (regcache, a)
817 || record_full_arch_list_add_reg (regcache, b))
451fa05e
AG
818 return -1;
819 }
820 break;
821 case 0x08: /* lda.l */
822 {
823 int reg = (inst >> 4) & 0xf;
25ea693b 824 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
825 return -1;
826 }
827 break;
828 case 0x09: /* sta.l */
829 {
830 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
831 4, byte_order);
25ea693b 832 if (record_full_arch_list_add_mem (tmpu32, 4))
451fa05e
AG
833 return -1;
834 }
835 break;
836 case 0x0a: /* ld.l (register indirect) */
837 {
838 int reg = (inst >> 4) & 0xf;
25ea693b 839 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
840 return -1;
841 }
842 break;
843 case 0x0b: /* st.l */
844 {
845 int reg = (inst >> 4) & 0xf;
846 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
847 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
848 4, byte_order);
25ea693b 849 if (record_full_arch_list_add_mem (tmpu32, 4))
451fa05e
AG
850 return -1;
851 }
852 break;
853 case 0x0c: /* ldo.l */
854 {
855 int reg = (inst >> 4) & 0xf;
25ea693b 856 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
857 return -1;
858 }
859 break;
860 case 0x0d: /* sto.l */
861 {
862 int reg = (inst >> 4) & 0xf;
6441e6db
AG
863 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
864 byte_order)) << 16 ) >> 16;
451fa05e
AG
865 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
866 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
867 4, byte_order);
868 tmpu32 += offset;
25ea693b 869 if (record_full_arch_list_add_mem (tmpu32, 4))
451fa05e
AG
870 return -1;
871 }
872 break;
873 case 0x0e: /* cmp */
874 {
25ea693b 875 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
451fa05e
AG
876 return -1;
877 }
878 break;
6441e6db
AG
879 case 0x0f: /* nop */
880 {
881 /* Do nothing. */
882 break;
883 }
884 case 0x10: /* sex.b */
885 case 0x11: /* sex.s */
886 case 0x12: /* zex.b */
887 case 0x13: /* zex.s */
888 case 0x14: /* umul.x */
889 case 0x15: /* mul.x */
890 {
891 int reg = (inst >> 4) & 0xf;
892 if (record_full_arch_list_add_reg (regcache, reg))
893 return -1;
894 }
895 break;
451fa05e
AG
896 case 0x16:
897 case 0x17:
898 case 0x18:
899 {
900 /* Do nothing. */
901 break;
902 }
903 case 0x19: /* jsr */
904 {
905 regcache_raw_read (regcache,
906 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
907 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
908 4, byte_order);
25ea693b
MM
909 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
910 || (record_full_arch_list_add_reg (regcache,
911 MOXIE_SP_REGNUM))
912 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
451fa05e
AG
913 return -1;
914 }
915 break;
916 case 0x1a: /* jmpa */
917 {
918 /* Do nothing. */
919 }
920 break;
921 case 0x1b: /* ldi.b (immediate) */
922 case 0x1c: /* ld.b (register indirect) */
923 case 0x1d: /* lda.b */
924 {
925 int reg = (inst >> 4) & 0xf;
25ea693b 926 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
927 return -1;
928 }
929 break;
930 case 0x1e: /* st.b */
931 {
932 int reg = (inst >> 4) & 0xf;
933 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
934 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
935 4, byte_order);
25ea693b 936 if (record_full_arch_list_add_mem (tmpu32, 1))
451fa05e
AG
937 return -1;
938 }
939 break;
940 case 0x1f: /* sta.b */
941 {
948f8e3d 942 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
25ea693b 943 if (record_full_arch_list_add_mem (tmpu32, 1))
451fa05e
AG
944 return -1;
945 }
946 break;
947 case 0x20: /* ldi.s (immediate) */
948 case 0x21: /* ld.s (register indirect) */
949 case 0x22: /* lda.s */
950 {
951 int reg = (inst >> 4) & 0xf;
25ea693b 952 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
953 return -1;
954 }
955 break;
956 case 0x23: /* st.s */
957 {
958 int reg = (inst >> 4) & 0xf;
959 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
960 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
961 4, byte_order);
25ea693b 962 if (record_full_arch_list_add_mem (tmpu32, 2))
451fa05e
AG
963 return -1;
964 }
965 break;
966 case 0x24: /* sta.s */
967 {
948f8e3d 968 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
25ea693b 969 if (record_full_arch_list_add_mem (tmpu32, 2))
451fa05e
AG
970 return -1;
971 }
972 break;
973 case 0x25: /* jmp */
974 {
975 /* Do nothing. */
976 }
977 break;
978 case 0x26: /* and */
979 case 0x27: /* lshr */
980 case 0x28: /* ashl */
6441e6db 981 case 0x29: /* sub */
451fa05e
AG
982 case 0x2a: /* neg */
983 case 0x2b: /* or */
984 case 0x2c: /* not */
985 case 0x2d: /* ashr */
986 case 0x2e: /* xor */
6441e6db 987 case 0x2f: /* mul */
451fa05e
AG
988 {
989 int reg = (inst >> 4) & 0xf;
25ea693b 990 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
991 return -1;
992 }
993 break;
994 case 0x30: /* swi */
995 {
996 /* We currently implement support for libgloss'
997 system calls. */
998
948f8e3d 999 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
451fa05e
AG
1000
1001 switch (inum)
1002 {
1003 case 0x1: /* SYS_exit */
1004 {
1005 /* Do nothing. */
1006 }
1007 break;
1008 case 0x2: /* SYS_open */
1009 {
25ea693b 1010 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
451fa05e
AG
1011 return -1;
1012 }
1013 break;
1014 case 0x4: /* SYS_read */
1015 {
1016 uint32_t length, ptr;
1017
1018 /* Read buffer pointer is in $r1. */
1019 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1020 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1021 4, byte_order);
1022
025bb325 1023 /* String length is at 0x12($fp). */
451fa05e
AG
1024 regcache_raw_read (regcache,
1025 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1026 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1027 4, byte_order);
948f8e3d 1028 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
451fa05e 1029
25ea693b 1030 if (record_full_arch_list_add_mem (ptr, length))
451fa05e
AG
1031 return -1;
1032 }
1033 break;
1034 case 0x5: /* SYS_write */
1035 {
25ea693b 1036 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
451fa05e
AG
1037 return -1;
1038 }
1039 break;
1040 default:
1041 break;
1042 }
1043 }
1044 break;
1045 case 0x31: /* div.l */
1046 case 0x32: /* udiv.l */
1047 case 0x33: /* mod.l */
1048 case 0x34: /* umod.l */
1049 {
1050 int reg = (inst >> 4) & 0xf;
25ea693b 1051 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
1052 return -1;
1053 }
1054 break;
1055 case 0x35: /* brk */
1056 /* Do nothing. */
1057 break;
1058 case 0x36: /* ldo.b */
1059 {
1060 int reg = (inst >> 4) & 0xf;
25ea693b 1061 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
1062 return -1;
1063 }
1064 break;
1065 case 0x37: /* sto.b */
1066 {
1067 int reg = (inst >> 4) & 0xf;
6441e6db
AG
1068 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1069 byte_order)) << 16 ) >> 16;
451fa05e
AG
1070 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1071 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1072 4, byte_order);
1073 tmpu32 += offset;
25ea693b 1074 if (record_full_arch_list_add_mem (tmpu32, 1))
451fa05e
AG
1075 return -1;
1076 }
1077 break;
1078 case 0x38: /* ldo.s */
1079 {
1080 int reg = (inst >> 4) & 0xf;
25ea693b 1081 if (record_full_arch_list_add_reg (regcache, reg))
451fa05e
AG
1082 return -1;
1083 }
1084 break;
1085 case 0x39: /* sto.s */
1086 {
1087 int reg = (inst >> 4) & 0xf;
6441e6db
AG
1088 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1089 byte_order)) << 16 ) >> 16;
451fa05e
AG
1090 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1091 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1092 4, byte_order);
1093 tmpu32 += offset;
25ea693b 1094 if (record_full_arch_list_add_mem (tmpu32, 2))
451fa05e
AG
1095 return -1;
1096 }
1097 break;
1098 default:
1099 /* Do nothing. */
1100 break;
1101 }
1102 }
1103
25ea693b 1104 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
451fa05e 1105 return -1;
25ea693b 1106 if (record_full_arch_list_add_end ())
451fa05e
AG
1107 return -1;
1108 return 0;
1109}
1110
d7066cce
AG
1111/* Allocate and initialize the moxie gdbarch object. */
1112
1113static struct gdbarch *
1114moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1115{
1116 struct gdbarch *gdbarch;
1117 struct gdbarch_tdep *tdep;
1118
1119 /* If there is already a candidate, use it. */
1120 arches = gdbarch_list_lookup_by_info (arches, &info);
1121 if (arches != NULL)
1122 return arches->gdbarch;
1123
1124 /* Allocate space for the new architecture. */
70ba0933 1125 tdep = XNEW (struct gdbarch_tdep);
d7066cce
AG
1126 gdbarch = gdbarch_alloc (&info, tdep);
1127
1128 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1129 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1130 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1131
1132 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1133 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
451fa05e 1134 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
d7066cce
AG
1135 set_gdbarch_register_name (gdbarch, moxie_register_name);
1136 set_gdbarch_register_type (gdbarch, moxie_register_type);
1137
1138 set_gdbarch_return_value (gdbarch, moxie_return_value);
1139
1140 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1141 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1142 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
1143 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1144
1145 frame_base_set_default (gdbarch, &moxie_frame_base);
1146
1147 /* Methods for saving / extracting a dummy frame's ID. The ID's
1148 stack address must match the SP value returned by
1149 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1150 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1151
1152 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1153
1154 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1155
1156 /* Hook in ABI-specific overrides, if they have been registered. */
1157 gdbarch_init_osabi (info, gdbarch);
1158
1159 /* Hook in the default unwinders. */
1160 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1161
6ed1ff02
AG
1162 /* Single stepping. */
1163 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1164
d7066cce
AG
1165 /* Support simple overlay manager. */
1166 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1167
451fa05e
AG
1168 /* Support reverse debugging. */
1169 set_gdbarch_process_record (gdbarch, moxie_process_record);
1170
d7066cce
AG
1171 return gdbarch;
1172}
1173
1174/* Register this machine's init routine. */
1175
1176void
1177_initialize_moxie_tdep (void)
1178{
1179 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
1180}
This page took 0.796816 seconds and 4 git commands to generate.