1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009-2022 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 /* Use an invalid address value as 'not available' marker. */
45 enum { REG_UNAVAIL
= (CORE_ADDR
) -1 };
47 struct moxie_frame_cache
53 CORE_ADDR saved_regs
[MOXIE_NUM_REGS
];
57 /* Implement the "frame_align" gdbarch method. */
60 moxie_frame_align (struct gdbarch
*gdbarch
, CORE_ADDR sp
)
62 /* Align to the size of an instruction (so that they can safely be
63 pushed onto the stack. */
67 constexpr gdb_byte moxie_break_insn
[] = { 0x35, 0x00 };
69 typedef BP_MANIPULATION (moxie_break_insn
) moxie_breakpoint
;
71 /* Moxie register names. */
73 static const char * const moxie_register_names
[] = {
74 "$fp", "$sp", "$r0", "$r1", "$r2",
75 "$r3", "$r4", "$r5", "$r6", "$r7",
76 "$r8", "$r9", "$r10", "$r11", "$r12",
77 "$r13", "$pc", "$cc" };
79 /* Implement the "register_name" gdbarch method. */
82 moxie_register_name (struct gdbarch
*gdbarch
, int reg_nr
)
86 if (reg_nr
>= MOXIE_NUM_REGS
)
88 return moxie_register_names
[reg_nr
];
91 /* Implement the "register_type" gdbarch method. */
94 moxie_register_type (struct gdbarch
*gdbarch
, int reg_nr
)
96 if (reg_nr
== MOXIE_PC_REGNUM
)
97 return builtin_type (gdbarch
)->builtin_func_ptr
;
98 else if (reg_nr
== MOXIE_SP_REGNUM
|| reg_nr
== MOXIE_FP_REGNUM
)
99 return builtin_type (gdbarch
)->builtin_data_ptr
;
101 return builtin_type (gdbarch
)->builtin_int32
;
104 /* Write into appropriate registers a function return value
105 of type TYPE, given in virtual format. */
108 moxie_store_return_value (struct type
*type
, struct regcache
*regcache
,
109 const gdb_byte
*valbuf
)
111 struct gdbarch
*gdbarch
= regcache
->arch ();
112 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
114 int len
= type
->length ();
116 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
117 regval
= extract_unsigned_integer (valbuf
, len
> 4 ? 4 : len
, byte_order
);
118 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
, regval
);
121 regval
= extract_unsigned_integer (valbuf
+ 4, len
- 4, byte_order
);
122 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
+ 1, regval
);
126 /* Decode the instructions within the given address range. Decide
127 when we must have reached the end of the function prologue. If a
128 frame_info pointer is provided, fill in its saved_regs etc.
130 Returns the address of the first instruction after the prologue. */
133 moxie_analyze_prologue (CORE_ADDR start_addr
, CORE_ADDR end_addr
,
134 struct moxie_frame_cache
*cache
,
135 struct gdbarch
*gdbarch
)
137 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
139 ULONGEST inst
, inst2
;
143 /* Record where the jsra instruction saves the PC and FP. */
144 cache
->saved_regs
[MOXIE_PC_REGNUM
] = -4;
145 cache
->saved_regs
[MOXIE_FP_REGNUM
] = 0;
146 cache
->framesize
= 0;
148 if (start_addr
>= end_addr
)
151 for (next_addr
= start_addr
; next_addr
< end_addr
; )
153 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
155 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
156 if (inst
>= 0x0612 && inst
<= 0x061f)
158 regnum
= inst
& 0x000f;
159 cache
->framesize
+= 4;
160 cache
->saved_regs
[regnum
] = cache
->framesize
;
167 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
169 /* Optional stack allocation for args and local vars <= 4
171 if (inst
== 0x01e0) /* ldi.l $r12, X */
173 offset
= read_memory_integer (next_addr
+ 2, 4, byte_order
);
174 inst2
= read_memory_unsigned_integer (next_addr
+ 6, 2, byte_order
);
176 if (inst2
== 0x291e) /* sub.l $sp, $r12 */
178 cache
->framesize
+= offset
;
181 return (next_addr
+ 8);
183 else if ((inst
& 0xff00) == 0x9100) /* dec $sp, X */
185 cache
->framesize
+= (inst
& 0x00ff);
188 while (next_addr
< end_addr
)
190 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
191 if ((inst
& 0xff00) != 0x9100) /* no more dec $sp, X */
193 cache
->framesize
+= (inst
& 0x00ff);
201 /* Find the end of function prologue. */
204 moxie_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
206 CORE_ADDR func_addr
= 0, func_end
= 0;
207 const char *func_name
;
209 /* See if we can determine the end of the prologue via the symbol table.
210 If so, then return either PC, or the PC after the prologue, whichever
212 if (find_pc_partial_function (pc
, &func_name
, &func_addr
, &func_end
))
214 CORE_ADDR post_prologue_pc
215 = skip_prologue_using_sal (gdbarch
, func_addr
);
216 if (post_prologue_pc
!= 0)
217 return std::max (pc
, post_prologue_pc
);
220 /* Can't determine prologue from the symbol table, need to examine
222 struct symtab_and_line sal
;
224 struct moxie_frame_cache cache
;
227 memset (&cache
, 0, sizeof cache
);
229 plg_end
= moxie_analyze_prologue (func_addr
,
230 func_end
, &cache
, gdbarch
);
231 /* Found a function. */
232 sym
= lookup_symbol (func_name
, NULL
, VAR_DOMAIN
, NULL
).symbol
;
233 /* Don't use line number debug info for assembly source
235 if (sym
&& sym
->language () != language_asm
)
237 sal
= find_pc_line (func_addr
, 0);
238 if (sal
.end
&& sal
.end
< func_end
)
240 /* Found a line number, use it as end of
245 /* No useable line symbol. Use result of prologue parsing
251 /* No function symbol -- just return the PC. */
252 return (CORE_ADDR
) pc
;
255 struct moxie_unwind_cache
257 /* The previous frame's inner most stack address. Used as this
258 frame ID's stack_addr. */
260 /* The frame's base, optionally used by the high-level debug info. */
263 /* How far the SP and r13 (FP) have been offset from the start of
264 the stack frame (as defined by the previous frame's stack
269 /* Table indicating the location of each and every register. */
270 trad_frame_saved_reg
*saved_regs
;
273 /* Read an unsigned integer from the inferior, and adjust
276 moxie_process_readu (CORE_ADDR addr
, gdb_byte
*buf
,
277 int length
, enum bfd_endian byte_order
)
279 if (target_read_memory (addr
, buf
, length
))
282 gdb_printf (gdb_stderr
,
283 _("Process record: error reading memory at "
284 "addr 0x%s len = %d.\n"),
285 paddress (target_gdbarch (), addr
), length
);
289 return extract_unsigned_integer (buf
, length
, byte_order
);
293 /* Helper macro to extract the signed 10-bit offset from a 16-bit
294 branch instruction. */
295 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
297 /* Insert a single step breakpoint. */
299 static std::vector
<CORE_ADDR
>
300 moxie_software_single_step (struct regcache
*regcache
)
302 struct gdbarch
*gdbarch
= regcache
->arch ();
308 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
309 std::vector
<CORE_ADDR
> next_pcs
;
311 addr
= regcache_read_pc (regcache
);
313 inst
= (uint16_t) moxie_process_readu (addr
, buf
, 2, byte_order
);
315 /* Decode instruction. */
316 if (inst
& (1 << 15))
318 if (inst
& (1 << 14))
320 /* This is a Form 3 instruction. */
321 int opcode
= (inst
>> 10 & 0xf);
329 case 0x04: /* bltu */
330 case 0x05: /* bgtu */
333 case 0x08: /* bgeu */
334 case 0x09: /* bleu */
335 /* Insert breaks on both branches, because we can't currently tell
336 which way things will go. */
337 next_pcs
.push_back (addr
+ 2);
338 next_pcs
.push_back (addr
+ 2 + INST2OFFSET(inst
));
349 /* This is a Form 2 instruction. They are all 16 bits. */
350 next_pcs
.push_back (addr
+ 2);
355 /* This is a Form 1 instruction. */
356 int opcode
= inst
>> 8;
360 /* 16-bit instructions. */
362 case 0x02: /* mov (register-to-register) */
363 case 0x05: /* add.l */
364 case 0x06: /* push */
366 case 0x0a: /* ld.l (register indirect) */
367 case 0x0b: /* st.l */
370 case 0x10: /* sex.b */
371 case 0x11: /* sex.s */
372 case 0x12: /* zex.b */
373 case 0x13: /* zex.s */
374 case 0x14: /* umul.x */
375 case 0x15: /* mul.x */
379 case 0x1c: /* ld.b (register indirect) */
380 case 0x1e: /* st.b */
381 case 0x21: /* ld.s (register indirect) */
382 case 0x23: /* st.s */
384 case 0x27: /* lshr */
385 case 0x28: /* ashl */
386 case 0x29: /* sub.l */
390 case 0x2d: /* ashr */
392 case 0x2f: /* mul.l */
393 case 0x31: /* div.l */
394 case 0x32: /* udiv.l */
395 case 0x33: /* mod.l */
396 case 0x34: /* umod.l */
397 next_pcs
.push_back (addr
+ 2);
400 /* 32-bit instructions. */
401 case 0x0c: /* ldo.l */
402 case 0x0d: /* sto.l */
403 case 0x36: /* ldo.b */
404 case 0x37: /* sto.b */
405 case 0x38: /* ldo.s */
406 case 0x39: /* sto.s */
407 next_pcs
.push_back (addr
+ 4);
410 /* 48-bit instructions. */
411 case 0x01: /* ldi.l (immediate) */
412 case 0x08: /* lda.l */
413 case 0x09: /* sta.l */
414 case 0x1b: /* ldi.b (immediate) */
415 case 0x1d: /* lda.b */
416 case 0x1f: /* sta.b */
417 case 0x20: /* ldi.s (immediate) */
418 case 0x22: /* lda.s */
419 case 0x24: /* sta.s */
420 next_pcs
.push_back (addr
+ 6);
423 /* Control flow instructions. */
424 case 0x03: /* jsra */
425 case 0x1a: /* jmpa */
426 next_pcs
.push_back (moxie_process_readu (addr
+ 2, buf
, 4,
431 regcache_cooked_read_unsigned (regcache
, MOXIE_FP_REGNUM
, &fp
);
432 next_pcs
.push_back (moxie_process_readu (fp
+ 4, buf
, 4, byte_order
));
437 regcache
->raw_read ((inst
>> 4) & 0xf, (gdb_byte
*) & tmpu32
);
438 next_pcs
.push_back (tmpu32
);
443 /* Unsupported, for now. */
451 /* Given a return value in `regbuf' with a type `valtype',
452 extract and copy its value into `valbuf'. */
455 moxie_extract_return_value (struct type
*type
, struct regcache
*regcache
,
458 struct gdbarch
*gdbarch
= regcache
->arch ();
459 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
460 int len
= type
->length ();
463 /* By using store_unsigned_integer we avoid having to do
464 anything special for small big-endian values. */
465 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
, &tmp
);
466 store_unsigned_integer (dst
, (len
> 4 ? len
- 4 : len
), byte_order
, tmp
);
468 /* Ignore return values more than 8 bytes in size because the moxie
469 returns anything more than 8 bytes in the stack. */
472 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
+ 1, &tmp
);
473 store_unsigned_integer (dst
+ len
- 4, 4, byte_order
, tmp
);
477 /* Implement the "return_value" gdbarch method. */
479 static enum return_value_convention
480 moxie_return_value (struct gdbarch
*gdbarch
, struct value
*function
,
481 struct type
*valtype
, struct regcache
*regcache
,
482 gdb_byte
*readbuf
, const gdb_byte
*writebuf
)
484 if (valtype
->length () > 8)
485 return RETURN_VALUE_STRUCT_CONVENTION
;
489 moxie_extract_return_value (valtype
, regcache
, readbuf
);
490 if (writebuf
!= NULL
)
491 moxie_store_return_value (valtype
, regcache
, writebuf
);
492 return RETURN_VALUE_REGISTER_CONVENTION
;
496 /* Allocate and initialize a moxie_frame_cache object. */
498 static struct moxie_frame_cache
*
499 moxie_alloc_frame_cache (void)
501 struct moxie_frame_cache
*cache
;
504 cache
= FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache
);
509 cache
->framesize
= 0;
510 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
511 cache
->saved_regs
[i
] = REG_UNAVAIL
;
516 /* Populate a moxie_frame_cache object for this_frame. */
518 static struct moxie_frame_cache
*
519 moxie_frame_cache (struct frame_info
*this_frame
, void **this_cache
)
521 struct moxie_frame_cache
*cache
;
522 CORE_ADDR current_pc
;
526 return (struct moxie_frame_cache
*) *this_cache
;
528 cache
= moxie_alloc_frame_cache ();
531 cache
->base
= get_frame_register_unsigned (this_frame
, MOXIE_FP_REGNUM
);
532 if (cache
->base
== 0)
535 cache
->pc
= get_frame_func (this_frame
);
536 current_pc
= get_frame_pc (this_frame
);
539 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
540 moxie_analyze_prologue (cache
->pc
, current_pc
, cache
, gdbarch
);
543 cache
->saved_sp
= cache
->base
- cache
->framesize
;
545 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
546 if (cache
->saved_regs
[i
] != REG_UNAVAIL
)
547 cache
->saved_regs
[i
] = cache
->base
- cache
->saved_regs
[i
];
552 /* Given a GDB frame, determine the address of the calling function's
553 frame. This will be used to create a new GDB frame struct. */
556 moxie_frame_this_id (struct frame_info
*this_frame
,
557 void **this_prologue_cache
, struct frame_id
*this_id
)
559 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
560 this_prologue_cache
);
562 /* This marks the outermost frame. */
563 if (cache
->base
== 0)
566 *this_id
= frame_id_build (cache
->saved_sp
, cache
->pc
);
569 /* Get the value of register regnum in the previous stack frame. */
571 static struct value
*
572 moxie_frame_prev_register (struct frame_info
*this_frame
,
573 void **this_prologue_cache
, int regnum
)
575 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
576 this_prologue_cache
);
578 gdb_assert (regnum
>= 0);
580 if (regnum
== MOXIE_SP_REGNUM
&& cache
->saved_sp
)
581 return frame_unwind_got_constant (this_frame
, regnum
, cache
->saved_sp
);
583 if (regnum
< MOXIE_NUM_REGS
&& cache
->saved_regs
[regnum
] != REG_UNAVAIL
)
584 return frame_unwind_got_memory (this_frame
, regnum
,
585 cache
->saved_regs
[regnum
]);
587 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
590 static const struct frame_unwind moxie_frame_unwind
= {
593 default_frame_unwind_stop_reason
,
595 moxie_frame_prev_register
,
597 default_frame_sniffer
600 /* Return the base address of this_frame. */
603 moxie_frame_base_address (struct frame_info
*this_frame
, void **this_cache
)
605 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
611 static const struct frame_base moxie_frame_base
= {
613 moxie_frame_base_address
,
614 moxie_frame_base_address
,
615 moxie_frame_base_address
618 /* Parse the current instruction and record the values of the registers and
619 memory that will be changed in current instruction to "record_arch_list".
620 Return -1 if something wrong. */
623 moxie_process_record (struct gdbarch
*gdbarch
, struct regcache
*regcache
,
629 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
631 if (record_debug
> 1)
632 gdb_printf (gdb_stdlog
, "Process record: moxie_process_record "
634 paddress (target_gdbarch (), addr
));
636 inst
= (uint16_t) moxie_process_readu (addr
, buf
, 2, byte_order
);
638 /* Decode instruction. */
639 if (inst
& (1 << 15))
641 if (inst
& (1 << 14))
643 /* This is a Form 3 instruction. */
644 int opcode
= (inst
>> 10 & 0xf);
652 case 0x04: /* bltu */
653 case 0x05: /* bgtu */
656 case 0x08: /* bgeu */
657 case 0x09: /* bleu */
669 /* This is a Form 2 instruction. */
670 int opcode
= (inst
>> 12 & 0x3);
677 int reg
= (inst
>> 8) & 0xf;
678 if (record_full_arch_list_add_reg (regcache
, reg
))
684 /* Do nothing until GDB learns about moxie's special
696 /* This is a Form 1 instruction. */
697 int opcode
= inst
>> 8;
704 case 0x01: /* ldi.l (immediate) */
705 case 0x02: /* mov (register-to-register) */
707 int reg
= (inst
>> 4) & 0xf;
708 if (record_full_arch_list_add_reg (regcache
, reg
))
712 case 0x03: /* jsra */
715 MOXIE_SP_REGNUM
, (gdb_byte
*) & tmpu32
);
716 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
718 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
719 || (record_full_arch_list_add_reg (regcache
,
721 || record_full_arch_list_add_mem (tmpu32
- 12, 12))
727 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
728 || (record_full_arch_list_add_reg (regcache
,
733 case 0x05: /* add.l */
735 int reg
= (inst
>> 4) & 0xf;
736 if (record_full_arch_list_add_reg (regcache
, reg
))
740 case 0x06: /* push */
742 int reg
= (inst
>> 4) & 0xf;
743 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
744 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
746 if (record_full_arch_list_add_reg (regcache
, reg
)
747 || record_full_arch_list_add_mem (tmpu32
- 4, 4))
753 int a
= (inst
>> 4) & 0xf;
755 if (record_full_arch_list_add_reg (regcache
, a
)
756 || record_full_arch_list_add_reg (regcache
, b
))
760 case 0x08: /* lda.l */
762 int reg
= (inst
>> 4) & 0xf;
763 if (record_full_arch_list_add_reg (regcache
, reg
))
767 case 0x09: /* sta.l */
769 tmpu32
= (uint32_t) moxie_process_readu (addr
+2, buf
,
771 if (record_full_arch_list_add_mem (tmpu32
, 4))
775 case 0x0a: /* ld.l (register indirect) */
777 int reg
= (inst
>> 4) & 0xf;
778 if (record_full_arch_list_add_reg (regcache
, reg
))
782 case 0x0b: /* st.l */
784 int reg
= (inst
>> 4) & 0xf;
785 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
786 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
788 if (record_full_arch_list_add_mem (tmpu32
, 4))
792 case 0x0c: /* ldo.l */
794 int reg
= (inst
>> 4) & 0xf;
795 if (record_full_arch_list_add_reg (regcache
, reg
))
799 case 0x0d: /* sto.l */
801 int reg
= (inst
>> 4) & 0xf;
802 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
803 byte_order
)) << 16 ) >> 16;
804 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
805 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
808 if (record_full_arch_list_add_mem (tmpu32
, 4))
814 if (record_full_arch_list_add_reg (regcache
, MOXIE_CC_REGNUM
))
823 case 0x10: /* sex.b */
824 case 0x11: /* sex.s */
825 case 0x12: /* zex.b */
826 case 0x13: /* zex.s */
827 case 0x14: /* umul.x */
828 case 0x15: /* mul.x */
830 int reg
= (inst
>> 4) & 0xf;
831 if (record_full_arch_list_add_reg (regcache
, reg
))
845 MOXIE_SP_REGNUM
, (gdb_byte
*) & tmpu32
);
846 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
848 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
849 || (record_full_arch_list_add_reg (regcache
,
851 || record_full_arch_list_add_mem (tmpu32
- 12, 12))
855 case 0x1a: /* jmpa */
860 case 0x1b: /* ldi.b (immediate) */
861 case 0x1c: /* ld.b (register indirect) */
862 case 0x1d: /* lda.b */
864 int reg
= (inst
>> 4) & 0xf;
865 if (record_full_arch_list_add_reg (regcache
, reg
))
869 case 0x1e: /* st.b */
871 int reg
= (inst
>> 4) & 0xf;
872 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
873 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
875 if (record_full_arch_list_add_mem (tmpu32
, 1))
879 case 0x1f: /* sta.b */
881 tmpu32
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
882 if (record_full_arch_list_add_mem (tmpu32
, 1))
886 case 0x20: /* ldi.s (immediate) */
887 case 0x21: /* ld.s (register indirect) */
888 case 0x22: /* lda.s */
890 int reg
= (inst
>> 4) & 0xf;
891 if (record_full_arch_list_add_reg (regcache
, reg
))
895 case 0x23: /* st.s */
897 int reg
= (inst
>> 4) & 0xf;
898 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
899 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
901 if (record_full_arch_list_add_mem (tmpu32
, 2))
905 case 0x24: /* sta.s */
907 tmpu32
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
908 if (record_full_arch_list_add_mem (tmpu32
, 2))
918 case 0x27: /* lshr */
919 case 0x28: /* ashl */
924 case 0x2d: /* ashr */
928 int reg
= (inst
>> 4) & 0xf;
929 if (record_full_arch_list_add_reg (regcache
, reg
))
935 /* We currently implement support for libgloss'
938 int inum
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
942 case 0x1: /* SYS_exit */
947 case 0x2: /* SYS_open */
949 if (record_full_arch_list_add_reg (regcache
, RET1_REGNUM
))
953 case 0x4: /* SYS_read */
955 uint32_t length
, ptr
;
957 /* Read buffer pointer is in $r1. */
958 regcache
->raw_read (3, (gdb_byte
*) & ptr
);
959 ptr
= extract_unsigned_integer ((gdb_byte
*) & ptr
,
962 /* String length is at 0x12($fp). */
964 MOXIE_FP_REGNUM
, (gdb_byte
*) & tmpu32
);
965 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
967 length
= moxie_process_readu (tmpu32
+20, buf
, 4, byte_order
);
969 if (record_full_arch_list_add_mem (ptr
, length
))
973 case 0x5: /* SYS_write */
975 if (record_full_arch_list_add_reg (regcache
, RET1_REGNUM
))
984 case 0x31: /* div.l */
985 case 0x32: /* udiv.l */
986 case 0x33: /* mod.l */
987 case 0x34: /* umod.l */
989 int reg
= (inst
>> 4) & 0xf;
990 if (record_full_arch_list_add_reg (regcache
, reg
))
997 case 0x36: /* ldo.b */
999 int reg
= (inst
>> 4) & 0xf;
1000 if (record_full_arch_list_add_reg (regcache
, reg
))
1004 case 0x37: /* sto.b */
1006 int reg
= (inst
>> 4) & 0xf;
1007 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
1008 byte_order
)) << 16 ) >> 16;
1009 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
1010 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
1013 if (record_full_arch_list_add_mem (tmpu32
, 1))
1017 case 0x38: /* ldo.s */
1019 int reg
= (inst
>> 4) & 0xf;
1020 if (record_full_arch_list_add_reg (regcache
, reg
))
1024 case 0x39: /* sto.s */
1026 int reg
= (inst
>> 4) & 0xf;
1027 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
1028 byte_order
)) << 16 ) >> 16;
1029 regcache
->raw_read (reg
, (gdb_byte
*) & tmpu32
);
1030 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
1033 if (record_full_arch_list_add_mem (tmpu32
, 2))
1043 if (record_full_arch_list_add_reg (regcache
, MOXIE_PC_REGNUM
))
1045 if (record_full_arch_list_add_end ())
1050 /* Allocate and initialize the moxie gdbarch object. */
1052 static struct gdbarch
*
1053 moxie_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
1055 struct gdbarch
*gdbarch
;
1057 /* If there is already a candidate, use it. */
1058 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
1060 return arches
->gdbarch
;
1062 /* Allocate space for the new architecture. */
1063 moxie_gdbarch_tdep
*tdep
= new moxie_gdbarch_tdep
;
1064 gdbarch
= gdbarch_alloc (&info
, tdep
);
1066 set_gdbarch_wchar_bit (gdbarch
, 32);
1067 set_gdbarch_wchar_signed (gdbarch
, 0);
1069 set_gdbarch_num_regs (gdbarch
, MOXIE_NUM_REGS
);
1070 set_gdbarch_sp_regnum (gdbarch
, MOXIE_SP_REGNUM
);
1071 set_gdbarch_pc_regnum (gdbarch
, MOXIE_PC_REGNUM
);
1072 set_gdbarch_register_name (gdbarch
, moxie_register_name
);
1073 set_gdbarch_register_type (gdbarch
, moxie_register_type
);
1075 set_gdbarch_return_value (gdbarch
, moxie_return_value
);
1077 set_gdbarch_skip_prologue (gdbarch
, moxie_skip_prologue
);
1078 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
1079 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
1080 moxie_breakpoint::kind_from_pc
);
1081 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
1082 moxie_breakpoint::bp_from_kind
);
1083 set_gdbarch_frame_align (gdbarch
, moxie_frame_align
);
1085 frame_base_set_default (gdbarch
, &moxie_frame_base
);
1087 /* Hook in ABI-specific overrides, if they have been registered. */
1088 gdbarch_init_osabi (info
, gdbarch
);
1090 /* Hook in the default unwinders. */
1091 frame_unwind_append_unwinder (gdbarch
, &moxie_frame_unwind
);
1093 /* Single stepping. */
1094 set_gdbarch_software_single_step (gdbarch
, moxie_software_single_step
);
1096 /* Support simple overlay manager. */
1097 set_gdbarch_overlay_update (gdbarch
, simple_overlay_update
);
1099 /* Support reverse debugging. */
1100 set_gdbarch_process_record (gdbarch
, moxie_process_record
);
1105 /* Register this machine's init routine. */
1107 void _initialize_moxie_tdep ();
1109 _initialize_moxie_tdep ()
1111 gdbarch_register (bfd_arch_moxie
, moxie_gdbarch_init
);