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"
44 /* Local functions. */
46 extern void _initialize_moxie_tdep (void);
48 /* Use an invalid address value as 'not available' marker. */
49 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
51 struct moxie_frame_cache
57 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
61 /* Implement the "frame_align" gdbarch method. */
64 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
71 static unsigned char breakpoint[] = { 0x35, 0x00 };
73 GDBARCH_BREAKPOINT_MANIPULATION (moxie, breakpoint)
75 /* Moxie register names. */
77 char *moxie_register_names[] = {
78 "$fp", "$sp", "$r0", "$r1", "$r2",
79 "$r3", "$r4", "$r5", "$r6", "$r7",
80 "$r8", "$r9", "$r10", "$r11", "$r12",
81 "$r13", "$pc", "$cc" };
83 /* Implement the "register_name" gdbarch method. */
86 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
90 if (reg_nr >= MOXIE_NUM_REGS)
92 return moxie_register_names[reg_nr];
95 /* Implement the "register_type" gdbarch method. */
98 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
100 if (reg_nr == MOXIE_PC_REGNUM)
101 return builtin_type (gdbarch)->builtin_func_ptr;
102 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
103 return builtin_type (gdbarch)->builtin_data_ptr;
105 return builtin_type (gdbarch)->builtin_int32;
108 /* Write into appropriate registers a function return value
109 of type TYPE, given in virtual format. */
112 moxie_store_return_value (struct type *type, struct regcache *regcache,
113 const gdb_byte *valbuf)
115 struct gdbarch *gdbarch = get_regcache_arch (regcache);
116 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
118 int len = TYPE_LENGTH (type);
120 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
121 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
122 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
125 regval = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
126 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
130 /* Decode the instructions within the given address range. Decide
131 when we must have reached the end of the function prologue. If a
132 frame_info pointer is provided, fill in its saved_regs etc.
134 Returns the address of the first instruction after the prologue. */
137 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
138 struct moxie_frame_cache *cache,
139 struct gdbarch *gdbarch)
141 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
143 ULONGEST inst, inst2;
147 /* Record where the jsra instruction saves the PC and FP. */
148 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
149 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
150 cache->framesize = 0;
152 if (start_addr >= end_addr)
155 for (next_addr = start_addr; next_addr < end_addr; )
157 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
159 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
160 if (inst >= 0x0612 && inst <= 0x061f)
162 regnum = inst & 0x000f;
163 cache->framesize += 4;
164 cache->saved_regs[regnum] = cache->framesize;
171 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
173 /* Optional stack allocation for args and local vars <= 4
175 if (inst == 0x01e0) /* ldi.l $r12, X */
177 offset = read_memory_integer (next_addr + 2, 4, byte_order);
178 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
180 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
182 cache->framesize += offset;
185 return (next_addr + 8);
187 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
189 cache->framesize += (inst & 0x00ff);
192 while (next_addr < end_addr)
194 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
195 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
197 cache->framesize += (inst & 0x00ff);
205 /* Find the end of function prologue. */
208 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
210 CORE_ADDR func_addr = 0, func_end = 0;
211 const char *func_name;
213 /* See if we can determine the end of the prologue via the symbol table.
214 If so, then return either PC, or the PC after the prologue, whichever
216 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
218 CORE_ADDR post_prologue_pc
219 = skip_prologue_using_sal (gdbarch, func_addr);
220 if (post_prologue_pc != 0)
221 return std::max (pc, post_prologue_pc);
224 /* Can't determine prologue from the symbol table, need to examine
226 struct symtab_and_line sal;
228 struct moxie_frame_cache cache;
231 memset (&cache, 0, sizeof cache);
233 plg_end = moxie_analyze_prologue (func_addr,
234 func_end, &cache, gdbarch);
235 /* Found a function. */
236 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
237 /* Don't use line number debug info for assembly source
239 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
241 sal = find_pc_line (func_addr, 0);
242 if (sal.end && sal.end < func_end)
244 /* Found a line number, use it as end of
249 /* No useable line symbol. Use result of prologue parsing
255 /* No function symbol -- just return the PC. */
256 return (CORE_ADDR) pc;
259 struct moxie_unwind_cache
261 /* The previous frame's inner most stack address. Used as this
262 frame ID's stack_addr. */
264 /* The frame's base, optionally used by the high-level debug info. */
267 /* How far the SP and r13 (FP) have been offset from the start of
268 the stack frame (as defined by the previous frame's stack
273 /* Table indicating the location of each and every register. */
274 struct trad_frame_saved_reg *saved_regs;
277 /* Read an unsigned integer from the inferior, and adjust
280 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
281 int length, enum bfd_endian byte_order)
283 if (target_read_memory (addr, buf, length))
286 printf_unfiltered (_("Process record: error reading memory at "
287 "addr 0x%s len = %d.\n"),
288 paddress (target_gdbarch (), addr), length);
292 return extract_unsigned_integer (buf, length, byte_order);
296 /* Helper macro to extract the signed 10-bit offset from a 16-bit
297 branch instruction. */
298 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
300 /* Insert a single step breakpoint. */
303 moxie_software_single_step (struct frame_info *frame)
305 struct gdbarch *gdbarch = get_frame_arch (frame);
306 struct address_space *aspace = get_frame_address_space (frame);
312 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
313 struct regcache *regcache = get_current_regcache ();
315 addr = get_frame_pc (frame);
317 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
319 /* Decode instruction. */
320 if (inst & (1 << 15))
322 if (inst & (1 << 14))
324 /* This is a Form 3 instruction. */
325 int opcode = (inst >> 10 & 0xf);
333 case 0x04: /* bltu */
334 case 0x05: /* bgtu */
337 case 0x08: /* bgeu */
338 case 0x09: /* bleu */
339 /* Insert breaks on both branches, because we can't currently tell
340 which way things will go. */
341 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
342 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
353 /* This is a Form 2 instruction. They are all 16 bits. */
354 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
359 /* This is a Form 1 instruction. */
360 int opcode = inst >> 8;
364 /* 16-bit instructions. */
366 case 0x02: /* mov (register-to-register) */
367 case 0x05: /* add.l */
368 case 0x06: /* push */
370 case 0x0a: /* ld.l (register indirect) */
371 case 0x0b: /* st.l */
374 case 0x10: /* sex.b */
375 case 0x11: /* sex.s */
376 case 0x12: /* zex.b */
377 case 0x13: /* zex.s */
378 case 0x14: /* umul.x */
379 case 0x15: /* mul.x */
383 case 0x1c: /* ld.b (register indirect) */
384 case 0x1e: /* st.b */
385 case 0x21: /* ld.s (register indirect) */
386 case 0x23: /* st.s */
388 case 0x27: /* lshr */
389 case 0x28: /* ashl */
390 case 0x29: /* sub.l */
394 case 0x2d: /* ashr */
396 case 0x2f: /* mul.l */
397 case 0x31: /* div.l */
398 case 0x32: /* udiv.l */
399 case 0x33: /* mod.l */
400 case 0x34: /* umod.l */
401 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
404 /* 32-bit instructions. */
405 case 0x0c: /* ldo.l */
406 case 0x0d: /* sto.l */
407 case 0x36: /* ldo.b */
408 case 0x37: /* sto.b */
409 case 0x38: /* ldo.s */
410 case 0x39: /* sto.s */
411 insert_single_step_breakpoint (gdbarch, aspace, addr + 4);
414 /* 48-bit instructions. */
415 case 0x01: /* ldi.l (immediate) */
416 case 0x08: /* lda.l */
417 case 0x09: /* sta.l */
418 case 0x1b: /* ldi.b (immediate) */
419 case 0x1d: /* lda.b */
420 case 0x1f: /* sta.b */
421 case 0x20: /* ldi.s (immediate) */
422 case 0x22: /* lda.s */
423 case 0x24: /* sta.s */
424 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
427 /* Control flow instructions. */
428 case 0x03: /* jsra */
429 case 0x1a: /* jmpa */
430 insert_single_step_breakpoint (gdbarch, aspace,
431 moxie_process_readu (addr + 2,
437 regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
438 insert_single_step_breakpoint (gdbarch, aspace,
439 moxie_process_readu (fp + 4,
446 regcache_raw_read (regcache,
447 (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
448 insert_single_step_breakpoint (gdbarch, aspace,
454 /* Unsupported, for now. */
462 /* Implement the "read_pc" gdbarch method. */
465 moxie_read_pc (struct regcache *regcache)
469 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
473 /* Implement the "write_pc" gdbarch method. */
476 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
478 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
481 /* Implement the "unwind_sp" gdbarch method. */
484 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
486 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
489 /* Given a return value in `regbuf' with a type `valtype',
490 extract and copy its value into `valbuf'. */
493 moxie_extract_return_value (struct type *type, struct regcache *regcache,
496 struct gdbarch *gdbarch = get_regcache_arch (regcache);
497 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
498 int len = TYPE_LENGTH (type);
501 /* By using store_unsigned_integer we avoid having to do
502 anything special for small big-endian values. */
503 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
504 store_unsigned_integer (dst, (len > 4 ? len - 4 : len), byte_order, tmp);
506 /* Ignore return values more than 8 bytes in size because the moxie
507 returns anything more than 8 bytes in the stack. */
510 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
511 store_unsigned_integer (dst + len - 4, 4, byte_order, tmp);
515 /* Implement the "return_value" gdbarch method. */
517 static enum return_value_convention
518 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
519 struct type *valtype, struct regcache *regcache,
520 gdb_byte *readbuf, const gdb_byte *writebuf)
522 if (TYPE_LENGTH (valtype) > 8)
523 return RETURN_VALUE_STRUCT_CONVENTION;
527 moxie_extract_return_value (valtype, regcache, readbuf);
528 if (writebuf != NULL)
529 moxie_store_return_value (valtype, regcache, writebuf);
530 return RETURN_VALUE_REGISTER_CONVENTION;
534 /* Allocate and initialize a moxie_frame_cache object. */
536 static struct moxie_frame_cache *
537 moxie_alloc_frame_cache (void)
539 struct moxie_frame_cache *cache;
542 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
547 cache->framesize = 0;
548 for (i = 0; i < MOXIE_NUM_REGS; ++i)
549 cache->saved_regs[i] = REG_UNAVAIL;
554 /* Populate a moxie_frame_cache object for this_frame. */
556 static struct moxie_frame_cache *
557 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
559 struct moxie_frame_cache *cache;
560 CORE_ADDR current_pc;
564 return (struct moxie_frame_cache *) *this_cache;
566 cache = moxie_alloc_frame_cache ();
569 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
570 if (cache->base == 0)
573 cache->pc = get_frame_func (this_frame);
574 current_pc = get_frame_pc (this_frame);
577 struct gdbarch *gdbarch = get_frame_arch (this_frame);
578 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
581 cache->saved_sp = cache->base - cache->framesize;
583 for (i = 0; i < MOXIE_NUM_REGS; ++i)
584 if (cache->saved_regs[i] != REG_UNAVAIL)
585 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
590 /* Implement the "unwind_pc" gdbarch method. */
593 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
595 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
598 /* Given a GDB frame, determine the address of the calling function's
599 frame. This will be used to create a new GDB frame struct. */
602 moxie_frame_this_id (struct frame_info *this_frame,
603 void **this_prologue_cache, struct frame_id *this_id)
605 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
606 this_prologue_cache);
608 /* This marks the outermost frame. */
609 if (cache->base == 0)
612 *this_id = frame_id_build (cache->saved_sp, cache->pc);
615 /* Get the value of register regnum in the previous stack frame. */
617 static struct value *
618 moxie_frame_prev_register (struct frame_info *this_frame,
619 void **this_prologue_cache, int regnum)
621 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
622 this_prologue_cache);
624 gdb_assert (regnum >= 0);
626 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
627 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
629 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
630 return frame_unwind_got_memory (this_frame, regnum,
631 cache->saved_regs[regnum]);
633 return frame_unwind_got_register (this_frame, regnum, regnum);
636 static const struct frame_unwind moxie_frame_unwind = {
638 default_frame_unwind_stop_reason,
640 moxie_frame_prev_register,
642 default_frame_sniffer
645 /* Return the base address of this_frame. */
648 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
650 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
656 static const struct frame_base moxie_frame_base = {
658 moxie_frame_base_address,
659 moxie_frame_base_address,
660 moxie_frame_base_address
663 static struct frame_id
664 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
666 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
668 return frame_id_build (sp, get_frame_pc (this_frame));
671 /* Parse the current instruction and record the values of the registers and
672 memory that will be changed in current instruction to "record_arch_list".
673 Return -1 if something wrong. */
676 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
682 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
684 if (record_debug > 1)
685 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
687 paddress (target_gdbarch (), addr));
689 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
691 /* Decode instruction. */
692 if (inst & (1 << 15))
694 if (inst & (1 << 14))
696 /* This is a Form 3 instruction. */
697 int opcode = (inst >> 10 & 0xf);
705 case 0x04: /* bltu */
706 case 0x05: /* bgtu */
709 case 0x08: /* bgeu */
710 case 0x09: /* bleu */
722 /* This is a Form 2 instruction. */
723 int opcode = (inst >> 12 & 0x3);
730 int reg = (inst >> 8) & 0xf;
731 if (record_full_arch_list_add_reg (regcache, reg))
737 /* Do nothing until GDB learns about moxie's special
749 /* This is a Form 1 instruction. */
750 int opcode = inst >> 8;
757 case 0x01: /* ldi.l (immediate) */
758 case 0x02: /* mov (register-to-register) */
760 int reg = (inst >> 4) & 0xf;
761 if (record_full_arch_list_add_reg (regcache, reg))
765 case 0x03: /* jsra */
767 regcache_raw_read (regcache,
768 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
769 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
771 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
772 || (record_full_arch_list_add_reg (regcache,
774 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
780 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
781 || (record_full_arch_list_add_reg (regcache,
786 case 0x05: /* add.l */
788 int reg = (inst >> 4) & 0xf;
789 if (record_full_arch_list_add_reg (regcache, reg))
793 case 0x06: /* push */
795 int reg = (inst >> 4) & 0xf;
796 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
797 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
799 if (record_full_arch_list_add_reg (regcache, reg)
800 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
806 int a = (inst >> 4) & 0xf;
808 if (record_full_arch_list_add_reg (regcache, a)
809 || record_full_arch_list_add_reg (regcache, b))
813 case 0x08: /* lda.l */
815 int reg = (inst >> 4) & 0xf;
816 if (record_full_arch_list_add_reg (regcache, reg))
820 case 0x09: /* sta.l */
822 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
824 if (record_full_arch_list_add_mem (tmpu32, 4))
828 case 0x0a: /* ld.l (register indirect) */
830 int reg = (inst >> 4) & 0xf;
831 if (record_full_arch_list_add_reg (regcache, reg))
835 case 0x0b: /* st.l */
837 int reg = (inst >> 4) & 0xf;
838 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
839 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
841 if (record_full_arch_list_add_mem (tmpu32, 4))
845 case 0x0c: /* ldo.l */
847 int reg = (inst >> 4) & 0xf;
848 if (record_full_arch_list_add_reg (regcache, reg))
852 case 0x0d: /* sto.l */
854 int reg = (inst >> 4) & 0xf;
855 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
856 byte_order)) << 16 ) >> 16;
857 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
858 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
861 if (record_full_arch_list_add_mem (tmpu32, 4))
867 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
876 case 0x10: /* sex.b */
877 case 0x11: /* sex.s */
878 case 0x12: /* zex.b */
879 case 0x13: /* zex.s */
880 case 0x14: /* umul.x */
881 case 0x15: /* mul.x */
883 int reg = (inst >> 4) & 0xf;
884 if (record_full_arch_list_add_reg (regcache, reg))
897 regcache_raw_read (regcache,
898 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
899 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
901 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
902 || (record_full_arch_list_add_reg (regcache,
904 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
908 case 0x1a: /* jmpa */
913 case 0x1b: /* ldi.b (immediate) */
914 case 0x1c: /* ld.b (register indirect) */
915 case 0x1d: /* lda.b */
917 int reg = (inst >> 4) & 0xf;
918 if (record_full_arch_list_add_reg (regcache, reg))
922 case 0x1e: /* st.b */
924 int reg = (inst >> 4) & 0xf;
925 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
926 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
928 if (record_full_arch_list_add_mem (tmpu32, 1))
932 case 0x1f: /* sta.b */
934 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
935 if (record_full_arch_list_add_mem (tmpu32, 1))
939 case 0x20: /* ldi.s (immediate) */
940 case 0x21: /* ld.s (register indirect) */
941 case 0x22: /* lda.s */
943 int reg = (inst >> 4) & 0xf;
944 if (record_full_arch_list_add_reg (regcache, reg))
948 case 0x23: /* st.s */
950 int reg = (inst >> 4) & 0xf;
951 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
952 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
954 if (record_full_arch_list_add_mem (tmpu32, 2))
958 case 0x24: /* sta.s */
960 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
961 if (record_full_arch_list_add_mem (tmpu32, 2))
971 case 0x27: /* lshr */
972 case 0x28: /* ashl */
977 case 0x2d: /* ashr */
981 int reg = (inst >> 4) & 0xf;
982 if (record_full_arch_list_add_reg (regcache, reg))
988 /* We currently implement support for libgloss'
991 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
995 case 0x1: /* SYS_exit */
1000 case 0x2: /* SYS_open */
1002 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1006 case 0x4: /* SYS_read */
1008 uint32_t length, ptr;
1010 /* Read buffer pointer is in $r1. */
1011 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1012 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1015 /* String length is at 0x12($fp). */
1016 regcache_raw_read (regcache,
1017 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1018 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1020 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1022 if (record_full_arch_list_add_mem (ptr, length))
1026 case 0x5: /* SYS_write */
1028 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1037 case 0x31: /* div.l */
1038 case 0x32: /* udiv.l */
1039 case 0x33: /* mod.l */
1040 case 0x34: /* umod.l */
1042 int reg = (inst >> 4) & 0xf;
1043 if (record_full_arch_list_add_reg (regcache, reg))
1047 case 0x35: /* brk */
1050 case 0x36: /* ldo.b */
1052 int reg = (inst >> 4) & 0xf;
1053 if (record_full_arch_list_add_reg (regcache, reg))
1057 case 0x37: /* sto.b */
1059 int reg = (inst >> 4) & 0xf;
1060 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1061 byte_order)) << 16 ) >> 16;
1062 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1063 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1066 if (record_full_arch_list_add_mem (tmpu32, 1))
1070 case 0x38: /* ldo.s */
1072 int reg = (inst >> 4) & 0xf;
1073 if (record_full_arch_list_add_reg (regcache, reg))
1077 case 0x39: /* sto.s */
1079 int reg = (inst >> 4) & 0xf;
1080 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1081 byte_order)) << 16 ) >> 16;
1082 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1083 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1086 if (record_full_arch_list_add_mem (tmpu32, 2))
1096 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1098 if (record_full_arch_list_add_end ())
1103 /* Allocate and initialize the moxie gdbarch object. */
1105 static struct gdbarch *
1106 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1108 struct gdbarch *gdbarch;
1109 struct gdbarch_tdep *tdep;
1111 /* If there is already a candidate, use it. */
1112 arches = gdbarch_list_lookup_by_info (arches, &info);
1114 return arches->gdbarch;
1116 /* Allocate space for the new architecture. */
1117 tdep = XNEW (struct gdbarch_tdep);
1118 gdbarch = gdbarch_alloc (&info, tdep);
1120 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1121 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1122 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1124 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1125 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1126 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1127 set_gdbarch_register_name (gdbarch, moxie_register_name);
1128 set_gdbarch_register_type (gdbarch, moxie_register_type);
1130 set_gdbarch_return_value (gdbarch, moxie_return_value);
1132 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1133 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1134 SET_GDBARCH_BREAKPOINT_MANIPULATION (moxie);
1135 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1137 frame_base_set_default (gdbarch, &moxie_frame_base);
1139 /* Methods for saving / extracting a dummy frame's ID. The ID's
1140 stack address must match the SP value returned by
1141 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1142 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1144 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1146 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1148 /* Hook in ABI-specific overrides, if they have been registered. */
1149 gdbarch_init_osabi (info, gdbarch);
1151 /* Hook in the default unwinders. */
1152 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1154 /* Single stepping. */
1155 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1157 /* Support simple overlay manager. */
1158 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1160 /* Support reverse debugging. */
1161 set_gdbarch_process_record (gdbarch, moxie_process_record);
1166 /* Register this machine's init routine. */
1169 _initialize_moxie_tdep (void)
1171 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);