1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009-2014 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"
35 #include "arch-utils.h"
37 #include "trad-frame.h"
40 #include "record-full.h"
42 #include "gdb_assert.h"
44 #include "moxie-tdep.h"
46 /* Local functions. */
48 extern void _initialize_moxie_tdep (void);
50 /* Use an invalid address value as 'not available' marker. */
51 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
53 struct moxie_frame_cache
59 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
63 /* Implement the "frame_align" gdbarch method. */
66 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
68 /* Align to the size of an instruction (so that they can safely be
69 pushed onto the stack. */
73 /* Implement the "breakpoint_from_pc" gdbarch method. */
75 static const unsigned char *
76 moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
77 CORE_ADDR *pcptr, int *lenptr)
79 static unsigned char breakpoint[] = { 0x35, 0x00 };
81 *lenptr = sizeof (breakpoint);
85 /* Moxie register names. */
87 char *moxie_register_names[] = {
88 "$fp", "$sp", "$r0", "$r1", "$r2",
89 "$r3", "$r4", "$r5", "$r6", "$r7",
90 "$r8", "$r9", "$r10", "$r11", "$r12",
91 "$r13", "$pc", "$cc" };
93 /* Implement the "register_name" gdbarch method. */
96 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
100 if (reg_nr >= MOXIE_NUM_REGS)
102 return moxie_register_names[reg_nr];
105 /* Implement the "register_type" gdbarch method. */
108 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
110 if (reg_nr == MOXIE_PC_REGNUM)
111 return builtin_type (gdbarch)->builtin_func_ptr;
112 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
113 return builtin_type (gdbarch)->builtin_data_ptr;
115 return builtin_type (gdbarch)->builtin_int32;
118 /* Write into appropriate registers a function return value
119 of type TYPE, given in virtual format. */
122 moxie_store_return_value (struct type *type, struct regcache *regcache,
125 struct gdbarch *gdbarch = get_regcache_arch (regcache);
126 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
128 int len = TYPE_LENGTH (type);
130 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
131 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
132 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
135 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
136 len - 4, byte_order);
137 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
141 /* Decode the instructions within the given address range. Decide
142 when we must have reached the end of the function prologue. If a
143 frame_info pointer is provided, fill in its saved_regs etc.
145 Returns the address of the first instruction after the prologue. */
148 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
149 struct moxie_frame_cache *cache,
150 struct gdbarch *gdbarch)
152 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
154 ULONGEST inst, inst2;
158 /* Record where the jsra instruction saves the PC and FP. */
159 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
160 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
161 cache->framesize = 0;
163 if (start_addr >= end_addr)
166 for (next_addr = start_addr; next_addr < end_addr; )
168 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
170 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
171 if (inst >= 0x0612 && inst <= 0x061f)
173 regnum = inst & 0x000f;
174 cache->framesize += 4;
175 cache->saved_regs[regnum] = cache->framesize;
182 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
184 /* Optional stack allocation for args and local vars <= 4
186 if (inst == 0x01e0) /* ldi.l $r12, X */
188 offset = read_memory_integer (next_addr + 2, 4, byte_order);
189 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
191 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
193 cache->framesize += offset;
196 return (next_addr + 8);
198 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
200 cache->framesize += (inst & 0x00ff);
203 while (next_addr < end_addr)
205 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
206 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
208 cache->framesize += (inst & 0x00ff);
216 /* Find the end of function prologue. */
219 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
221 CORE_ADDR func_addr = 0, func_end = 0;
222 const char *func_name;
224 /* See if we can determine the end of the prologue via the symbol table.
225 If so, then return either PC, or the PC after the prologue, whichever
227 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
229 CORE_ADDR post_prologue_pc
230 = skip_prologue_using_sal (gdbarch, func_addr);
231 if (post_prologue_pc != 0)
232 return max (pc, post_prologue_pc);
235 /* Can't determine prologue from the symbol table, need to examine
237 struct symtab_and_line sal;
239 struct moxie_frame_cache cache;
242 memset (&cache, 0, sizeof cache);
244 plg_end = moxie_analyze_prologue (func_addr,
245 func_end, &cache, gdbarch);
246 /* Found a function. */
247 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
248 /* Don't use line number debug info for assembly source
250 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
252 sal = find_pc_line (func_addr, 0);
253 if (sal.end && sal.end < func_end)
255 /* Found a line number, use it as end of
260 /* No useable line symbol. Use result of prologue parsing
266 /* No function symbol -- just return the PC. */
267 return (CORE_ADDR) pc;
270 struct moxie_unwind_cache
272 /* The previous frame's inner most stack address. Used as this
273 frame ID's stack_addr. */
275 /* The frame's base, optionally used by the high-level debug info. */
278 /* How far the SP and r13 (FP) have been offset from the start of
279 the stack frame (as defined by the previous frame's stack
284 /* Table indicating the location of each and every register. */
285 struct trad_frame_saved_reg *saved_regs;
288 /* Read an unsigned integer from the inferior, and adjust
291 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
292 int length, enum bfd_endian byte_order)
294 if (target_read_memory (addr, buf, length))
297 printf_unfiltered (_("Process record: error reading memory at "
298 "addr 0x%s len = %d.\n"),
299 paddress (target_gdbarch (), addr), length);
303 return extract_unsigned_integer (buf, length, byte_order);
307 /* Helper macro to extract the signed 10-bit offset from a 16-bit
308 branch instruction. */
309 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
311 /* Insert a single step breakpoint. */
314 moxie_software_single_step (struct frame_info *frame)
316 struct gdbarch *gdbarch = get_frame_arch (frame);
317 struct address_space *aspace = get_frame_address_space (frame);
323 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
324 struct regcache *regcache = get_current_regcache ();
326 addr = get_frame_pc (frame);
328 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
330 /* Decode instruction. */
331 if (inst & (1 << 15))
333 if (inst & (1 << 14))
335 /* This is a Form 3 instruction. */
336 int opcode = (inst >> 10 & 0xf);
344 case 0x04: /* bltu */
345 case 0x05: /* bgtu */
348 case 0x08: /* bgeu */
349 case 0x09: /* bleu */
350 /* Insert breaks on both branches, because we can't currently tell
351 which way things will go. */
352 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
353 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
364 /* This is a Form 2 instruction. They are all 16 bits. */
365 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
370 /* This is a Form 1 instruction. */
371 int opcode = inst >> 8;
375 /* 16-bit instructions. */
377 case 0x02: /* mov (register-to-register) */
378 case 0x05: /* add.l */
379 case 0x06: /* push */
381 case 0x0a: /* ld.l (register indirect) */
382 case 0x0b: /* st.l */
394 case 0x1c: /* ld.b (register indirect) */
395 case 0x1e: /* st.b */
396 case 0x21: /* ld.s (register indirect) */
397 case 0x23: /* st.s */
399 case 0x27: /* lshr */
400 case 0x28: /* ashl */
401 case 0x29: /* sub.l */
405 case 0x2d: /* ashr */
407 case 0x2f: /* mul.l */
408 case 0x31: /* div.l */
409 case 0x32: /* udiv.l */
410 case 0x33: /* mod.l */
411 case 0x34: /* umod.l */
412 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
415 /* 48-bit instructions. */
416 case 0x01: /* ldi.l (immediate) */
417 case 0x08: /* lda.l */
418 case 0x09: /* sta.l */
419 case 0x0c: /* ldo.l */
420 case 0x0d: /* sto.l */
421 case 0x1b: /* ldi.b (immediate) */
422 case 0x1d: /* lda.b */
423 case 0x1f: /* sta.b */
424 case 0x20: /* ldi.s (immediate) */
425 case 0x22: /* lda.s */
426 case 0x24: /* sta.s */
427 case 0x36: /* ldo.b */
428 case 0x37: /* sto.b */
429 case 0x38: /* ldo.s */
430 case 0x39: /* sto.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 bfd_byte *valbuf = dst;
506 int len = TYPE_LENGTH (type);
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);
512 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
514 /* Ignore return values more than 8 bytes in size because the moxie
515 returns anything more than 8 bytes in the stack. */
518 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
519 store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
523 /* Implement the "return_value" gdbarch method. */
525 static enum return_value_convention
526 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
527 struct type *valtype, struct regcache *regcache,
528 gdb_byte *readbuf, const gdb_byte *writebuf)
530 if (TYPE_LENGTH (valtype) > 8)
531 return RETURN_VALUE_STRUCT_CONVENTION;
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;
542 /* Allocate and initialize a moxie_frame_cache object. */
544 static struct moxie_frame_cache *
545 moxie_alloc_frame_cache (void)
547 struct moxie_frame_cache *cache;
550 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
555 cache->framesize = 0;
556 for (i = 0; i < MOXIE_NUM_REGS; ++i)
557 cache->saved_regs[i] = REG_UNAVAIL;
562 /* Populate a moxie_frame_cache object for this_frame. */
564 static struct moxie_frame_cache *
565 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
567 struct moxie_frame_cache *cache;
568 CORE_ADDR current_pc;
574 cache = moxie_alloc_frame_cache ();
577 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
578 if (cache->base == 0)
581 cache->pc = get_frame_func (this_frame);
582 current_pc = get_frame_pc (this_frame);
585 struct gdbarch *gdbarch = get_frame_arch (this_frame);
586 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
589 cache->saved_sp = cache->base - cache->framesize;
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];
598 /* Implement the "unwind_pc" gdbarch method. */
601 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
603 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
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. */
610 moxie_frame_this_id (struct frame_info *this_frame,
611 void **this_prologue_cache, struct frame_id *this_id)
613 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
614 this_prologue_cache);
616 /* This marks the outermost frame. */
617 if (cache->base == 0)
620 *this_id = frame_id_build (cache->saved_sp, cache->pc);
623 /* Get the value of register regnum in the previous stack frame. */
625 static struct value *
626 moxie_frame_prev_register (struct frame_info *this_frame,
627 void **this_prologue_cache, int regnum)
629 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
630 this_prologue_cache);
632 gdb_assert (regnum >= 0);
634 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
635 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
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]);
641 return frame_unwind_got_register (this_frame, regnum, regnum);
644 static const struct frame_unwind moxie_frame_unwind = {
646 default_frame_unwind_stop_reason,
648 moxie_frame_prev_register,
650 default_frame_sniffer
653 /* Return the base address of this_frame. */
656 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
658 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
664 static const struct frame_base moxie_frame_base = {
666 moxie_frame_base_address,
667 moxie_frame_base_address,
668 moxie_frame_base_address
671 static struct frame_id
672 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
674 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
676 return frame_id_build (sp, get_frame_pc (this_frame));
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".
681 Return -1 if something wrong. */
684 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
690 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
692 if (record_debug > 1)
693 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
695 paddress (target_gdbarch (), addr));
697 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
699 /* Decode instruction. */
700 if (inst & (1 << 15))
702 if (inst & (1 << 14))
704 /* This is a Form 3 instruction. */
705 int opcode = (inst >> 10 & 0xf);
713 case 0x04: /* bltu */
714 case 0x05: /* bgtu */
717 case 0x08: /* bgeu */
718 case 0x09: /* bleu */
730 /* This is a Form 2 instruction. */
731 int opcode = (inst >> 12 & 0x3);
738 int reg = (inst >> 8) & 0xf;
739 if (record_full_arch_list_add_reg (regcache, reg))
745 /* Do nothing until GDB learns about moxie's special
757 /* This is a Form 1 instruction. */
758 int opcode = inst >> 8;
765 case 0x01: /* ldi.l (immediate) */
766 case 0x02: /* mov (register-to-register) */
768 int reg = (inst >> 4) & 0xf;
769 if (record_full_arch_list_add_reg (regcache, reg))
773 case 0x03: /* jsra */
775 regcache_raw_read (regcache,
776 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
777 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
779 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
780 || (record_full_arch_list_add_reg (regcache,
782 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
788 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
789 || (record_full_arch_list_add_reg (regcache,
794 case 0x05: /* add.l */
796 int reg = (inst >> 4) & 0xf;
797 if (record_full_arch_list_add_reg (regcache, reg))
801 case 0x06: /* push */
803 int reg = (inst >> 4) & 0xf;
804 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
805 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
807 if (record_full_arch_list_add_reg (regcache, reg)
808 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
814 int a = (inst >> 4) & 0xf;
816 if (record_full_arch_list_add_reg (regcache, a)
817 || record_full_arch_list_add_reg (regcache, b))
821 case 0x08: /* lda.l */
823 int reg = (inst >> 4) & 0xf;
824 if (record_full_arch_list_add_reg (regcache, reg))
828 case 0x09: /* sta.l */
830 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
832 if (record_full_arch_list_add_mem (tmpu32, 4))
836 case 0x0a: /* ld.l (register indirect) */
838 int reg = (inst >> 4) & 0xf;
839 if (record_full_arch_list_add_reg (regcache, reg))
843 case 0x0b: /* st.l */
845 int reg = (inst >> 4) & 0xf;
846 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
847 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
849 if (record_full_arch_list_add_mem (tmpu32, 4))
853 case 0x0c: /* ldo.l */
855 int reg = (inst >> 4) & 0xf;
856 if (record_full_arch_list_add_reg (regcache, reg))
860 case 0x0d: /* sto.l */
862 int reg = (inst >> 4) & 0xf;
863 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
865 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
866 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
869 if (record_full_arch_list_add_mem (tmpu32, 4))
875 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
895 regcache_raw_read (regcache,
896 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
897 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
899 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
900 || (record_full_arch_list_add_reg (regcache,
902 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
906 case 0x1a: /* jmpa */
911 case 0x1b: /* ldi.b (immediate) */
912 case 0x1c: /* ld.b (register indirect) */
913 case 0x1d: /* lda.b */
915 int reg = (inst >> 4) & 0xf;
916 if (record_full_arch_list_add_reg (regcache, reg))
920 case 0x1e: /* st.b */
922 int reg = (inst >> 4) & 0xf;
923 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
924 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
926 if (record_full_arch_list_add_mem (tmpu32, 1))
930 case 0x1f: /* sta.b */
932 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
933 if (record_full_arch_list_add_mem (tmpu32, 1))
937 case 0x20: /* ldi.s (immediate) */
938 case 0x21: /* ld.s (register indirect) */
939 case 0x22: /* lda.s */
941 int reg = (inst >> 4) & 0xf;
942 if (record_full_arch_list_add_reg (regcache, reg))
946 case 0x23: /* st.s */
948 int reg = (inst >> 4) & 0xf;
949 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
950 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
952 if (record_full_arch_list_add_mem (tmpu32, 2))
956 case 0x24: /* sta.s */
958 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
959 if (record_full_arch_list_add_mem (tmpu32, 2))
969 case 0x27: /* lshr */
970 case 0x28: /* ashl */
971 case 0x29: /* sub.l */
975 case 0x2d: /* ashr */
977 case 0x2f: /* mul.l */
979 int reg = (inst >> 4) & 0xf;
980 if (record_full_arch_list_add_reg (regcache, reg))
986 /* We currently implement support for libgloss'
989 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
993 case 0x1: /* SYS_exit */
998 case 0x2: /* SYS_open */
1000 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1004 case 0x4: /* SYS_read */
1006 uint32_t length, ptr;
1008 /* Read buffer pointer is in $r1. */
1009 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1010 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1013 /* String length is at 0x12($fp). */
1014 regcache_raw_read (regcache,
1015 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1016 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1018 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1020 if (record_full_arch_list_add_mem (ptr, length))
1024 case 0x5: /* SYS_write */
1026 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1035 case 0x31: /* div.l */
1036 case 0x32: /* udiv.l */
1037 case 0x33: /* mod.l */
1038 case 0x34: /* umod.l */
1040 int reg = (inst >> 4) & 0xf;
1041 if (record_full_arch_list_add_reg (regcache, reg))
1045 case 0x35: /* brk */
1048 case 0x36: /* ldo.b */
1050 int reg = (inst >> 4) & 0xf;
1051 if (record_full_arch_list_add_reg (regcache, reg))
1055 case 0x37: /* sto.b */
1057 int reg = (inst >> 4) & 0xf;
1058 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
1060 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1061 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1064 if (record_full_arch_list_add_mem (tmpu32, 1))
1068 case 0x38: /* ldo.s */
1070 int reg = (inst >> 4) & 0xf;
1071 if (record_full_arch_list_add_reg (regcache, reg))
1075 case 0x39: /* sto.s */
1077 int reg = (inst >> 4) & 0xf;
1078 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
1080 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1081 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1084 if (record_full_arch_list_add_mem (tmpu32, 2))
1094 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1096 if (record_full_arch_list_add_end ())
1101 /* Allocate and initialize the moxie gdbarch object. */
1103 static struct gdbarch *
1104 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1106 struct gdbarch *gdbarch;
1107 struct gdbarch_tdep *tdep;
1109 /* If there is already a candidate, use it. */
1110 arches = gdbarch_list_lookup_by_info (arches, &info);
1112 return arches->gdbarch;
1114 /* Allocate space for the new architecture. */
1115 tdep = XNEW (struct gdbarch_tdep);
1116 gdbarch = gdbarch_alloc (&info, tdep);
1118 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1119 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1120 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1122 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1123 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1124 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1125 set_gdbarch_register_name (gdbarch, moxie_register_name);
1126 set_gdbarch_register_type (gdbarch, moxie_register_type);
1128 set_gdbarch_return_value (gdbarch, moxie_return_value);
1130 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1131 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1132 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
1133 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1135 frame_base_set_default (gdbarch, &moxie_frame_base);
1137 /* Methods for saving / extracting a dummy frame's ID. The ID's
1138 stack address must match the SP value returned by
1139 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1140 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1142 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1144 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1146 /* Hook in ABI-specific overrides, if they have been registered. */
1147 gdbarch_init_osabi (info, gdbarch);
1149 /* Hook in the default unwinders. */
1150 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1152 /* Single stepping. */
1153 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1155 /* Support simple overlay manager. */
1156 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1158 /* Support reverse debugging. */
1159 set_gdbarch_process_record (gdbarch, moxie_process_record);
1164 /* Register this machine's init routine. */
1167 _initialize_moxie_tdep (void)
1169 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);