1 /* Target-dependent code for Moxie.
3 Copyright (C) 2009-2015 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "frame-unwind.h"
23 #include "frame-base.h"
34 #include "arch-utils.h"
36 #include "trad-frame.h"
39 #include "record-full.h"
41 #include "moxie-tdep.h"
43 /* Local functions. */
45 extern void _initialize_moxie_tdep (void);
47 /* Use an invalid address value as 'not available' marker. */
48 enum { REG_UNAVAIL
= (CORE_ADDR
) -1 };
50 struct moxie_frame_cache
56 CORE_ADDR saved_regs
[MOXIE_NUM_REGS
];
60 /* Implement the "frame_align" gdbarch method. */
63 moxie_frame_align (struct gdbarch
*gdbarch
, CORE_ADDR sp
)
65 /* Align to the size of an instruction (so that they can safely be
66 pushed onto the stack. */
70 /* Implement the "breakpoint_from_pc" gdbarch method. */
72 static const unsigned char *
73 moxie_breakpoint_from_pc (struct gdbarch
*gdbarch
,
74 CORE_ADDR
*pcptr
, int *lenptr
)
76 static unsigned char breakpoint
[] = { 0x35, 0x00 };
78 *lenptr
= sizeof (breakpoint
);
82 /* Moxie register names. */
84 char *moxie_register_names
[] = {
85 "$fp", "$sp", "$r0", "$r1", "$r2",
86 "$r3", "$r4", "$r5", "$r6", "$r7",
87 "$r8", "$r9", "$r10", "$r11", "$r12",
88 "$r13", "$pc", "$cc" };
90 /* Implement the "register_name" gdbarch method. */
93 moxie_register_name (struct gdbarch
*gdbarch
, int reg_nr
)
97 if (reg_nr
>= MOXIE_NUM_REGS
)
99 return moxie_register_names
[reg_nr
];
102 /* Implement the "register_type" gdbarch method. */
105 moxie_register_type (struct gdbarch
*gdbarch
, int reg_nr
)
107 if (reg_nr
== MOXIE_PC_REGNUM
)
108 return builtin_type (gdbarch
)->builtin_func_ptr
;
109 else if (reg_nr
== MOXIE_SP_REGNUM
|| reg_nr
== MOXIE_FP_REGNUM
)
110 return builtin_type (gdbarch
)->builtin_data_ptr
;
112 return builtin_type (gdbarch
)->builtin_int32
;
115 /* Write into appropriate registers a function return value
116 of type TYPE, given in virtual format. */
119 moxie_store_return_value (struct type
*type
, struct regcache
*regcache
,
122 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
123 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
125 int len
= TYPE_LENGTH (type
);
127 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
128 regval
= extract_unsigned_integer (valbuf
, len
> 4 ? 4 : len
, byte_order
);
129 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
, regval
);
132 regval
= extract_unsigned_integer ((gdb_byte
*) valbuf
+ 4,
133 len
- 4, byte_order
);
134 regcache_cooked_write_unsigned (regcache
, RET1_REGNUM
+ 1, regval
);
138 /* Decode the instructions within the given address range. Decide
139 when we must have reached the end of the function prologue. If a
140 frame_info pointer is provided, fill in its saved_regs etc.
142 Returns the address of the first instruction after the prologue. */
145 moxie_analyze_prologue (CORE_ADDR start_addr
, CORE_ADDR end_addr
,
146 struct moxie_frame_cache
*cache
,
147 struct gdbarch
*gdbarch
)
149 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
151 ULONGEST inst
, inst2
;
155 /* Record where the jsra instruction saves the PC and FP. */
156 cache
->saved_regs
[MOXIE_PC_REGNUM
] = -4;
157 cache
->saved_regs
[MOXIE_FP_REGNUM
] = 0;
158 cache
->framesize
= 0;
160 if (start_addr
>= end_addr
)
163 for (next_addr
= start_addr
; next_addr
< end_addr
; )
165 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
167 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
168 if (inst
>= 0x0612 && inst
<= 0x061f)
170 regnum
= inst
& 0x000f;
171 cache
->framesize
+= 4;
172 cache
->saved_regs
[regnum
] = cache
->framesize
;
179 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
181 /* Optional stack allocation for args and local vars <= 4
183 if (inst
== 0x01e0) /* ldi.l $r12, X */
185 offset
= read_memory_integer (next_addr
+ 2, 4, byte_order
);
186 inst2
= read_memory_unsigned_integer (next_addr
+ 6, 2, byte_order
);
188 if (inst2
== 0x291e) /* sub.l $sp, $r12 */
190 cache
->framesize
+= offset
;
193 return (next_addr
+ 8);
195 else if ((inst
& 0xff00) == 0x9100) /* dec $sp, X */
197 cache
->framesize
+= (inst
& 0x00ff);
200 while (next_addr
< end_addr
)
202 inst
= read_memory_unsigned_integer (next_addr
, 2, byte_order
);
203 if ((inst
& 0xff00) != 0x9100) /* no more dec $sp, X */
205 cache
->framesize
+= (inst
& 0x00ff);
213 /* Find the end of function prologue. */
216 moxie_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
218 CORE_ADDR func_addr
= 0, func_end
= 0;
219 const char *func_name
;
221 /* See if we can determine the end of the prologue via the symbol table.
222 If so, then return either PC, or the PC after the prologue, whichever
224 if (find_pc_partial_function (pc
, &func_name
, &func_addr
, &func_end
))
226 CORE_ADDR post_prologue_pc
227 = skip_prologue_using_sal (gdbarch
, func_addr
);
228 if (post_prologue_pc
!= 0)
229 return max (pc
, post_prologue_pc
);
232 /* Can't determine prologue from the symbol table, need to examine
234 struct symtab_and_line sal
;
236 struct moxie_frame_cache cache
;
239 memset (&cache
, 0, sizeof cache
);
241 plg_end
= moxie_analyze_prologue (func_addr
,
242 func_end
, &cache
, gdbarch
);
243 /* Found a function. */
244 sym
= lookup_symbol (func_name
, NULL
, VAR_DOMAIN
, NULL
);
245 /* Don't use line number debug info for assembly source
247 if (sym
&& SYMBOL_LANGUAGE (sym
) != language_asm
)
249 sal
= find_pc_line (func_addr
, 0);
250 if (sal
.end
&& sal
.end
< func_end
)
252 /* Found a line number, use it as end of
257 /* No useable line symbol. Use result of prologue parsing
263 /* No function symbol -- just return the PC. */
264 return (CORE_ADDR
) pc
;
267 struct moxie_unwind_cache
269 /* The previous frame's inner most stack address. Used as this
270 frame ID's stack_addr. */
272 /* The frame's base, optionally used by the high-level debug info. */
275 /* How far the SP and r13 (FP) have been offset from the start of
276 the stack frame (as defined by the previous frame's stack
281 /* Table indicating the location of each and every register. */
282 struct trad_frame_saved_reg
*saved_regs
;
285 /* Read an unsigned integer from the inferior, and adjust
288 moxie_process_readu (CORE_ADDR addr
, gdb_byte
*buf
,
289 int length
, enum bfd_endian byte_order
)
291 if (target_read_memory (addr
, buf
, length
))
294 printf_unfiltered (_("Process record: error reading memory at "
295 "addr 0x%s len = %d.\n"),
296 paddress (target_gdbarch (), addr
), length
);
300 return extract_unsigned_integer (buf
, length
, byte_order
);
304 /* Helper macro to extract the signed 10-bit offset from a 16-bit
305 branch instruction. */
306 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
308 /* Insert a single step breakpoint. */
311 moxie_software_single_step (struct frame_info
*frame
)
313 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
314 struct address_space
*aspace
= get_frame_address_space (frame
);
320 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
321 struct regcache
*regcache
= get_current_regcache ();
323 addr
= get_frame_pc (frame
);
325 inst
= (uint16_t) moxie_process_readu (addr
, buf
, 2, byte_order
);
327 /* Decode instruction. */
328 if (inst
& (1 << 15))
330 if (inst
& (1 << 14))
332 /* This is a Form 3 instruction. */
333 int opcode
= (inst
>> 10 & 0xf);
341 case 0x04: /* bltu */
342 case 0x05: /* bgtu */
345 case 0x08: /* bgeu */
346 case 0x09: /* bleu */
347 /* Insert breaks on both branches, because we can't currently tell
348 which way things will go. */
349 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 2);
350 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 2 + INST2OFFSET(inst
));
361 /* This is a Form 2 instruction. They are all 16 bits. */
362 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 2);
367 /* This is a Form 1 instruction. */
368 int opcode
= inst
>> 8;
372 /* 16-bit instructions. */
374 case 0x02: /* mov (register-to-register) */
375 case 0x05: /* add.l */
376 case 0x06: /* push */
378 case 0x0a: /* ld.l (register indirect) */
379 case 0x0b: /* st.l */
382 case 0x10: /* sex.b */
383 case 0x11: /* sex.s */
384 case 0x12: /* zex.b */
385 case 0x13: /* zex.s */
386 case 0x14: /* umul.x */
387 case 0x15: /* mul.x */
391 case 0x1c: /* ld.b (register indirect) */
392 case 0x1e: /* st.b */
393 case 0x21: /* ld.s (register indirect) */
394 case 0x23: /* st.s */
396 case 0x27: /* lshr */
397 case 0x28: /* ashl */
398 case 0x29: /* sub.l */
402 case 0x2d: /* ashr */
404 case 0x2f: /* mul.l */
405 case 0x31: /* div.l */
406 case 0x32: /* udiv.l */
407 case 0x33: /* mod.l */
408 case 0x34: /* umod.l */
409 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 2);
412 /* 32-bit instructions. */
413 case 0x0c: /* ldo.l */
414 case 0x0d: /* sto.l */
415 case 0x36: /* ldo.b */
416 case 0x37: /* sto.b */
417 case 0x38: /* ldo.s */
418 case 0x39: /* sto.s */
419 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 4);
422 /* 48-bit instructions. */
423 case 0x01: /* ldi.l (immediate) */
424 case 0x08: /* lda.l */
425 case 0x09: /* sta.l */
426 case 0x1b: /* ldi.b (immediate) */
427 case 0x1d: /* lda.b */
428 case 0x1f: /* sta.b */
429 case 0x20: /* ldi.s (immediate) */
430 case 0x22: /* lda.s */
431 case 0x24: /* sta.s */
432 insert_single_step_breakpoint (gdbarch
, aspace
, addr
+ 6);
435 /* Control flow instructions. */
436 case 0x03: /* jsra */
437 case 0x1a: /* jmpa */
438 insert_single_step_breakpoint (gdbarch
, aspace
,
439 moxie_process_readu (addr
+ 2,
445 regcache_cooked_read_unsigned (regcache
, MOXIE_FP_REGNUM
, &fp
);
446 insert_single_step_breakpoint (gdbarch
, aspace
,
447 moxie_process_readu (fp
+ 4,
454 regcache_raw_read (regcache
,
455 (inst
>> 4) & 0xf, (gdb_byte
*) & tmpu32
);
456 insert_single_step_breakpoint (gdbarch
, aspace
,
462 /* Unsupported, for now. */
470 /* Implement the "read_pc" gdbarch method. */
473 moxie_read_pc (struct regcache
*regcache
)
477 regcache_cooked_read_unsigned (regcache
, MOXIE_PC_REGNUM
, &pc
);
481 /* Implement the "write_pc" gdbarch method. */
484 moxie_write_pc (struct regcache
*regcache
, CORE_ADDR val
)
486 regcache_cooked_write_unsigned (regcache
, MOXIE_PC_REGNUM
, val
);
489 /* Implement the "unwind_sp" gdbarch method. */
492 moxie_unwind_sp (struct gdbarch
*gdbarch
, struct frame_info
*next_frame
)
494 return frame_unwind_register_unsigned (next_frame
, MOXIE_SP_REGNUM
);
497 /* Given a return value in `regbuf' with a type `valtype',
498 extract and copy its value into `valbuf'. */
501 moxie_extract_return_value (struct type
*type
, struct regcache
*regcache
,
504 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
505 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
506 bfd_byte
*valbuf
= dst
;
507 int len
= TYPE_LENGTH (type
);
510 /* By using store_unsigned_integer we avoid having to do
511 anything special for small big-endian values. */
512 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
, &tmp
);
513 store_unsigned_integer (valbuf
, (len
> 4 ? len
- 4 : len
), byte_order
, tmp
);
515 /* Ignore return values more than 8 bytes in size because the moxie
516 returns anything more than 8 bytes in the stack. */
519 regcache_cooked_read_unsigned (regcache
, RET1_REGNUM
+ 1, &tmp
);
520 store_unsigned_integer (valbuf
+ len
- 4, 4, byte_order
, tmp
);
524 /* Implement the "return_value" gdbarch method. */
526 static enum return_value_convention
527 moxie_return_value (struct gdbarch
*gdbarch
, struct value
*function
,
528 struct type
*valtype
, struct regcache
*regcache
,
529 gdb_byte
*readbuf
, const gdb_byte
*writebuf
)
531 if (TYPE_LENGTH (valtype
) > 8)
532 return RETURN_VALUE_STRUCT_CONVENTION
;
536 moxie_extract_return_value (valtype
, regcache
, readbuf
);
537 if (writebuf
!= NULL
)
538 moxie_store_return_value (valtype
, regcache
, writebuf
);
539 return RETURN_VALUE_REGISTER_CONVENTION
;
543 /* Allocate and initialize a moxie_frame_cache object. */
545 static struct moxie_frame_cache
*
546 moxie_alloc_frame_cache (void)
548 struct moxie_frame_cache
*cache
;
551 cache
= FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache
);
556 cache
->framesize
= 0;
557 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
558 cache
->saved_regs
[i
] = REG_UNAVAIL
;
563 /* Populate a moxie_frame_cache object for this_frame. */
565 static struct moxie_frame_cache
*
566 moxie_frame_cache (struct frame_info
*this_frame
, void **this_cache
)
568 struct moxie_frame_cache
*cache
;
569 CORE_ADDR current_pc
;
575 cache
= moxie_alloc_frame_cache ();
578 cache
->base
= get_frame_register_unsigned (this_frame
, MOXIE_FP_REGNUM
);
579 if (cache
->base
== 0)
582 cache
->pc
= get_frame_func (this_frame
);
583 current_pc
= get_frame_pc (this_frame
);
586 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
587 moxie_analyze_prologue (cache
->pc
, current_pc
, cache
, gdbarch
);
590 cache
->saved_sp
= cache
->base
- cache
->framesize
;
592 for (i
= 0; i
< MOXIE_NUM_REGS
; ++i
)
593 if (cache
->saved_regs
[i
] != REG_UNAVAIL
)
594 cache
->saved_regs
[i
] = cache
->base
- cache
->saved_regs
[i
];
599 /* Implement the "unwind_pc" gdbarch method. */
602 moxie_unwind_pc (struct gdbarch
*gdbarch
, struct frame_info
*next_frame
)
604 return frame_unwind_register_unsigned (next_frame
, MOXIE_PC_REGNUM
);
607 /* Given a GDB frame, determine the address of the calling function's
608 frame. This will be used to create a new GDB frame struct. */
611 moxie_frame_this_id (struct frame_info
*this_frame
,
612 void **this_prologue_cache
, struct frame_id
*this_id
)
614 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
615 this_prologue_cache
);
617 /* This marks the outermost frame. */
618 if (cache
->base
== 0)
621 *this_id
= frame_id_build (cache
->saved_sp
, cache
->pc
);
624 /* Get the value of register regnum in the previous stack frame. */
626 static struct value
*
627 moxie_frame_prev_register (struct frame_info
*this_frame
,
628 void **this_prologue_cache
, int regnum
)
630 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
631 this_prologue_cache
);
633 gdb_assert (regnum
>= 0);
635 if (regnum
== MOXIE_SP_REGNUM
&& cache
->saved_sp
)
636 return frame_unwind_got_constant (this_frame
, regnum
, cache
->saved_sp
);
638 if (regnum
< MOXIE_NUM_REGS
&& cache
->saved_regs
[regnum
] != REG_UNAVAIL
)
639 return frame_unwind_got_memory (this_frame
, regnum
,
640 cache
->saved_regs
[regnum
]);
642 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
645 static const struct frame_unwind moxie_frame_unwind
= {
647 default_frame_unwind_stop_reason
,
649 moxie_frame_prev_register
,
651 default_frame_sniffer
654 /* Return the base address of this_frame. */
657 moxie_frame_base_address (struct frame_info
*this_frame
, void **this_cache
)
659 struct moxie_frame_cache
*cache
= moxie_frame_cache (this_frame
,
665 static const struct frame_base moxie_frame_base
= {
667 moxie_frame_base_address
,
668 moxie_frame_base_address
,
669 moxie_frame_base_address
672 static struct frame_id
673 moxie_dummy_id (struct gdbarch
*gdbarch
, struct frame_info
*this_frame
)
675 CORE_ADDR sp
= get_frame_register_unsigned (this_frame
, MOXIE_SP_REGNUM
);
677 return frame_id_build (sp
, get_frame_pc (this_frame
));
680 /* Parse the current instruction and record the values of the registers and
681 memory that will be changed in current instruction to "record_arch_list".
682 Return -1 if something wrong. */
685 moxie_process_record (struct gdbarch
*gdbarch
, struct regcache
*regcache
,
691 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
693 if (record_debug
> 1)
694 fprintf_unfiltered (gdb_stdlog
, "Process record: moxie_process_record "
696 paddress (target_gdbarch (), addr
));
698 inst
= (uint16_t) moxie_process_readu (addr
, buf
, 2, byte_order
);
700 /* Decode instruction. */
701 if (inst
& (1 << 15))
703 if (inst
& (1 << 14))
705 /* This is a Form 3 instruction. */
706 int opcode
= (inst
>> 10 & 0xf);
714 case 0x04: /* bltu */
715 case 0x05: /* bgtu */
718 case 0x08: /* bgeu */
719 case 0x09: /* bleu */
731 /* This is a Form 2 instruction. */
732 int opcode
= (inst
>> 12 & 0x3);
739 int reg
= (inst
>> 8) & 0xf;
740 if (record_full_arch_list_add_reg (regcache
, reg
))
746 /* Do nothing until GDB learns about moxie's special
758 /* This is a Form 1 instruction. */
759 int opcode
= inst
>> 8;
766 case 0x01: /* ldi.l (immediate) */
767 case 0x02: /* mov (register-to-register) */
769 int reg
= (inst
>> 4) & 0xf;
770 if (record_full_arch_list_add_reg (regcache
, reg
))
774 case 0x03: /* jsra */
776 regcache_raw_read (regcache
,
777 MOXIE_SP_REGNUM
, (gdb_byte
*) & tmpu32
);
778 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
780 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
781 || (record_full_arch_list_add_reg (regcache
,
783 || record_full_arch_list_add_mem (tmpu32
- 12, 12))
789 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
790 || (record_full_arch_list_add_reg (regcache
,
795 case 0x05: /* add.l */
797 int reg
= (inst
>> 4) & 0xf;
798 if (record_full_arch_list_add_reg (regcache
, reg
))
802 case 0x06: /* push */
804 int reg
= (inst
>> 4) & 0xf;
805 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
806 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
808 if (record_full_arch_list_add_reg (regcache
, reg
)
809 || record_full_arch_list_add_mem (tmpu32
- 4, 4))
815 int a
= (inst
>> 4) & 0xf;
817 if (record_full_arch_list_add_reg (regcache
, a
)
818 || record_full_arch_list_add_reg (regcache
, b
))
822 case 0x08: /* lda.l */
824 int reg
= (inst
>> 4) & 0xf;
825 if (record_full_arch_list_add_reg (regcache
, reg
))
829 case 0x09: /* sta.l */
831 tmpu32
= (uint32_t) moxie_process_readu (addr
+2, buf
,
833 if (record_full_arch_list_add_mem (tmpu32
, 4))
837 case 0x0a: /* ld.l (register indirect) */
839 int reg
= (inst
>> 4) & 0xf;
840 if (record_full_arch_list_add_reg (regcache
, reg
))
844 case 0x0b: /* st.l */
846 int reg
= (inst
>> 4) & 0xf;
847 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
848 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
850 if (record_full_arch_list_add_mem (tmpu32
, 4))
854 case 0x0c: /* ldo.l */
856 int reg
= (inst
>> 4) & 0xf;
857 if (record_full_arch_list_add_reg (regcache
, reg
))
861 case 0x0d: /* sto.l */
863 int reg
= (inst
>> 4) & 0xf;
864 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
865 byte_order
)) << 16 ) >> 16;
866 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
867 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
870 if (record_full_arch_list_add_mem (tmpu32
, 4))
876 if (record_full_arch_list_add_reg (regcache
, MOXIE_CC_REGNUM
))
885 case 0x10: /* sex.b */
886 case 0x11: /* sex.s */
887 case 0x12: /* zex.b */
888 case 0x13: /* zex.s */
889 case 0x14: /* umul.x */
890 case 0x15: /* mul.x */
892 int reg
= (inst
>> 4) & 0xf;
893 if (record_full_arch_list_add_reg (regcache
, reg
))
906 regcache_raw_read (regcache
,
907 MOXIE_SP_REGNUM
, (gdb_byte
*) & tmpu32
);
908 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
910 if (record_full_arch_list_add_reg (regcache
, MOXIE_FP_REGNUM
)
911 || (record_full_arch_list_add_reg (regcache
,
913 || record_full_arch_list_add_mem (tmpu32
- 12, 12))
917 case 0x1a: /* jmpa */
922 case 0x1b: /* ldi.b (immediate) */
923 case 0x1c: /* ld.b (register indirect) */
924 case 0x1d: /* lda.b */
926 int reg
= (inst
>> 4) & 0xf;
927 if (record_full_arch_list_add_reg (regcache
, reg
))
931 case 0x1e: /* st.b */
933 int reg
= (inst
>> 4) & 0xf;
934 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
935 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
937 if (record_full_arch_list_add_mem (tmpu32
, 1))
941 case 0x1f: /* sta.b */
943 tmpu32
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
944 if (record_full_arch_list_add_mem (tmpu32
, 1))
948 case 0x20: /* ldi.s (immediate) */
949 case 0x21: /* ld.s (register indirect) */
950 case 0x22: /* lda.s */
952 int reg
= (inst
>> 4) & 0xf;
953 if (record_full_arch_list_add_reg (regcache
, reg
))
957 case 0x23: /* st.s */
959 int reg
= (inst
>> 4) & 0xf;
960 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
961 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
963 if (record_full_arch_list_add_mem (tmpu32
, 2))
967 case 0x24: /* sta.s */
969 tmpu32
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
970 if (record_full_arch_list_add_mem (tmpu32
, 2))
980 case 0x27: /* lshr */
981 case 0x28: /* ashl */
986 case 0x2d: /* ashr */
990 int reg
= (inst
>> 4) & 0xf;
991 if (record_full_arch_list_add_reg (regcache
, reg
))
997 /* We currently implement support for libgloss'
1000 int inum
= moxie_process_readu (addr
+2, buf
, 4, byte_order
);
1004 case 0x1: /* SYS_exit */
1009 case 0x2: /* SYS_open */
1011 if (record_full_arch_list_add_reg (regcache
, RET1_REGNUM
))
1015 case 0x4: /* SYS_read */
1017 uint32_t length
, ptr
;
1019 /* Read buffer pointer is in $r1. */
1020 regcache_raw_read (regcache
, 3, (gdb_byte
*) & ptr
);
1021 ptr
= extract_unsigned_integer ((gdb_byte
*) & ptr
,
1024 /* String length is at 0x12($fp). */
1025 regcache_raw_read (regcache
,
1026 MOXIE_FP_REGNUM
, (gdb_byte
*) & tmpu32
);
1027 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
1029 length
= moxie_process_readu (tmpu32
+20, buf
, 4, byte_order
);
1031 if (record_full_arch_list_add_mem (ptr
, length
))
1035 case 0x5: /* SYS_write */
1037 if (record_full_arch_list_add_reg (regcache
, RET1_REGNUM
))
1046 case 0x31: /* div.l */
1047 case 0x32: /* udiv.l */
1048 case 0x33: /* mod.l */
1049 case 0x34: /* umod.l */
1051 int reg
= (inst
>> 4) & 0xf;
1052 if (record_full_arch_list_add_reg (regcache
, reg
))
1056 case 0x35: /* brk */
1059 case 0x36: /* ldo.b */
1061 int reg
= (inst
>> 4) & 0xf;
1062 if (record_full_arch_list_add_reg (regcache
, reg
))
1066 case 0x37: /* sto.b */
1068 int reg
= (inst
>> 4) & 0xf;
1069 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
1070 byte_order
)) << 16 ) >> 16;
1071 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
1072 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
1075 if (record_full_arch_list_add_mem (tmpu32
, 1))
1079 case 0x38: /* ldo.s */
1081 int reg
= (inst
>> 4) & 0xf;
1082 if (record_full_arch_list_add_reg (regcache
, reg
))
1086 case 0x39: /* sto.s */
1088 int reg
= (inst
>> 4) & 0xf;
1089 uint32_t offset
= (((int16_t) moxie_process_readu (addr
+2, buf
, 2,
1090 byte_order
)) << 16 ) >> 16;
1091 regcache_raw_read (regcache
, reg
, (gdb_byte
*) & tmpu32
);
1092 tmpu32
= extract_unsigned_integer ((gdb_byte
*) & tmpu32
,
1095 if (record_full_arch_list_add_mem (tmpu32
, 2))
1105 if (record_full_arch_list_add_reg (regcache
, MOXIE_PC_REGNUM
))
1107 if (record_full_arch_list_add_end ())
1112 /* Allocate and initialize the moxie gdbarch object. */
1114 static struct gdbarch
*
1115 moxie_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
1117 struct gdbarch
*gdbarch
;
1118 struct gdbarch_tdep
*tdep
;
1120 /* If there is already a candidate, use it. */
1121 arches
= gdbarch_list_lookup_by_info (arches
, &info
);
1123 return arches
->gdbarch
;
1125 /* Allocate space for the new architecture. */
1126 tdep
= XNEW (struct gdbarch_tdep
);
1127 gdbarch
= gdbarch_alloc (&info
, tdep
);
1129 set_gdbarch_read_pc (gdbarch
, moxie_read_pc
);
1130 set_gdbarch_write_pc (gdbarch
, moxie_write_pc
);
1131 set_gdbarch_unwind_sp (gdbarch
, moxie_unwind_sp
);
1133 set_gdbarch_num_regs (gdbarch
, MOXIE_NUM_REGS
);
1134 set_gdbarch_sp_regnum (gdbarch
, MOXIE_SP_REGNUM
);
1135 set_gdbarch_pc_regnum (gdbarch
, MOXIE_PC_REGNUM
);
1136 set_gdbarch_register_name (gdbarch
, moxie_register_name
);
1137 set_gdbarch_register_type (gdbarch
, moxie_register_type
);
1139 set_gdbarch_return_value (gdbarch
, moxie_return_value
);
1141 set_gdbarch_skip_prologue (gdbarch
, moxie_skip_prologue
);
1142 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
1143 set_gdbarch_breakpoint_from_pc (gdbarch
, moxie_breakpoint_from_pc
);
1144 set_gdbarch_frame_align (gdbarch
, moxie_frame_align
);
1146 frame_base_set_default (gdbarch
, &moxie_frame_base
);
1148 /* Methods for saving / extracting a dummy frame's ID. The ID's
1149 stack address must match the SP value returned by
1150 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1151 set_gdbarch_dummy_id (gdbarch
, moxie_dummy_id
);
1153 set_gdbarch_unwind_pc (gdbarch
, moxie_unwind_pc
);
1155 set_gdbarch_print_insn (gdbarch
, print_insn_moxie
);
1157 /* Hook in ABI-specific overrides, if they have been registered. */
1158 gdbarch_init_osabi (info
, gdbarch
);
1160 /* Hook in the default unwinders. */
1161 frame_unwind_append_unwinder (gdbarch
, &moxie_frame_unwind
);
1163 /* Single stepping. */
1164 set_gdbarch_software_single_step (gdbarch
, moxie_software_single_step
);
1166 /* Support simple overlay manager. */
1167 set_gdbarch_overlay_update (gdbarch
, simple_overlay_update
);
1169 /* Support reverse debugging. */
1170 set_gdbarch_process_record (gdbarch
, moxie_process_record
);
1175 /* Register this machine's init routine. */
1178 _initialize_moxie_tdep (void)
1180 register_gdbarch_init (bfd_arch_moxie
, moxie_gdbarch_init
);