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 "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 /* Implement the "breakpoint_from_pc" gdbarch method. */
73 static const unsigned char *
74 moxie_breakpoint_from_pc (struct gdbarch *gdbarch,
75 CORE_ADDR *pcptr, int *lenptr)
77 static unsigned char breakpoint[] = { 0x35, 0x00 };
79 *lenptr = sizeof (breakpoint);
83 /* Moxie register names. */
85 char *moxie_register_names[] = {
86 "$fp", "$sp", "$r0", "$r1", "$r2",
87 "$r3", "$r4", "$r5", "$r6", "$r7",
88 "$r8", "$r9", "$r10", "$r11", "$r12",
89 "$r13", "$pc", "$cc" };
91 /* Implement the "register_name" gdbarch method. */
94 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
98 if (reg_nr >= MOXIE_NUM_REGS)
100 return moxie_register_names[reg_nr];
103 /* Implement the "register_type" gdbarch method. */
106 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
108 if (reg_nr == MOXIE_PC_REGNUM)
109 return builtin_type (gdbarch)->builtin_func_ptr;
110 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
111 return builtin_type (gdbarch)->builtin_data_ptr;
113 return builtin_type (gdbarch)->builtin_int32;
116 /* Write into appropriate registers a function return value
117 of type TYPE, given in virtual format. */
120 moxie_store_return_value (struct type *type, struct regcache *regcache,
123 struct gdbarch *gdbarch = get_regcache_arch (regcache);
124 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
126 int len = TYPE_LENGTH (type);
128 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
129 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
130 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
133 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4,
134 len - 4, byte_order);
135 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
139 /* Decode the instructions within the given address range. Decide
140 when we must have reached the end of the function prologue. If a
141 frame_info pointer is provided, fill in its saved_regs etc.
143 Returns the address of the first instruction after the prologue. */
146 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
147 struct moxie_frame_cache *cache,
148 struct gdbarch *gdbarch)
150 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
152 ULONGEST inst, inst2;
156 /* Record where the jsra instruction saves the PC and FP. */
157 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
158 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
159 cache->framesize = 0;
161 if (start_addr >= end_addr)
164 for (next_addr = start_addr; next_addr < end_addr; )
166 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
168 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
169 if (inst >= 0x0612 && inst <= 0x061f)
171 regnum = inst & 0x000f;
172 cache->framesize += 4;
173 cache->saved_regs[regnum] = cache->framesize;
180 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
182 /* Optional stack allocation for args and local vars <= 4
184 if (inst == 0x01e0) /* ldi.l $r12, X */
186 offset = read_memory_integer (next_addr + 2, 4, byte_order);
187 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
189 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
191 cache->framesize += offset;
194 return (next_addr + 8);
196 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
198 cache->framesize += (inst & 0x00ff);
201 while (next_addr < end_addr)
203 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
204 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
206 cache->framesize += (inst & 0x00ff);
214 /* Find the end of function prologue. */
217 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
219 CORE_ADDR func_addr = 0, func_end = 0;
220 const char *func_name;
222 /* See if we can determine the end of the prologue via the symbol table.
223 If so, then return either PC, or the PC after the prologue, whichever
225 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
227 CORE_ADDR post_prologue_pc
228 = skip_prologue_using_sal (gdbarch, func_addr);
229 if (post_prologue_pc != 0)
230 return max (pc, post_prologue_pc);
233 /* Can't determine prologue from the symbol table, need to examine
235 struct symtab_and_line sal;
237 struct moxie_frame_cache cache;
240 memset (&cache, 0, sizeof cache);
242 plg_end = moxie_analyze_prologue (func_addr,
243 func_end, &cache, gdbarch);
244 /* Found a function. */
245 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
246 /* Don't use line number debug info for assembly source
248 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
250 sal = find_pc_line (func_addr, 0);
251 if (sal.end && sal.end < func_end)
253 /* Found a line number, use it as end of
258 /* No useable line symbol. Use result of prologue parsing
264 /* No function symbol -- just return the PC. */
265 return (CORE_ADDR) pc;
268 struct moxie_unwind_cache
270 /* The previous frame's inner most stack address. Used as this
271 frame ID's stack_addr. */
273 /* The frame's base, optionally used by the high-level debug info. */
276 /* How far the SP and r13 (FP) have been offset from the start of
277 the stack frame (as defined by the previous frame's stack
282 /* Table indicating the location of each and every register. */
283 struct trad_frame_saved_reg *saved_regs;
286 /* Read an unsigned integer from the inferior, and adjust
289 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
290 int length, enum bfd_endian byte_order)
292 if (target_read_memory (addr, buf, length))
295 printf_unfiltered (_("Process record: error reading memory at "
296 "addr 0x%s len = %d.\n"),
297 paddress (target_gdbarch (), addr), length);
301 return extract_unsigned_integer (buf, length, byte_order);
305 /* Helper macro to extract the signed 10-bit offset from a 16-bit
306 branch instruction. */
307 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
309 /* Insert a single step breakpoint. */
312 moxie_software_single_step (struct frame_info *frame)
314 struct gdbarch *gdbarch = get_frame_arch (frame);
315 struct address_space *aspace = get_frame_address_space (frame);
321 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
322 struct regcache *regcache = get_current_regcache ();
324 addr = get_frame_pc (frame);
326 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
328 /* Decode instruction. */
329 if (inst & (1 << 15))
331 if (inst & (1 << 14))
333 /* This is a Form 3 instruction. */
334 int opcode = (inst >> 10 & 0xf);
342 case 0x04: /* bltu */
343 case 0x05: /* bgtu */
346 case 0x08: /* bgeu */
347 case 0x09: /* bleu */
348 /* Insert breaks on both branches, because we can't currently tell
349 which way things will go. */
350 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
351 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
362 /* This is a Form 2 instruction. They are all 16 bits. */
363 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
368 /* This is a Form 1 instruction. */
369 int opcode = inst >> 8;
373 /* 16-bit instructions. */
375 case 0x02: /* mov (register-to-register) */
376 case 0x05: /* add.l */
377 case 0x06: /* push */
379 case 0x0a: /* ld.l (register indirect) */
380 case 0x0b: /* st.l */
392 case 0x1c: /* ld.b (register indirect) */
393 case 0x1e: /* st.b */
394 case 0x21: /* ld.s (register indirect) */
395 case 0x23: /* st.s */
397 case 0x27: /* lshr */
398 case 0x28: /* ashl */
399 case 0x29: /* sub.l */
403 case 0x2d: /* ashr */
405 case 0x2f: /* mul.l */
406 case 0x31: /* div.l */
407 case 0x32: /* udiv.l */
408 case 0x33: /* mod.l */
409 case 0x34: /* umod.l */
410 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
413 /* 48-bit instructions. */
414 case 0x01: /* ldi.l (immediate) */
415 case 0x08: /* lda.l */
416 case 0x09: /* sta.l */
417 case 0x0c: /* ldo.l */
418 case 0x0d: /* sto.l */
419 case 0x1b: /* ldi.b (immediate) */
420 case 0x1d: /* lda.b */
421 case 0x1f: /* sta.b */
422 case 0x20: /* ldi.s (immediate) */
423 case 0x22: /* lda.s */
424 case 0x24: /* sta.s */
425 case 0x36: /* ldo.b */
426 case 0x37: /* sto.b */
427 case 0x38: /* ldo.s */
428 case 0x39: /* sto.s */
429 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
432 /* Control flow instructions. */
433 case 0x03: /* jsra */
434 case 0x1a: /* jmpa */
435 insert_single_step_breakpoint (gdbarch, aspace,
436 moxie_process_readu (addr + 2,
442 regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
443 insert_single_step_breakpoint (gdbarch, aspace,
444 moxie_process_readu (fp + 4,
451 regcache_raw_read (regcache,
452 (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
453 insert_single_step_breakpoint (gdbarch, aspace,
459 /* Unsupported, for now. */
467 /* Implement the "read_pc" gdbarch method. */
470 moxie_read_pc (struct regcache *regcache)
474 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
478 /* Implement the "write_pc" gdbarch method. */
481 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
483 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
486 /* Implement the "unwind_sp" gdbarch method. */
489 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
491 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
494 /* Given a return value in `regbuf' with a type `valtype',
495 extract and copy its value into `valbuf'. */
498 moxie_extract_return_value (struct type *type, struct regcache *regcache,
501 struct gdbarch *gdbarch = get_regcache_arch (regcache);
502 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
503 bfd_byte *valbuf = dst;
504 int len = TYPE_LENGTH (type);
507 /* By using store_unsigned_integer we avoid having to do
508 anything special for small big-endian values. */
509 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
510 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp);
512 /* Ignore return values more than 8 bytes in size because the moxie
513 returns anything more than 8 bytes in the stack. */
516 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
517 store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp);
521 /* Implement the "return_value" gdbarch method. */
523 static enum return_value_convention
524 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
525 struct type *valtype, struct regcache *regcache,
526 gdb_byte *readbuf, const gdb_byte *writebuf)
528 if (TYPE_LENGTH (valtype) > 8)
529 return RETURN_VALUE_STRUCT_CONVENTION;
533 moxie_extract_return_value (valtype, regcache, readbuf);
534 if (writebuf != NULL)
535 moxie_store_return_value (valtype, regcache, writebuf);
536 return RETURN_VALUE_REGISTER_CONVENTION;
540 /* Allocate and initialize a moxie_frame_cache object. */
542 static struct moxie_frame_cache *
543 moxie_alloc_frame_cache (void)
545 struct moxie_frame_cache *cache;
548 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
553 cache->framesize = 0;
554 for (i = 0; i < MOXIE_NUM_REGS; ++i)
555 cache->saved_regs[i] = REG_UNAVAIL;
560 /* Populate a moxie_frame_cache object for this_frame. */
562 static struct moxie_frame_cache *
563 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
565 struct moxie_frame_cache *cache;
566 CORE_ADDR current_pc;
572 cache = moxie_alloc_frame_cache ();
575 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
576 if (cache->base == 0)
579 cache->pc = get_frame_func (this_frame);
580 current_pc = get_frame_pc (this_frame);
583 struct gdbarch *gdbarch = get_frame_arch (this_frame);
584 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
587 cache->saved_sp = cache->base - cache->framesize;
589 for (i = 0; i < MOXIE_NUM_REGS; ++i)
590 if (cache->saved_regs[i] != REG_UNAVAIL)
591 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
596 /* Implement the "unwind_pc" gdbarch method. */
599 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
601 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
604 /* Given a GDB frame, determine the address of the calling function's
605 frame. This will be used to create a new GDB frame struct. */
608 moxie_frame_this_id (struct frame_info *this_frame,
609 void **this_prologue_cache, struct frame_id *this_id)
611 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
612 this_prologue_cache);
614 /* This marks the outermost frame. */
615 if (cache->base == 0)
618 *this_id = frame_id_build (cache->saved_sp, cache->pc);
621 /* Get the value of register regnum in the previous stack frame. */
623 static struct value *
624 moxie_frame_prev_register (struct frame_info *this_frame,
625 void **this_prologue_cache, int regnum)
627 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
628 this_prologue_cache);
630 gdb_assert (regnum >= 0);
632 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
633 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
635 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
636 return frame_unwind_got_memory (this_frame, regnum,
637 cache->saved_regs[regnum]);
639 return frame_unwind_got_register (this_frame, regnum, regnum);
642 static const struct frame_unwind moxie_frame_unwind = {
644 default_frame_unwind_stop_reason,
646 moxie_frame_prev_register,
648 default_frame_sniffer
651 /* Return the base address of this_frame. */
654 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
656 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
662 static const struct frame_base moxie_frame_base = {
664 moxie_frame_base_address,
665 moxie_frame_base_address,
666 moxie_frame_base_address
669 static struct frame_id
670 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
672 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
674 return frame_id_build (sp, get_frame_pc (this_frame));
677 /* Parse the current instruction and record the values of the registers and
678 memory that will be changed in current instruction to "record_arch_list".
679 Return -1 if something wrong. */
682 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
688 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
690 if (record_debug > 1)
691 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
693 paddress (target_gdbarch (), addr));
695 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
697 /* Decode instruction. */
698 if (inst & (1 << 15))
700 if (inst & (1 << 14))
702 /* This is a Form 3 instruction. */
703 int opcode = (inst >> 10 & 0xf);
711 case 0x04: /* bltu */
712 case 0x05: /* bgtu */
715 case 0x08: /* bgeu */
716 case 0x09: /* bleu */
728 /* This is a Form 2 instruction. */
729 int opcode = (inst >> 12 & 0x3);
736 int reg = (inst >> 8) & 0xf;
737 if (record_full_arch_list_add_reg (regcache, reg))
743 /* Do nothing until GDB learns about moxie's special
755 /* This is a Form 1 instruction. */
756 int opcode = inst >> 8;
763 case 0x01: /* ldi.l (immediate) */
764 case 0x02: /* mov (register-to-register) */
766 int reg = (inst >> 4) & 0xf;
767 if (record_full_arch_list_add_reg (regcache, reg))
771 case 0x03: /* jsra */
773 regcache_raw_read (regcache,
774 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
775 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
777 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
778 || (record_full_arch_list_add_reg (regcache,
780 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
786 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
787 || (record_full_arch_list_add_reg (regcache,
792 case 0x05: /* add.l */
794 int reg = (inst >> 4) & 0xf;
795 if (record_full_arch_list_add_reg (regcache, reg))
799 case 0x06: /* push */
801 int reg = (inst >> 4) & 0xf;
802 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
803 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
805 if (record_full_arch_list_add_reg (regcache, reg)
806 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
812 int a = (inst >> 4) & 0xf;
814 if (record_full_arch_list_add_reg (regcache, a)
815 || record_full_arch_list_add_reg (regcache, b))
819 case 0x08: /* lda.l */
821 int reg = (inst >> 4) & 0xf;
822 if (record_full_arch_list_add_reg (regcache, reg))
826 case 0x09: /* sta.l */
828 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
830 if (record_full_arch_list_add_mem (tmpu32, 4))
834 case 0x0a: /* ld.l (register indirect) */
836 int reg = (inst >> 4) & 0xf;
837 if (record_full_arch_list_add_reg (regcache, reg))
841 case 0x0b: /* st.l */
843 int reg = (inst >> 4) & 0xf;
844 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
845 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
847 if (record_full_arch_list_add_mem (tmpu32, 4))
851 case 0x0c: /* ldo.l */
853 int reg = (inst >> 4) & 0xf;
854 if (record_full_arch_list_add_reg (regcache, reg))
858 case 0x0d: /* sto.l */
860 int reg = (inst >> 4) & 0xf;
861 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
863 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
864 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
867 if (record_full_arch_list_add_mem (tmpu32, 4))
873 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
893 regcache_raw_read (regcache,
894 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
895 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
897 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
898 || (record_full_arch_list_add_reg (regcache,
900 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
904 case 0x1a: /* jmpa */
909 case 0x1b: /* ldi.b (immediate) */
910 case 0x1c: /* ld.b (register indirect) */
911 case 0x1d: /* lda.b */
913 int reg = (inst >> 4) & 0xf;
914 if (record_full_arch_list_add_reg (regcache, reg))
918 case 0x1e: /* st.b */
920 int reg = (inst >> 4) & 0xf;
921 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
922 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
924 if (record_full_arch_list_add_mem (tmpu32, 1))
928 case 0x1f: /* sta.b */
930 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
931 if (record_full_arch_list_add_mem (tmpu32, 1))
935 case 0x20: /* ldi.s (immediate) */
936 case 0x21: /* ld.s (register indirect) */
937 case 0x22: /* lda.s */
939 int reg = (inst >> 4) & 0xf;
940 if (record_full_arch_list_add_reg (regcache, reg))
944 case 0x23: /* st.s */
946 int reg = (inst >> 4) & 0xf;
947 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
948 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
950 if (record_full_arch_list_add_mem (tmpu32, 2))
954 case 0x24: /* sta.s */
956 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
957 if (record_full_arch_list_add_mem (tmpu32, 2))
967 case 0x27: /* lshr */
968 case 0x28: /* ashl */
969 case 0x29: /* sub.l */
973 case 0x2d: /* ashr */
975 case 0x2f: /* mul.l */
977 int reg = (inst >> 4) & 0xf;
978 if (record_full_arch_list_add_reg (regcache, reg))
984 /* We currently implement support for libgloss'
987 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
991 case 0x1: /* SYS_exit */
996 case 0x2: /* SYS_open */
998 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1002 case 0x4: /* SYS_read */
1004 uint32_t length, ptr;
1006 /* Read buffer pointer is in $r1. */
1007 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1008 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1011 /* String length is at 0x12($fp). */
1012 regcache_raw_read (regcache,
1013 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1014 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1016 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1018 if (record_full_arch_list_add_mem (ptr, length))
1022 case 0x5: /* SYS_write */
1024 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1033 case 0x31: /* div.l */
1034 case 0x32: /* udiv.l */
1035 case 0x33: /* mod.l */
1036 case 0x34: /* umod.l */
1038 int reg = (inst >> 4) & 0xf;
1039 if (record_full_arch_list_add_reg (regcache, reg))
1043 case 0x35: /* brk */
1046 case 0x36: /* ldo.b */
1048 int reg = (inst >> 4) & 0xf;
1049 if (record_full_arch_list_add_reg (regcache, reg))
1053 case 0x37: /* sto.b */
1055 int reg = (inst >> 4) & 0xf;
1056 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
1058 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1059 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1062 if (record_full_arch_list_add_mem (tmpu32, 1))
1066 case 0x38: /* ldo.s */
1068 int reg = (inst >> 4) & 0xf;
1069 if (record_full_arch_list_add_reg (regcache, reg))
1073 case 0x39: /* sto.s */
1075 int reg = (inst >> 4) & 0xf;
1076 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4,
1078 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1079 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1082 if (record_full_arch_list_add_mem (tmpu32, 2))
1092 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1094 if (record_full_arch_list_add_end ())
1099 /* Allocate and initialize the moxie gdbarch object. */
1101 static struct gdbarch *
1102 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1104 struct gdbarch *gdbarch;
1105 struct gdbarch_tdep *tdep;
1107 /* If there is already a candidate, use it. */
1108 arches = gdbarch_list_lookup_by_info (arches, &info);
1110 return arches->gdbarch;
1112 /* Allocate space for the new architecture. */
1113 tdep = XNEW (struct gdbarch_tdep);
1114 gdbarch = gdbarch_alloc (&info, tdep);
1116 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1117 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1118 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1120 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1121 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1122 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1123 set_gdbarch_register_name (gdbarch, moxie_register_name);
1124 set_gdbarch_register_type (gdbarch, moxie_register_type);
1126 set_gdbarch_return_value (gdbarch, moxie_return_value);
1128 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1129 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1130 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
1131 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1133 frame_base_set_default (gdbarch, &moxie_frame_base);
1135 /* Methods for saving / extracting a dummy frame's ID. The ID's
1136 stack address must match the SP value returned by
1137 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1138 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1140 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1142 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1144 /* Hook in ABI-specific overrides, if they have been registered. */
1145 gdbarch_init_osabi (info, gdbarch);
1147 /* Hook in the default unwinders. */
1148 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1150 /* Single stepping. */
1151 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1153 /* Support simple overlay manager. */
1154 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1156 /* Support reverse debugging. */
1157 set_gdbarch_process_record (gdbarch, moxie_process_record);
1162 /* Register this machine's init routine. */
1165 _initialize_moxie_tdep (void)
1167 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);