1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009-2016 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/>. */
22 #include "frame-unwind.h"
23 #include "frame-base.h"
34 #include "arch-utils.h"
36 #include "trad-frame.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
56 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
60 /* Implement the "frame_align" gdbarch method. */
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. */
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);
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. */
93 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
97 if (reg_nr >= MOXIE_NUM_REGS)
99 return moxie_register_names[reg_nr];
102 /* Implement the "register_type" gdbarch method. */
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;
112 return builtin_type (gdbarch)->builtin_int32;
115 /* Write into appropriate registers a function return value
116 of type TYPE, given in virtual format. */
119 moxie_store_return_value (struct type *type, struct regcache *regcache,
120 const gdb_byte *valbuf)
122 struct gdbarch *gdbarch = get_regcache_arch (regcache);
123 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
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);
132 regval = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
133 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
137 /* Decode the instructions within the given address range. Decide
138 when we must have reached the end of the function prologue. If a
139 frame_info pointer is provided, fill in its saved_regs etc.
141 Returns the address of the first instruction after the prologue. */
144 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
145 struct moxie_frame_cache *cache,
146 struct gdbarch *gdbarch)
148 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
150 ULONGEST inst, inst2;
154 /* Record where the jsra instruction saves the PC and FP. */
155 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
156 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
157 cache->framesize = 0;
159 if (start_addr >= end_addr)
162 for (next_addr = start_addr; next_addr < end_addr; )
164 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
166 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
167 if (inst >= 0x0612 && inst <= 0x061f)
169 regnum = inst & 0x000f;
170 cache->framesize += 4;
171 cache->saved_regs[regnum] = cache->framesize;
178 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
180 /* Optional stack allocation for args and local vars <= 4
182 if (inst == 0x01e0) /* ldi.l $r12, X */
184 offset = read_memory_integer (next_addr + 2, 4, byte_order);
185 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
187 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
189 cache->framesize += offset;
192 return (next_addr + 8);
194 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
196 cache->framesize += (inst & 0x00ff);
199 while (next_addr < end_addr)
201 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
202 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
204 cache->framesize += (inst & 0x00ff);
212 /* Find the end of function prologue. */
215 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
217 CORE_ADDR func_addr = 0, func_end = 0;
218 const char *func_name;
220 /* See if we can determine the end of the prologue via the symbol table.
221 If so, then return either PC, or the PC after the prologue, whichever
223 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
225 CORE_ADDR post_prologue_pc
226 = skip_prologue_using_sal (gdbarch, func_addr);
227 if (post_prologue_pc != 0)
228 return max (pc, post_prologue_pc);
231 /* Can't determine prologue from the symbol table, need to examine
233 struct symtab_and_line sal;
235 struct moxie_frame_cache cache;
238 memset (&cache, 0, sizeof cache);
240 plg_end = moxie_analyze_prologue (func_addr,
241 func_end, &cache, gdbarch);
242 /* Found a function. */
243 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
244 /* Don't use line number debug info for assembly source
246 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
248 sal = find_pc_line (func_addr, 0);
249 if (sal.end && sal.end < func_end)
251 /* Found a line number, use it as end of
256 /* No useable line symbol. Use result of prologue parsing
262 /* No function symbol -- just return the PC. */
263 return (CORE_ADDR) pc;
266 struct moxie_unwind_cache
268 /* The previous frame's inner most stack address. Used as this
269 frame ID's stack_addr. */
271 /* The frame's base, optionally used by the high-level debug info. */
274 /* How far the SP and r13 (FP) have been offset from the start of
275 the stack frame (as defined by the previous frame's stack
280 /* Table indicating the location of each and every register. */
281 struct trad_frame_saved_reg *saved_regs;
284 /* Read an unsigned integer from the inferior, and adjust
287 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
288 int length, enum bfd_endian byte_order)
290 if (target_read_memory (addr, buf, length))
293 printf_unfiltered (_("Process record: error reading memory at "
294 "addr 0x%s len = %d.\n"),
295 paddress (target_gdbarch (), addr), length);
299 return extract_unsigned_integer (buf, length, byte_order);
303 /* Helper macro to extract the signed 10-bit offset from a 16-bit
304 branch instruction. */
305 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
307 /* Insert a single step breakpoint. */
310 moxie_software_single_step (struct frame_info *frame)
312 struct gdbarch *gdbarch = get_frame_arch (frame);
313 struct address_space *aspace = get_frame_address_space (frame);
319 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
320 struct regcache *regcache = get_current_regcache ();
322 addr = get_frame_pc (frame);
324 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
326 /* Decode instruction. */
327 if (inst & (1 << 15))
329 if (inst & (1 << 14))
331 /* This is a Form 3 instruction. */
332 int opcode = (inst >> 10 & 0xf);
340 case 0x04: /* bltu */
341 case 0x05: /* bgtu */
344 case 0x08: /* bgeu */
345 case 0x09: /* bleu */
346 /* Insert breaks on both branches, because we can't currently tell
347 which way things will go. */
348 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
349 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
360 /* This is a Form 2 instruction. They are all 16 bits. */
361 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
366 /* This is a Form 1 instruction. */
367 int opcode = inst >> 8;
371 /* 16-bit instructions. */
373 case 0x02: /* mov (register-to-register) */
374 case 0x05: /* add.l */
375 case 0x06: /* push */
377 case 0x0a: /* ld.l (register indirect) */
378 case 0x0b: /* st.l */
381 case 0x10: /* sex.b */
382 case 0x11: /* sex.s */
383 case 0x12: /* zex.b */
384 case 0x13: /* zex.s */
385 case 0x14: /* umul.x */
386 case 0x15: /* mul.x */
390 case 0x1c: /* ld.b (register indirect) */
391 case 0x1e: /* st.b */
392 case 0x21: /* ld.s (register indirect) */
393 case 0x23: /* st.s */
395 case 0x27: /* lshr */
396 case 0x28: /* ashl */
397 case 0x29: /* sub.l */
401 case 0x2d: /* ashr */
403 case 0x2f: /* mul.l */
404 case 0x31: /* div.l */
405 case 0x32: /* udiv.l */
406 case 0x33: /* mod.l */
407 case 0x34: /* umod.l */
408 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
411 /* 32-bit instructions. */
412 case 0x0c: /* ldo.l */
413 case 0x0d: /* sto.l */
414 case 0x36: /* ldo.b */
415 case 0x37: /* sto.b */
416 case 0x38: /* ldo.s */
417 case 0x39: /* sto.s */
418 insert_single_step_breakpoint (gdbarch, aspace, addr + 4);
421 /* 48-bit instructions. */
422 case 0x01: /* ldi.l (immediate) */
423 case 0x08: /* lda.l */
424 case 0x09: /* sta.l */
425 case 0x1b: /* ldi.b (immediate) */
426 case 0x1d: /* lda.b */
427 case 0x1f: /* sta.b */
428 case 0x20: /* ldi.s (immediate) */
429 case 0x22: /* lda.s */
430 case 0x24: /* sta.s */
431 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
434 /* Control flow instructions. */
435 case 0x03: /* jsra */
436 case 0x1a: /* jmpa */
437 insert_single_step_breakpoint (gdbarch, aspace,
438 moxie_process_readu (addr + 2,
444 regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
445 insert_single_step_breakpoint (gdbarch, aspace,
446 moxie_process_readu (fp + 4,
453 regcache_raw_read (regcache,
454 (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
455 insert_single_step_breakpoint (gdbarch, aspace,
461 /* Unsupported, for now. */
469 /* Implement the "read_pc" gdbarch method. */
472 moxie_read_pc (struct regcache *regcache)
476 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
480 /* Implement the "write_pc" gdbarch method. */
483 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
485 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
488 /* Implement the "unwind_sp" gdbarch method. */
491 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
493 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
496 /* Given a return value in `regbuf' with a type `valtype',
497 extract and copy its value into `valbuf'. */
500 moxie_extract_return_value (struct type *type, struct regcache *regcache,
503 struct gdbarch *gdbarch = get_regcache_arch (regcache);
504 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
505 int len = TYPE_LENGTH (type);
508 /* By using store_unsigned_integer we avoid having to do
509 anything special for small big-endian values. */
510 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
511 store_unsigned_integer (dst, (len > 4 ? len - 4 : len), byte_order, tmp);
513 /* Ignore return values more than 8 bytes in size because the moxie
514 returns anything more than 8 bytes in the stack. */
517 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
518 store_unsigned_integer (dst + len - 4, 4, byte_order, tmp);
522 /* Implement the "return_value" gdbarch method. */
524 static enum return_value_convention
525 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
526 struct type *valtype, struct regcache *regcache,
527 gdb_byte *readbuf, const gdb_byte *writebuf)
529 if (TYPE_LENGTH (valtype) > 8)
530 return RETURN_VALUE_STRUCT_CONVENTION;
534 moxie_extract_return_value (valtype, regcache, readbuf);
535 if (writebuf != NULL)
536 moxie_store_return_value (valtype, regcache, writebuf);
537 return RETURN_VALUE_REGISTER_CONVENTION;
541 /* Allocate and initialize a moxie_frame_cache object. */
543 static struct moxie_frame_cache *
544 moxie_alloc_frame_cache (void)
546 struct moxie_frame_cache *cache;
549 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
554 cache->framesize = 0;
555 for (i = 0; i < MOXIE_NUM_REGS; ++i)
556 cache->saved_regs[i] = REG_UNAVAIL;
561 /* Populate a moxie_frame_cache object for this_frame. */
563 static struct moxie_frame_cache *
564 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
566 struct moxie_frame_cache *cache;
567 CORE_ADDR current_pc;
571 return (struct moxie_frame_cache *) *this_cache;
573 cache = moxie_alloc_frame_cache ();
576 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
577 if (cache->base == 0)
580 cache->pc = get_frame_func (this_frame);
581 current_pc = get_frame_pc (this_frame);
584 struct gdbarch *gdbarch = get_frame_arch (this_frame);
585 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
588 cache->saved_sp = cache->base - cache->framesize;
590 for (i = 0; i < MOXIE_NUM_REGS; ++i)
591 if (cache->saved_regs[i] != REG_UNAVAIL)
592 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
597 /* Implement the "unwind_pc" gdbarch method. */
600 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
602 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
605 /* Given a GDB frame, determine the address of the calling function's
606 frame. This will be used to create a new GDB frame struct. */
609 moxie_frame_this_id (struct frame_info *this_frame,
610 void **this_prologue_cache, struct frame_id *this_id)
612 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
613 this_prologue_cache);
615 /* This marks the outermost frame. */
616 if (cache->base == 0)
619 *this_id = frame_id_build (cache->saved_sp, cache->pc);
622 /* Get the value of register regnum in the previous stack frame. */
624 static struct value *
625 moxie_frame_prev_register (struct frame_info *this_frame,
626 void **this_prologue_cache, int regnum)
628 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
629 this_prologue_cache);
631 gdb_assert (regnum >= 0);
633 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
634 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
636 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
637 return frame_unwind_got_memory (this_frame, regnum,
638 cache->saved_regs[regnum]);
640 return frame_unwind_got_register (this_frame, regnum, regnum);
643 static const struct frame_unwind moxie_frame_unwind = {
645 default_frame_unwind_stop_reason,
647 moxie_frame_prev_register,
649 default_frame_sniffer
652 /* Return the base address of this_frame. */
655 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
657 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
663 static const struct frame_base moxie_frame_base = {
665 moxie_frame_base_address,
666 moxie_frame_base_address,
667 moxie_frame_base_address
670 static struct frame_id
671 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
673 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
675 return frame_id_build (sp, get_frame_pc (this_frame));
678 /* Parse the current instruction and record the values of the registers and
679 memory that will be changed in current instruction to "record_arch_list".
680 Return -1 if something wrong. */
683 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
689 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
691 if (record_debug > 1)
692 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
694 paddress (target_gdbarch (), addr));
696 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
698 /* Decode instruction. */
699 if (inst & (1 << 15))
701 if (inst & (1 << 14))
703 /* This is a Form 3 instruction. */
704 int opcode = (inst >> 10 & 0xf);
712 case 0x04: /* bltu */
713 case 0x05: /* bgtu */
716 case 0x08: /* bgeu */
717 case 0x09: /* bleu */
729 /* This is a Form 2 instruction. */
730 int opcode = (inst >> 12 & 0x3);
737 int reg = (inst >> 8) & 0xf;
738 if (record_full_arch_list_add_reg (regcache, reg))
744 /* Do nothing until GDB learns about moxie's special
756 /* This is a Form 1 instruction. */
757 int opcode = inst >> 8;
764 case 0x01: /* ldi.l (immediate) */
765 case 0x02: /* mov (register-to-register) */
767 int reg = (inst >> 4) & 0xf;
768 if (record_full_arch_list_add_reg (regcache, reg))
772 case 0x03: /* jsra */
774 regcache_raw_read (regcache,
775 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
776 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
778 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
779 || (record_full_arch_list_add_reg (regcache,
781 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
787 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
788 || (record_full_arch_list_add_reg (regcache,
793 case 0x05: /* add.l */
795 int reg = (inst >> 4) & 0xf;
796 if (record_full_arch_list_add_reg (regcache, reg))
800 case 0x06: /* push */
802 int reg = (inst >> 4) & 0xf;
803 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
804 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
806 if (record_full_arch_list_add_reg (regcache, reg)
807 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
813 int a = (inst >> 4) & 0xf;
815 if (record_full_arch_list_add_reg (regcache, a)
816 || record_full_arch_list_add_reg (regcache, b))
820 case 0x08: /* lda.l */
822 int reg = (inst >> 4) & 0xf;
823 if (record_full_arch_list_add_reg (regcache, reg))
827 case 0x09: /* sta.l */
829 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
831 if (record_full_arch_list_add_mem (tmpu32, 4))
835 case 0x0a: /* ld.l (register indirect) */
837 int reg = (inst >> 4) & 0xf;
838 if (record_full_arch_list_add_reg (regcache, reg))
842 case 0x0b: /* st.l */
844 int reg = (inst >> 4) & 0xf;
845 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
846 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
848 if (record_full_arch_list_add_mem (tmpu32, 4))
852 case 0x0c: /* ldo.l */
854 int reg = (inst >> 4) & 0xf;
855 if (record_full_arch_list_add_reg (regcache, reg))
859 case 0x0d: /* sto.l */
861 int reg = (inst >> 4) & 0xf;
862 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
863 byte_order)) << 16 ) >> 16;
864 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
865 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
868 if (record_full_arch_list_add_mem (tmpu32, 4))
874 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
883 case 0x10: /* sex.b */
884 case 0x11: /* sex.s */
885 case 0x12: /* zex.b */
886 case 0x13: /* zex.s */
887 case 0x14: /* umul.x */
888 case 0x15: /* mul.x */
890 int reg = (inst >> 4) & 0xf;
891 if (record_full_arch_list_add_reg (regcache, reg))
904 regcache_raw_read (regcache,
905 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
906 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
908 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
909 || (record_full_arch_list_add_reg (regcache,
911 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
915 case 0x1a: /* jmpa */
920 case 0x1b: /* ldi.b (immediate) */
921 case 0x1c: /* ld.b (register indirect) */
922 case 0x1d: /* lda.b */
924 int reg = (inst >> 4) & 0xf;
925 if (record_full_arch_list_add_reg (regcache, reg))
929 case 0x1e: /* st.b */
931 int reg = (inst >> 4) & 0xf;
932 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
933 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
935 if (record_full_arch_list_add_mem (tmpu32, 1))
939 case 0x1f: /* sta.b */
941 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
942 if (record_full_arch_list_add_mem (tmpu32, 1))
946 case 0x20: /* ldi.s (immediate) */
947 case 0x21: /* ld.s (register indirect) */
948 case 0x22: /* lda.s */
950 int reg = (inst >> 4) & 0xf;
951 if (record_full_arch_list_add_reg (regcache, reg))
955 case 0x23: /* st.s */
957 int reg = (inst >> 4) & 0xf;
958 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
959 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
961 if (record_full_arch_list_add_mem (tmpu32, 2))
965 case 0x24: /* sta.s */
967 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
968 if (record_full_arch_list_add_mem (tmpu32, 2))
978 case 0x27: /* lshr */
979 case 0x28: /* ashl */
984 case 0x2d: /* ashr */
988 int reg = (inst >> 4) & 0xf;
989 if (record_full_arch_list_add_reg (regcache, reg))
995 /* We currently implement support for libgloss'
998 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
1002 case 0x1: /* SYS_exit */
1007 case 0x2: /* SYS_open */
1009 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1013 case 0x4: /* SYS_read */
1015 uint32_t length, ptr;
1017 /* Read buffer pointer is in $r1. */
1018 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1019 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1022 /* String length is at 0x12($fp). */
1023 regcache_raw_read (regcache,
1024 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1025 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1027 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1029 if (record_full_arch_list_add_mem (ptr, length))
1033 case 0x5: /* SYS_write */
1035 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1044 case 0x31: /* div.l */
1045 case 0x32: /* udiv.l */
1046 case 0x33: /* mod.l */
1047 case 0x34: /* umod.l */
1049 int reg = (inst >> 4) & 0xf;
1050 if (record_full_arch_list_add_reg (regcache, reg))
1054 case 0x35: /* brk */
1057 case 0x36: /* ldo.b */
1059 int reg = (inst >> 4) & 0xf;
1060 if (record_full_arch_list_add_reg (regcache, reg))
1064 case 0x37: /* sto.b */
1066 int reg = (inst >> 4) & 0xf;
1067 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1068 byte_order)) << 16 ) >> 16;
1069 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1070 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1073 if (record_full_arch_list_add_mem (tmpu32, 1))
1077 case 0x38: /* ldo.s */
1079 int reg = (inst >> 4) & 0xf;
1080 if (record_full_arch_list_add_reg (regcache, reg))
1084 case 0x39: /* sto.s */
1086 int reg = (inst >> 4) & 0xf;
1087 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1088 byte_order)) << 16 ) >> 16;
1089 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1090 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1093 if (record_full_arch_list_add_mem (tmpu32, 2))
1103 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1105 if (record_full_arch_list_add_end ())
1110 /* Allocate and initialize the moxie gdbarch object. */
1112 static struct gdbarch *
1113 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1115 struct gdbarch *gdbarch;
1116 struct gdbarch_tdep *tdep;
1118 /* If there is already a candidate, use it. */
1119 arches = gdbarch_list_lookup_by_info (arches, &info);
1121 return arches->gdbarch;
1123 /* Allocate space for the new architecture. */
1124 tdep = XNEW (struct gdbarch_tdep);
1125 gdbarch = gdbarch_alloc (&info, tdep);
1127 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1128 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1129 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1131 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1132 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1133 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1134 set_gdbarch_register_name (gdbarch, moxie_register_name);
1135 set_gdbarch_register_type (gdbarch, moxie_register_type);
1137 set_gdbarch_return_value (gdbarch, moxie_return_value);
1139 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1140 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1141 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
1142 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1144 frame_base_set_default (gdbarch, &moxie_frame_base);
1146 /* Methods for saving / extracting a dummy frame's ID. The ID's
1147 stack address must match the SP value returned by
1148 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1149 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1151 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1153 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1155 /* Hook in ABI-specific overrides, if they have been registered. */
1156 gdbarch_init_osabi (info, gdbarch);
1158 /* Hook in the default unwinders. */
1159 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1161 /* Single stepping. */
1162 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1164 /* Support simple overlay manager. */
1165 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1167 /* Support reverse debugging. */
1168 set_gdbarch_process_record (gdbarch, moxie_process_record);
1173 /* Register this machine's init routine. */
1176 _initialize_moxie_tdep (void)
1178 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);