s390-vregs.exp: Avoid compile errors with older GCCs and on 31-bit targets
[binutils-gdb.git] / gdb / moxie-tdep.c
blob555151d6282b059f0e91eebc655a131486f010f0
1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009-2015 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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"
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"
38 #include "record.h"
39 #include "record-full.h"
41 #include "moxie-tdep.h"
43 /* Local functions. */
45 extern void _initialize_moxie_tdep (void);
47 /* Use an invalid address value as 'not available' marker. */
48 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50 struct moxie_frame_cache
52 /* Base address. */
53 CORE_ADDR base;
54 CORE_ADDR pc;
55 LONGEST framesize;
56 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
57 CORE_ADDR saved_sp;
60 /* Implement the "frame_align" gdbarch method. */
62 static CORE_ADDR
63 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65 /* Align to the size of an instruction (so that they can safely be
66 pushed onto the stack. */
67 return sp & ~1;
70 /* Implement the "breakpoint_from_pc" gdbarch method. */
72 static const unsigned char *
73 moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
74 CORE_ADDR *pcptr, int *lenptr)
76 static unsigned char breakpoint[] = { 0x35, 0x00 };
78 *lenptr = sizeof (breakpoint);
79 return breakpoint;
82 /* Moxie register names. */
84 char *moxie_register_names[] = {
85 "$fp", "$sp", "$r0", "$r1", "$r2",
86 "$r3", "$r4", "$r5", "$r6", "$r7",
87 "$r8", "$r9", "$r10", "$r11", "$r12",
88 "$r13", "$pc", "$cc" };
90 /* Implement the "register_name" gdbarch method. */
92 static const char *
93 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
95 if (reg_nr < 0)
96 return NULL;
97 if (reg_nr >= MOXIE_NUM_REGS)
98 return NULL;
99 return moxie_register_names[reg_nr];
102 /* Implement the "register_type" gdbarch method. */
104 static struct type *
105 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
107 if (reg_nr == MOXIE_PC_REGNUM)
108 return builtin_type (gdbarch)->builtin_func_ptr;
109 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
110 return builtin_type (gdbarch)->builtin_data_ptr;
111 else
112 return builtin_type (gdbarch)->builtin_int32;
115 /* Write into appropriate registers a function return value
116 of type TYPE, given in virtual format. */
118 static void
119 moxie_store_return_value (struct type *type, struct regcache *regcache,
120 const void *valbuf)
122 struct gdbarch *gdbarch = get_regcache_arch (regcache);
123 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
124 CORE_ADDR regval;
125 int len = TYPE_LENGTH (type);
127 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
128 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
129 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
130 if (len > 4)
132 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
133 len - 4, byte_order);
134 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
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.
142 Returns the address of the first instruction after the prologue. */
144 static CORE_ADDR
145 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
146 struct moxie_frame_cache *cache,
147 struct gdbarch *gdbarch)
149 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
150 CORE_ADDR next_addr;
151 ULONGEST inst, inst2;
152 LONGEST offset;
153 int regnum;
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;
160 if (start_addr >= end_addr)
161 return end_addr;
163 for (next_addr = start_addr; next_addr < end_addr; )
165 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
167 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
168 if (inst >= 0x0612 && inst <= 0x061f)
170 regnum = inst & 0x000f;
171 cache->framesize += 4;
172 cache->saved_regs[regnum] = cache->framesize;
173 next_addr += 2;
175 else
176 break;
179 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
181 /* Optional stack allocation for args and local vars <= 4
182 byte. */
183 if (inst == 0x01e0) /* ldi.l $r12, X */
185 offset = read_memory_integer (next_addr + 2, 4, byte_order);
186 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
188 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
190 cache->framesize += offset;
193 return (next_addr + 8);
195 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
197 cache->framesize += (inst & 0x00ff);
198 next_addr += 2;
200 while (next_addr < end_addr)
202 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
203 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
204 break;
205 cache->framesize += (inst & 0x00ff);
206 next_addr += 2;
210 return next_addr;
213 /* Find the end of function prologue. */
215 static CORE_ADDR
216 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
218 CORE_ADDR func_addr = 0, func_end = 0;
219 const char *func_name;
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))
226 CORE_ADDR post_prologue_pc
227 = skip_prologue_using_sal (gdbarch, func_addr);
228 if (post_prologue_pc != 0)
229 return max (pc, post_prologue_pc);
230 else
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;
239 memset (&cache, 0, sizeof cache);
241 plg_end = moxie_analyze_prologue (func_addr,
242 func_end, &cache, gdbarch);
243 /* Found a function. */
244 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
245 /* Don't use line number debug info for assembly source
246 files. */
247 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
249 sal = find_pc_line (func_addr, 0);
250 if (sal.end && sal.end < func_end)
252 /* Found a line number, use it as end of
253 prologue. */
254 return sal.end;
257 /* No useable line symbol. Use result of prologue parsing
258 method. */
259 return plg_end;
263 /* No function symbol -- just return the PC. */
264 return (CORE_ADDR) pc;
267 struct moxie_unwind_cache
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;
285 /* Read an unsigned integer from the inferior, and adjust
286 endianess. */
287 static ULONGEST
288 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
289 int length, enum bfd_endian byte_order)
291 if (target_read_memory (addr, buf, length))
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;
300 return extract_unsigned_integer (buf, length, byte_order);
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)
308 /* Insert a single step breakpoint. */
310 static int
311 moxie_software_single_step (struct frame_info *frame)
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 ();
323 addr = get_frame_pc (frame);
325 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
327 /* Decode instruction. */
328 if (inst & (1 << 15))
330 if (inst & (1 << 14))
332 /* This is a Form 3 instruction. */
333 int opcode = (inst >> 10 & 0xf);
335 switch (opcode)
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:
354 /* Do nothing. */
355 break;
359 else
361 /* This is a Form 2 instruction. They are all 16 bits. */
362 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
365 else
367 /* This is a Form 1 instruction. */
368 int opcode = inst >> 8;
370 switch (opcode)
372 /* 16-bit instructions. */
373 case 0x00: /* bad */
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 */
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 */
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;
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;
422 /* 48-bit instructions. */
423 case 0x01: /* ldi.l (immediate) */
424 case 0x08: /* lda.l */
425 case 0x09: /* sta.l */
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 */
432 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
433 break;
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;
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;
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;
460 case 0x30: /* swi */
461 case 0x35: /* brk */
462 /* Unsupported, for now. */
463 break;
467 return 1;
470 /* Implement the "read_pc" gdbarch method. */
472 static CORE_ADDR
473 moxie_read_pc (struct regcache *regcache)
475 ULONGEST pc;
477 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
478 return pc;
481 /* Implement the "write_pc" gdbarch method. */
483 static void
484 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
486 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
489 /* Implement the "unwind_sp" gdbarch method. */
491 static CORE_ADDR
492 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
494 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
497 /* Given a return value in `regbuf' with a type `valtype',
498 extract and copy its value into `valbuf'. */
500 static void
501 moxie_extract_return_value (struct type *type, struct regcache *regcache,
502 void *dst)
504 struct gdbarch *gdbarch = get_regcache_arch (regcache);
505 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
506 bfd_byte *valbuf = dst;
507 int len = TYPE_LENGTH (type);
508 ULONGEST tmp;
510 /* By using store_unsigned_integer we avoid having to do
511 anything special for small big-endian values. */
512 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
513 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
515 /* Ignore return values more than 8 bytes in size because the moxie
516 returns anything more than 8 bytes in the stack. */
517 if (len > 4)
519 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
520 store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
524 /* Implement the "return_value" gdbarch method. */
526 static enum return_value_convention
527 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
528 struct type *valtype, struct regcache *regcache,
529 gdb_byte *readbuf, const gdb_byte *writebuf)
531 if (TYPE_LENGTH (valtype) > 8)
532 return RETURN_VALUE_STRUCT_CONVENTION;
533 else
535 if (readbuf != NULL)
536 moxie_extract_return_value (valtype, regcache, readbuf);
537 if (writebuf != NULL)
538 moxie_store_return_value (valtype, regcache, writebuf);
539 return RETURN_VALUE_REGISTER_CONVENTION;
543 /* Allocate and initialize a moxie_frame_cache object. */
545 static struct moxie_frame_cache *
546 moxie_alloc_frame_cache (void)
548 struct moxie_frame_cache *cache;
549 int i;
551 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
553 cache->base = 0;
554 cache->saved_sp = 0;
555 cache->pc = 0;
556 cache->framesize = 0;
557 for (i = 0; i < MOXIE_NUM_REGS; ++i)
558 cache->saved_regs[i] = REG_UNAVAIL;
560 return cache;
563 /* Populate a moxie_frame_cache object for this_frame. */
565 static struct moxie_frame_cache *
566 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
568 struct moxie_frame_cache *cache;
569 CORE_ADDR current_pc;
570 int i;
572 if (*this_cache)
573 return *this_cache;
575 cache = moxie_alloc_frame_cache ();
576 *this_cache = cache;
578 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
579 if (cache->base == 0)
580 return cache;
582 cache->pc = get_frame_func (this_frame);
583 current_pc = get_frame_pc (this_frame);
584 if (cache->pc)
586 struct gdbarch *gdbarch = get_frame_arch (this_frame);
587 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
590 cache->saved_sp = cache->base - cache->framesize;
592 for (i = 0; i < MOXIE_NUM_REGS; ++i)
593 if (cache->saved_regs[i] != REG_UNAVAIL)
594 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
596 return cache;
599 /* Implement the "unwind_pc" gdbarch method. */
601 static CORE_ADDR
602 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
604 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
607 /* Given a GDB frame, determine the address of the calling function's
608 frame. This will be used to create a new GDB frame struct. */
610 static void
611 moxie_frame_this_id (struct frame_info *this_frame,
612 void **this_prologue_cache, struct frame_id *this_id)
614 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
615 this_prologue_cache);
617 /* This marks the outermost frame. */
618 if (cache->base == 0)
619 return;
621 *this_id = frame_id_build (cache->saved_sp, cache->pc);
624 /* Get the value of register regnum in the previous stack frame. */
626 static struct value *
627 moxie_frame_prev_register (struct frame_info *this_frame,
628 void **this_prologue_cache, int regnum)
630 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
631 this_prologue_cache);
633 gdb_assert (regnum >= 0);
635 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
636 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
638 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
639 return frame_unwind_got_memory (this_frame, regnum,
640 cache->saved_regs[regnum]);
642 return frame_unwind_got_register (this_frame, regnum, regnum);
645 static const struct frame_unwind moxie_frame_unwind = {
646 NORMAL_FRAME,
647 default_frame_unwind_stop_reason,
648 moxie_frame_this_id,
649 moxie_frame_prev_register,
650 NULL,
651 default_frame_sniffer
654 /* Return the base address of this_frame. */
656 static CORE_ADDR
657 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
659 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
660 this_cache);
662 return cache->base;
665 static const struct frame_base moxie_frame_base = {
666 &moxie_frame_unwind,
667 moxie_frame_base_address,
668 moxie_frame_base_address,
669 moxie_frame_base_address
672 static struct frame_id
673 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
675 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
677 return frame_id_build (sp, get_frame_pc (this_frame));
680 /* Parse the current instruction and record the values of the registers and
681 memory that will be changed in current instruction to "record_arch_list".
682 Return -1 if something wrong. */
684 static int
685 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
686 CORE_ADDR addr)
688 gdb_byte buf[4];
689 uint16_t inst;
690 uint32_t tmpu32;
691 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
693 if (record_debug > 1)
694 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
695 "addr = 0x%s\n",
696 paddress (target_gdbarch (), addr));
698 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
700 /* Decode instruction. */
701 if (inst & (1 << 15))
703 if (inst & (1 << 14))
705 /* This is a Form 3 instruction. */
706 int opcode = (inst >> 10 & 0xf);
708 switch (opcode)
710 case 0x00: /* beq */
711 case 0x01: /* bne */
712 case 0x02: /* blt */
713 case 0x03: /* bgt */
714 case 0x04: /* bltu */
715 case 0x05: /* bgtu */
716 case 0x06: /* bge */
717 case 0x07: /* ble */
718 case 0x08: /* bgeu */
719 case 0x09: /* bleu */
720 /* Do nothing. */
721 break;
722 default:
724 /* Do nothing. */
725 break;
729 else
731 /* This is a Form 2 instruction. */
732 int opcode = (inst >> 12 & 0x3);
733 switch (opcode)
735 case 0x00: /* inc */
736 case 0x01: /* dec */
737 case 0x02: /* gsr */
739 int reg = (inst >> 8) & 0xf;
740 if (record_full_arch_list_add_reg (regcache, reg))
741 return -1;
743 break;
744 case 0x03: /* ssr */
746 /* Do nothing until GDB learns about moxie's special
747 registers. */
749 break;
750 default:
751 /* Do nothing. */
752 break;
756 else
758 /* This is a Form 1 instruction. */
759 int opcode = inst >> 8;
761 switch (opcode)
763 case 0x00: /* nop */
764 /* Do nothing. */
765 break;
766 case 0x01: /* ldi.l (immediate) */
767 case 0x02: /* mov (register-to-register) */
769 int reg = (inst >> 4) & 0xf;
770 if (record_full_arch_list_add_reg (regcache, reg))
771 return -1;
773 break;
774 case 0x03: /* jsra */
776 regcache_raw_read (regcache,
777 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
778 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
779 4, byte_order);
780 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
781 || (record_full_arch_list_add_reg (regcache,
782 MOXIE_SP_REGNUM))
783 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
784 return -1;
786 break;
787 case 0x04: /* ret */
789 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
790 || (record_full_arch_list_add_reg (regcache,
791 MOXIE_SP_REGNUM)))
792 return -1;
794 break;
795 case 0x05: /* add.l */
797 int reg = (inst >> 4) & 0xf;
798 if (record_full_arch_list_add_reg (regcache, reg))
799 return -1;
801 break;
802 case 0x06: /* push */
804 int reg = (inst >> 4) & 0xf;
805 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
806 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
807 4, byte_order);
808 if (record_full_arch_list_add_reg (regcache, reg)
809 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
810 return -1;
812 break;
813 case 0x07: /* pop */
815 int a = (inst >> 4) & 0xf;
816 int b = inst & 0xf;
817 if (record_full_arch_list_add_reg (regcache, a)
818 || record_full_arch_list_add_reg (regcache, b))
819 return -1;
821 break;
822 case 0x08: /* lda.l */
824 int reg = (inst >> 4) & 0xf;
825 if (record_full_arch_list_add_reg (regcache, reg))
826 return -1;
828 break;
829 case 0x09: /* sta.l */
831 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
832 4, byte_order);
833 if (record_full_arch_list_add_mem (tmpu32, 4))
834 return -1;
836 break;
837 case 0x0a: /* ld.l (register indirect) */
839 int reg = (inst >> 4) & 0xf;
840 if (record_full_arch_list_add_reg (regcache, reg))
841 return -1;
843 break;
844 case 0x0b: /* st.l */
846 int reg = (inst >> 4) & 0xf;
847 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
848 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
849 4, byte_order);
850 if (record_full_arch_list_add_mem (tmpu32, 4))
851 return -1;
853 break;
854 case 0x0c: /* ldo.l */
856 int reg = (inst >> 4) & 0xf;
857 if (record_full_arch_list_add_reg (regcache, reg))
858 return -1;
860 break;
861 case 0x0d: /* sto.l */
863 int reg = (inst >> 4) & 0xf;
864 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
865 byte_order)) << 16 ) >> 16;
866 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
867 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
868 4, byte_order);
869 tmpu32 += offset;
870 if (record_full_arch_list_add_mem (tmpu32, 4))
871 return -1;
873 break;
874 case 0x0e: /* cmp */
876 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
877 return -1;
879 break;
880 case 0x0f: /* nop */
882 /* Do nothing. */
883 break;
885 case 0x10: /* sex.b */
886 case 0x11: /* sex.s */
887 case 0x12: /* zex.b */
888 case 0x13: /* zex.s */
889 case 0x14: /* umul.x */
890 case 0x15: /* mul.x */
892 int reg = (inst >> 4) & 0xf;
893 if (record_full_arch_list_add_reg (regcache, reg))
894 return -1;
896 break;
897 case 0x16:
898 case 0x17:
899 case 0x18:
901 /* Do nothing. */
902 break;
904 case 0x19: /* jsr */
906 regcache_raw_read (regcache,
907 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
908 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
909 4, byte_order);
910 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
911 || (record_full_arch_list_add_reg (regcache,
912 MOXIE_SP_REGNUM))
913 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
914 return -1;
916 break;
917 case 0x1a: /* jmpa */
919 /* Do nothing. */
921 break;
922 case 0x1b: /* ldi.b (immediate) */
923 case 0x1c: /* ld.b (register indirect) */
924 case 0x1d: /* lda.b */
926 int reg = (inst >> 4) & 0xf;
927 if (record_full_arch_list_add_reg (regcache, reg))
928 return -1;
930 break;
931 case 0x1e: /* st.b */
933 int reg = (inst >> 4) & 0xf;
934 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
935 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
936 4, byte_order);
937 if (record_full_arch_list_add_mem (tmpu32, 1))
938 return -1;
940 break;
941 case 0x1f: /* sta.b */
943 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
944 if (record_full_arch_list_add_mem (tmpu32, 1))
945 return -1;
947 break;
948 case 0x20: /* ldi.s (immediate) */
949 case 0x21: /* ld.s (register indirect) */
950 case 0x22: /* lda.s */
952 int reg = (inst >> 4) & 0xf;
953 if (record_full_arch_list_add_reg (regcache, reg))
954 return -1;
956 break;
957 case 0x23: /* st.s */
959 int reg = (inst >> 4) & 0xf;
960 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
961 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
962 4, byte_order);
963 if (record_full_arch_list_add_mem (tmpu32, 2))
964 return -1;
966 break;
967 case 0x24: /* sta.s */
969 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
970 if (record_full_arch_list_add_mem (tmpu32, 2))
971 return -1;
973 break;
974 case 0x25: /* jmp */
976 /* Do nothing. */
978 break;
979 case 0x26: /* and */
980 case 0x27: /* lshr */
981 case 0x28: /* ashl */
982 case 0x29: /* sub */
983 case 0x2a: /* neg */
984 case 0x2b: /* or */
985 case 0x2c: /* not */
986 case 0x2d: /* ashr */
987 case 0x2e: /* xor */
988 case 0x2f: /* mul */
990 int reg = (inst >> 4) & 0xf;
991 if (record_full_arch_list_add_reg (regcache, reg))
992 return -1;
994 break;
995 case 0x30: /* swi */
997 /* We currently implement support for libgloss'
998 system calls. */
1000 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
1002 switch (inum)
1004 case 0x1: /* SYS_exit */
1006 /* Do nothing. */
1008 break;
1009 case 0x2: /* SYS_open */
1011 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1012 return -1;
1014 break;
1015 case 0x4: /* SYS_read */
1017 uint32_t length, ptr;
1019 /* Read buffer pointer is in $r1. */
1020 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1021 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1022 4, byte_order);
1024 /* String length is at 0x12($fp). */
1025 regcache_raw_read (regcache,
1026 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1027 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1028 4, byte_order);
1029 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1031 if (record_full_arch_list_add_mem (ptr, length))
1032 return -1;
1034 break;
1035 case 0x5: /* SYS_write */
1037 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1038 return -1;
1040 break;
1041 default:
1042 break;
1045 break;
1046 case 0x31: /* div.l */
1047 case 0x32: /* udiv.l */
1048 case 0x33: /* mod.l */
1049 case 0x34: /* umod.l */
1051 int reg = (inst >> 4) & 0xf;
1052 if (record_full_arch_list_add_reg (regcache, reg))
1053 return -1;
1055 break;
1056 case 0x35: /* brk */
1057 /* Do nothing. */
1058 break;
1059 case 0x36: /* ldo.b */
1061 int reg = (inst >> 4) & 0xf;
1062 if (record_full_arch_list_add_reg (regcache, reg))
1063 return -1;
1065 break;
1066 case 0x37: /* sto.b */
1068 int reg = (inst >> 4) & 0xf;
1069 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1070 byte_order)) << 16 ) >> 16;
1071 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1072 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1073 4, byte_order);
1074 tmpu32 += offset;
1075 if (record_full_arch_list_add_mem (tmpu32, 1))
1076 return -1;
1078 break;
1079 case 0x38: /* ldo.s */
1081 int reg = (inst >> 4) & 0xf;
1082 if (record_full_arch_list_add_reg (regcache, reg))
1083 return -1;
1085 break;
1086 case 0x39: /* sto.s */
1088 int reg = (inst >> 4) & 0xf;
1089 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1090 byte_order)) << 16 ) >> 16;
1091 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1092 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1093 4, byte_order);
1094 tmpu32 += offset;
1095 if (record_full_arch_list_add_mem (tmpu32, 2))
1096 return -1;
1098 break;
1099 default:
1100 /* Do nothing. */
1101 break;
1105 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1106 return -1;
1107 if (record_full_arch_list_add_end ())
1108 return -1;
1109 return 0;
1112 /* Allocate and initialize the moxie gdbarch object. */
1114 static struct gdbarch *
1115 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1117 struct gdbarch *gdbarch;
1118 struct gdbarch_tdep *tdep;
1120 /* If there is already a candidate, use it. */
1121 arches = gdbarch_list_lookup_by_info (arches, &info);
1122 if (arches != NULL)
1123 return arches->gdbarch;
1125 /* Allocate space for the new architecture. */
1126 tdep = XNEW (struct gdbarch_tdep);
1127 gdbarch = gdbarch_alloc (&info, tdep);
1129 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1130 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1131 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1133 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1134 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1135 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1136 set_gdbarch_register_name (gdbarch, moxie_register_name);
1137 set_gdbarch_register_type (gdbarch, moxie_register_type);
1139 set_gdbarch_return_value (gdbarch, moxie_return_value);
1141 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1142 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1143 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
1144 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1146 frame_base_set_default (gdbarch, &moxie_frame_base);
1148 /* Methods for saving / extracting a dummy frame's ID. The ID's
1149 stack address must match the SP value returned by
1150 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1151 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1153 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1155 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1157 /* Hook in ABI-specific overrides, if they have been registered. */
1158 gdbarch_init_osabi (info, gdbarch);
1160 /* Hook in the default unwinders. */
1161 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1163 /* Single stepping. */
1164 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1166 /* Support simple overlay manager. */
1167 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1169 /* Support reverse debugging. */
1170 set_gdbarch_process_record (gdbarch, moxie_process_record);
1172 return gdbarch;
1175 /* Register this machine's init routine. */
1177 void
1178 _initialize_moxie_tdep (void)
1180 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);