]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/moxie-tdep.c
Remove GDBARCH_BREAKPOINT_MANIPULATION and SET_GDBARCH_BREAKPOINT_MANIPULATION
[thirdparty/binutils-gdb.git] / gdb / moxie-tdep.c
1 /* Target-dependent code for Moxie.
2
3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20 #include "defs.h"
21 #include "frame.h"
22 #include "frame-unwind.h"
23 #include "frame-base.h"
24 #include "symtab.h"
25 #include "gdbtypes.h"
26 #include "gdbcmd.h"
27 #include "gdbcore.h"
28 #include "value.h"
29 #include "inferior.h"
30 #include "symfile.h"
31 #include "objfiles.h"
32 #include "osabi.h"
33 #include "language.h"
34 #include "arch-utils.h"
35 #include "regcache.h"
36 #include "trad-frame.h"
37 #include "dis-asm.h"
38 #include "record.h"
39 #include "record-full.h"
40
41 #include "moxie-tdep.h"
42 #include <algorithm>
43
44 /* Local functions. */
45
46 extern void _initialize_moxie_tdep (void);
47
48 /* Use an invalid address value as 'not available' marker. */
49 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50
51 struct moxie_frame_cache
52 {
53 /* Base address. */
54 CORE_ADDR base;
55 CORE_ADDR pc;
56 LONGEST framesize;
57 CORE_ADDR saved_regs[MOXIE_NUM_REGS];
58 CORE_ADDR saved_sp;
59 };
60
61 /* Implement the "frame_align" gdbarch method. */
62
63 static CORE_ADDR
64 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65 {
66 /* Align to the size of an instruction (so that they can safely be
67 pushed onto the stack. */
68 return sp & ~1;
69 }
70
71 constexpr gdb_byte moxie_break_insn[] = { 0x35, 0x00 };
72
73 typedef BP_MANIPULATION (moxie_break_insn) moxie_breakpoint;
74
75 /* Moxie register names. */
76
77 char *moxie_register_names[] = {
78 "$fp", "$sp", "$r0", "$r1", "$r2",
79 "$r3", "$r4", "$r5", "$r6", "$r7",
80 "$r8", "$r9", "$r10", "$r11", "$r12",
81 "$r13", "$pc", "$cc" };
82
83 /* Implement the "register_name" gdbarch method. */
84
85 static const char *
86 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
87 {
88 if (reg_nr < 0)
89 return NULL;
90 if (reg_nr >= MOXIE_NUM_REGS)
91 return NULL;
92 return moxie_register_names[reg_nr];
93 }
94
95 /* Implement the "register_type" gdbarch method. */
96
97 static struct type *
98 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
99 {
100 if (reg_nr == MOXIE_PC_REGNUM)
101 return builtin_type (gdbarch)->builtin_func_ptr;
102 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
103 return builtin_type (gdbarch)->builtin_data_ptr;
104 else
105 return builtin_type (gdbarch)->builtin_int32;
106 }
107
108 /* Write into appropriate registers a function return value
109 of type TYPE, given in virtual format. */
110
111 static void
112 moxie_store_return_value (struct type *type, struct regcache *regcache,
113 const gdb_byte *valbuf)
114 {
115 struct gdbarch *gdbarch = get_regcache_arch (regcache);
116 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
117 CORE_ADDR regval;
118 int len = TYPE_LENGTH (type);
119
120 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */
121 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
122 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
123 if (len > 4)
124 {
125 regval = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
126 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
127 }
128 }
129
130 /* Decode the instructions within the given address range. Decide
131 when we must have reached the end of the function prologue. If a
132 frame_info pointer is provided, fill in its saved_regs etc.
133
134 Returns the address of the first instruction after the prologue. */
135
136 static CORE_ADDR
137 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
138 struct moxie_frame_cache *cache,
139 struct gdbarch *gdbarch)
140 {
141 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
142 CORE_ADDR next_addr;
143 ULONGEST inst, inst2;
144 LONGEST offset;
145 int regnum;
146
147 /* Record where the jsra instruction saves the PC and FP. */
148 cache->saved_regs[MOXIE_PC_REGNUM] = -4;
149 cache->saved_regs[MOXIE_FP_REGNUM] = 0;
150 cache->framesize = 0;
151
152 if (start_addr >= end_addr)
153 return end_addr;
154
155 for (next_addr = start_addr; next_addr < end_addr; )
156 {
157 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
158
159 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */
160 if (inst >= 0x0612 && inst <= 0x061f)
161 {
162 regnum = inst & 0x000f;
163 cache->framesize += 4;
164 cache->saved_regs[regnum] = cache->framesize;
165 next_addr += 2;
166 }
167 else
168 break;
169 }
170
171 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
172
173 /* Optional stack allocation for args and local vars <= 4
174 byte. */
175 if (inst == 0x01e0) /* ldi.l $r12, X */
176 {
177 offset = read_memory_integer (next_addr + 2, 4, byte_order);
178 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
179
180 if (inst2 == 0x291e) /* sub.l $sp, $r12 */
181 {
182 cache->framesize += offset;
183 }
184
185 return (next_addr + 8);
186 }
187 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */
188 {
189 cache->framesize += (inst & 0x00ff);
190 next_addr += 2;
191
192 while (next_addr < end_addr)
193 {
194 inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
195 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
196 break;
197 cache->framesize += (inst & 0x00ff);
198 next_addr += 2;
199 }
200 }
201
202 return next_addr;
203 }
204
205 /* Find the end of function prologue. */
206
207 static CORE_ADDR
208 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
209 {
210 CORE_ADDR func_addr = 0, func_end = 0;
211 const char *func_name;
212
213 /* See if we can determine the end of the prologue via the symbol table.
214 If so, then return either PC, or the PC after the prologue, whichever
215 is greater. */
216 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
217 {
218 CORE_ADDR post_prologue_pc
219 = skip_prologue_using_sal (gdbarch, func_addr);
220 if (post_prologue_pc != 0)
221 return std::max (pc, post_prologue_pc);
222 else
223 {
224 /* Can't determine prologue from the symbol table, need to examine
225 instructions. */
226 struct symtab_and_line sal;
227 struct symbol *sym;
228 struct moxie_frame_cache cache;
229 CORE_ADDR plg_end;
230
231 memset (&cache, 0, sizeof cache);
232
233 plg_end = moxie_analyze_prologue (func_addr,
234 func_end, &cache, gdbarch);
235 /* Found a function. */
236 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
237 /* Don't use line number debug info for assembly source
238 files. */
239 if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
240 {
241 sal = find_pc_line (func_addr, 0);
242 if (sal.end && sal.end < func_end)
243 {
244 /* Found a line number, use it as end of
245 prologue. */
246 return sal.end;
247 }
248 }
249 /* No useable line symbol. Use result of prologue parsing
250 method. */
251 return plg_end;
252 }
253 }
254
255 /* No function symbol -- just return the PC. */
256 return (CORE_ADDR) pc;
257 }
258
259 struct moxie_unwind_cache
260 {
261 /* The previous frame's inner most stack address. Used as this
262 frame ID's stack_addr. */
263 CORE_ADDR prev_sp;
264 /* The frame's base, optionally used by the high-level debug info. */
265 CORE_ADDR base;
266 int size;
267 /* How far the SP and r13 (FP) have been offset from the start of
268 the stack frame (as defined by the previous frame's stack
269 pointer). */
270 LONGEST sp_offset;
271 LONGEST r13_offset;
272 int uses_frame;
273 /* Table indicating the location of each and every register. */
274 struct trad_frame_saved_reg *saved_regs;
275 };
276
277 /* Read an unsigned integer from the inferior, and adjust
278 endianess. */
279 static ULONGEST
280 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
281 int length, enum bfd_endian byte_order)
282 {
283 if (target_read_memory (addr, buf, length))
284 {
285 if (record_debug)
286 printf_unfiltered (_("Process record: error reading memory at "
287 "addr 0x%s len = %d.\n"),
288 paddress (target_gdbarch (), addr), length);
289 return -1;
290 }
291
292 return extract_unsigned_integer (buf, length, byte_order);
293 }
294
295
296 /* Helper macro to extract the signed 10-bit offset from a 16-bit
297 branch instruction. */
298 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
299
300 /* Insert a single step breakpoint. */
301
302 static int
303 moxie_software_single_step (struct frame_info *frame)
304 {
305 struct gdbarch *gdbarch = get_frame_arch (frame);
306 struct address_space *aspace = get_frame_address_space (frame);
307 CORE_ADDR addr;
308 gdb_byte buf[4];
309 uint16_t inst;
310 uint32_t tmpu32;
311 ULONGEST fp;
312 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
313 struct regcache *regcache = get_current_regcache ();
314
315 addr = get_frame_pc (frame);
316
317 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
318
319 /* Decode instruction. */
320 if (inst & (1 << 15))
321 {
322 if (inst & (1 << 14))
323 {
324 /* This is a Form 3 instruction. */
325 int opcode = (inst >> 10 & 0xf);
326
327 switch (opcode)
328 {
329 case 0x00: /* beq */
330 case 0x01: /* bne */
331 case 0x02: /* blt */
332 case 0x03: /* bgt */
333 case 0x04: /* bltu */
334 case 0x05: /* bgtu */
335 case 0x06: /* bge */
336 case 0x07: /* ble */
337 case 0x08: /* bgeu */
338 case 0x09: /* bleu */
339 /* Insert breaks on both branches, because we can't currently tell
340 which way things will go. */
341 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
342 insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst));
343 break;
344 default:
345 {
346 /* Do nothing. */
347 break;
348 }
349 }
350 }
351 else
352 {
353 /* This is a Form 2 instruction. They are all 16 bits. */
354 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
355 }
356 }
357 else
358 {
359 /* This is a Form 1 instruction. */
360 int opcode = inst >> 8;
361
362 switch (opcode)
363 {
364 /* 16-bit instructions. */
365 case 0x00: /* bad */
366 case 0x02: /* mov (register-to-register) */
367 case 0x05: /* add.l */
368 case 0x06: /* push */
369 case 0x07: /* pop */
370 case 0x0a: /* ld.l (register indirect) */
371 case 0x0b: /* st.l */
372 case 0x0e: /* cmp */
373 case 0x0f: /* nop */
374 case 0x10: /* sex.b */
375 case 0x11: /* sex.s */
376 case 0x12: /* zex.b */
377 case 0x13: /* zex.s */
378 case 0x14: /* umul.x */
379 case 0x15: /* mul.x */
380 case 0x16:
381 case 0x17:
382 case 0x18:
383 case 0x1c: /* ld.b (register indirect) */
384 case 0x1e: /* st.b */
385 case 0x21: /* ld.s (register indirect) */
386 case 0x23: /* st.s */
387 case 0x26: /* and */
388 case 0x27: /* lshr */
389 case 0x28: /* ashl */
390 case 0x29: /* sub.l */
391 case 0x2a: /* neg */
392 case 0x2b: /* or */
393 case 0x2c: /* not */
394 case 0x2d: /* ashr */
395 case 0x2e: /* xor */
396 case 0x2f: /* mul.l */
397 case 0x31: /* div.l */
398 case 0x32: /* udiv.l */
399 case 0x33: /* mod.l */
400 case 0x34: /* umod.l */
401 insert_single_step_breakpoint (gdbarch, aspace, addr + 2);
402 break;
403
404 /* 32-bit instructions. */
405 case 0x0c: /* ldo.l */
406 case 0x0d: /* sto.l */
407 case 0x36: /* ldo.b */
408 case 0x37: /* sto.b */
409 case 0x38: /* ldo.s */
410 case 0x39: /* sto.s */
411 insert_single_step_breakpoint (gdbarch, aspace, addr + 4);
412 break;
413
414 /* 48-bit instructions. */
415 case 0x01: /* ldi.l (immediate) */
416 case 0x08: /* lda.l */
417 case 0x09: /* sta.l */
418 case 0x1b: /* ldi.b (immediate) */
419 case 0x1d: /* lda.b */
420 case 0x1f: /* sta.b */
421 case 0x20: /* ldi.s (immediate) */
422 case 0x22: /* lda.s */
423 case 0x24: /* sta.s */
424 insert_single_step_breakpoint (gdbarch, aspace, addr + 6);
425 break;
426
427 /* Control flow instructions. */
428 case 0x03: /* jsra */
429 case 0x1a: /* jmpa */
430 insert_single_step_breakpoint (gdbarch, aspace,
431 moxie_process_readu (addr + 2,
432 buf, 4,
433 byte_order));
434 break;
435
436 case 0x04: /* ret */
437 regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
438 insert_single_step_breakpoint (gdbarch, aspace,
439 moxie_process_readu (fp + 4,
440 buf, 4,
441 byte_order));
442 break;
443
444 case 0x19: /* jsr */
445 case 0x25: /* jmp */
446 regcache_raw_read (regcache,
447 (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
448 insert_single_step_breakpoint (gdbarch, aspace,
449 tmpu32);
450 break;
451
452 case 0x30: /* swi */
453 case 0x35: /* brk */
454 /* Unsupported, for now. */
455 break;
456 }
457 }
458
459 return 1;
460 }
461
462 /* Implement the "read_pc" gdbarch method. */
463
464 static CORE_ADDR
465 moxie_read_pc (struct regcache *regcache)
466 {
467 ULONGEST pc;
468
469 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
470 return pc;
471 }
472
473 /* Implement the "write_pc" gdbarch method. */
474
475 static void
476 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
477 {
478 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
479 }
480
481 /* Implement the "unwind_sp" gdbarch method. */
482
483 static CORE_ADDR
484 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
485 {
486 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
487 }
488
489 /* Given a return value in `regbuf' with a type `valtype',
490 extract and copy its value into `valbuf'. */
491
492 static void
493 moxie_extract_return_value (struct type *type, struct regcache *regcache,
494 gdb_byte *dst)
495 {
496 struct gdbarch *gdbarch = get_regcache_arch (regcache);
497 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
498 int len = TYPE_LENGTH (type);
499 ULONGEST tmp;
500
501 /* By using store_unsigned_integer we avoid having to do
502 anything special for small big-endian values. */
503 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
504 store_unsigned_integer (dst, (len > 4 ? len - 4 : len), byte_order, tmp);
505
506 /* Ignore return values more than 8 bytes in size because the moxie
507 returns anything more than 8 bytes in the stack. */
508 if (len > 4)
509 {
510 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
511 store_unsigned_integer (dst + len - 4, 4, byte_order, tmp);
512 }
513 }
514
515 /* Implement the "return_value" gdbarch method. */
516
517 static enum return_value_convention
518 moxie_return_value (struct gdbarch *gdbarch, struct value *function,
519 struct type *valtype, struct regcache *regcache,
520 gdb_byte *readbuf, const gdb_byte *writebuf)
521 {
522 if (TYPE_LENGTH (valtype) > 8)
523 return RETURN_VALUE_STRUCT_CONVENTION;
524 else
525 {
526 if (readbuf != NULL)
527 moxie_extract_return_value (valtype, regcache, readbuf);
528 if (writebuf != NULL)
529 moxie_store_return_value (valtype, regcache, writebuf);
530 return RETURN_VALUE_REGISTER_CONVENTION;
531 }
532 }
533
534 /* Allocate and initialize a moxie_frame_cache object. */
535
536 static struct moxie_frame_cache *
537 moxie_alloc_frame_cache (void)
538 {
539 struct moxie_frame_cache *cache;
540 int i;
541
542 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
543
544 cache->base = 0;
545 cache->saved_sp = 0;
546 cache->pc = 0;
547 cache->framesize = 0;
548 for (i = 0; i < MOXIE_NUM_REGS; ++i)
549 cache->saved_regs[i] = REG_UNAVAIL;
550
551 return cache;
552 }
553
554 /* Populate a moxie_frame_cache object for this_frame. */
555
556 static struct moxie_frame_cache *
557 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
558 {
559 struct moxie_frame_cache *cache;
560 CORE_ADDR current_pc;
561 int i;
562
563 if (*this_cache)
564 return (struct moxie_frame_cache *) *this_cache;
565
566 cache = moxie_alloc_frame_cache ();
567 *this_cache = cache;
568
569 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
570 if (cache->base == 0)
571 return cache;
572
573 cache->pc = get_frame_func (this_frame);
574 current_pc = get_frame_pc (this_frame);
575 if (cache->pc)
576 {
577 struct gdbarch *gdbarch = get_frame_arch (this_frame);
578 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
579 }
580
581 cache->saved_sp = cache->base - cache->framesize;
582
583 for (i = 0; i < MOXIE_NUM_REGS; ++i)
584 if (cache->saved_regs[i] != REG_UNAVAIL)
585 cache->saved_regs[i] = cache->base - cache->saved_regs[i];
586
587 return cache;
588 }
589
590 /* Implement the "unwind_pc" gdbarch method. */
591
592 static CORE_ADDR
593 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
594 {
595 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
596 }
597
598 /* Given a GDB frame, determine the address of the calling function's
599 frame. This will be used to create a new GDB frame struct. */
600
601 static void
602 moxie_frame_this_id (struct frame_info *this_frame,
603 void **this_prologue_cache, struct frame_id *this_id)
604 {
605 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
606 this_prologue_cache);
607
608 /* This marks the outermost frame. */
609 if (cache->base == 0)
610 return;
611
612 *this_id = frame_id_build (cache->saved_sp, cache->pc);
613 }
614
615 /* Get the value of register regnum in the previous stack frame. */
616
617 static struct value *
618 moxie_frame_prev_register (struct frame_info *this_frame,
619 void **this_prologue_cache, int regnum)
620 {
621 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
622 this_prologue_cache);
623
624 gdb_assert (regnum >= 0);
625
626 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
627 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
628
629 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
630 return frame_unwind_got_memory (this_frame, regnum,
631 cache->saved_regs[regnum]);
632
633 return frame_unwind_got_register (this_frame, regnum, regnum);
634 }
635
636 static const struct frame_unwind moxie_frame_unwind = {
637 NORMAL_FRAME,
638 default_frame_unwind_stop_reason,
639 moxie_frame_this_id,
640 moxie_frame_prev_register,
641 NULL,
642 default_frame_sniffer
643 };
644
645 /* Return the base address of this_frame. */
646
647 static CORE_ADDR
648 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
649 {
650 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
651 this_cache);
652
653 return cache->base;
654 }
655
656 static const struct frame_base moxie_frame_base = {
657 &moxie_frame_unwind,
658 moxie_frame_base_address,
659 moxie_frame_base_address,
660 moxie_frame_base_address
661 };
662
663 static struct frame_id
664 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
665 {
666 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
667
668 return frame_id_build (sp, get_frame_pc (this_frame));
669 }
670
671 /* Parse the current instruction and record the values of the registers and
672 memory that will be changed in current instruction to "record_arch_list".
673 Return -1 if something wrong. */
674
675 static int
676 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
677 CORE_ADDR addr)
678 {
679 gdb_byte buf[4];
680 uint16_t inst;
681 uint32_t tmpu32;
682 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
683
684 if (record_debug > 1)
685 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
686 "addr = 0x%s\n",
687 paddress (target_gdbarch (), addr));
688
689 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);
690
691 /* Decode instruction. */
692 if (inst & (1 << 15))
693 {
694 if (inst & (1 << 14))
695 {
696 /* This is a Form 3 instruction. */
697 int opcode = (inst >> 10 & 0xf);
698
699 switch (opcode)
700 {
701 case 0x00: /* beq */
702 case 0x01: /* bne */
703 case 0x02: /* blt */
704 case 0x03: /* bgt */
705 case 0x04: /* bltu */
706 case 0x05: /* bgtu */
707 case 0x06: /* bge */
708 case 0x07: /* ble */
709 case 0x08: /* bgeu */
710 case 0x09: /* bleu */
711 /* Do nothing. */
712 break;
713 default:
714 {
715 /* Do nothing. */
716 break;
717 }
718 }
719 }
720 else
721 {
722 /* This is a Form 2 instruction. */
723 int opcode = (inst >> 12 & 0x3);
724 switch (opcode)
725 {
726 case 0x00: /* inc */
727 case 0x01: /* dec */
728 case 0x02: /* gsr */
729 {
730 int reg = (inst >> 8) & 0xf;
731 if (record_full_arch_list_add_reg (regcache, reg))
732 return -1;
733 }
734 break;
735 case 0x03: /* ssr */
736 {
737 /* Do nothing until GDB learns about moxie's special
738 registers. */
739 }
740 break;
741 default:
742 /* Do nothing. */
743 break;
744 }
745 }
746 }
747 else
748 {
749 /* This is a Form 1 instruction. */
750 int opcode = inst >> 8;
751
752 switch (opcode)
753 {
754 case 0x00: /* nop */
755 /* Do nothing. */
756 break;
757 case 0x01: /* ldi.l (immediate) */
758 case 0x02: /* mov (register-to-register) */
759 {
760 int reg = (inst >> 4) & 0xf;
761 if (record_full_arch_list_add_reg (regcache, reg))
762 return -1;
763 }
764 break;
765 case 0x03: /* jsra */
766 {
767 regcache_raw_read (regcache,
768 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
769 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
770 4, byte_order);
771 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
772 || (record_full_arch_list_add_reg (regcache,
773 MOXIE_SP_REGNUM))
774 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
775 return -1;
776 }
777 break;
778 case 0x04: /* ret */
779 {
780 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
781 || (record_full_arch_list_add_reg (regcache,
782 MOXIE_SP_REGNUM)))
783 return -1;
784 }
785 break;
786 case 0x05: /* add.l */
787 {
788 int reg = (inst >> 4) & 0xf;
789 if (record_full_arch_list_add_reg (regcache, reg))
790 return -1;
791 }
792 break;
793 case 0x06: /* push */
794 {
795 int reg = (inst >> 4) & 0xf;
796 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
797 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
798 4, byte_order);
799 if (record_full_arch_list_add_reg (regcache, reg)
800 || record_full_arch_list_add_mem (tmpu32 - 4, 4))
801 return -1;
802 }
803 break;
804 case 0x07: /* pop */
805 {
806 int a = (inst >> 4) & 0xf;
807 int b = inst & 0xf;
808 if (record_full_arch_list_add_reg (regcache, a)
809 || record_full_arch_list_add_reg (regcache, b))
810 return -1;
811 }
812 break;
813 case 0x08: /* lda.l */
814 {
815 int reg = (inst >> 4) & 0xf;
816 if (record_full_arch_list_add_reg (regcache, reg))
817 return -1;
818 }
819 break;
820 case 0x09: /* sta.l */
821 {
822 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf,
823 4, byte_order);
824 if (record_full_arch_list_add_mem (tmpu32, 4))
825 return -1;
826 }
827 break;
828 case 0x0a: /* ld.l (register indirect) */
829 {
830 int reg = (inst >> 4) & 0xf;
831 if (record_full_arch_list_add_reg (regcache, reg))
832 return -1;
833 }
834 break;
835 case 0x0b: /* st.l */
836 {
837 int reg = (inst >> 4) & 0xf;
838 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
839 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
840 4, byte_order);
841 if (record_full_arch_list_add_mem (tmpu32, 4))
842 return -1;
843 }
844 break;
845 case 0x0c: /* ldo.l */
846 {
847 int reg = (inst >> 4) & 0xf;
848 if (record_full_arch_list_add_reg (regcache, reg))
849 return -1;
850 }
851 break;
852 case 0x0d: /* sto.l */
853 {
854 int reg = (inst >> 4) & 0xf;
855 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
856 byte_order)) << 16 ) >> 16;
857 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
858 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
859 4, byte_order);
860 tmpu32 += offset;
861 if (record_full_arch_list_add_mem (tmpu32, 4))
862 return -1;
863 }
864 break;
865 case 0x0e: /* cmp */
866 {
867 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
868 return -1;
869 }
870 break;
871 case 0x0f: /* nop */
872 {
873 /* Do nothing. */
874 break;
875 }
876 case 0x10: /* sex.b */
877 case 0x11: /* sex.s */
878 case 0x12: /* zex.b */
879 case 0x13: /* zex.s */
880 case 0x14: /* umul.x */
881 case 0x15: /* mul.x */
882 {
883 int reg = (inst >> 4) & 0xf;
884 if (record_full_arch_list_add_reg (regcache, reg))
885 return -1;
886 }
887 break;
888 case 0x16:
889 case 0x17:
890 case 0x18:
891 {
892 /* Do nothing. */
893 break;
894 }
895 case 0x19: /* jsr */
896 {
897 regcache_raw_read (regcache,
898 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
899 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
900 4, byte_order);
901 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
902 || (record_full_arch_list_add_reg (regcache,
903 MOXIE_SP_REGNUM))
904 || record_full_arch_list_add_mem (tmpu32 - 12, 12))
905 return -1;
906 }
907 break;
908 case 0x1a: /* jmpa */
909 {
910 /* Do nothing. */
911 }
912 break;
913 case 0x1b: /* ldi.b (immediate) */
914 case 0x1c: /* ld.b (register indirect) */
915 case 0x1d: /* lda.b */
916 {
917 int reg = (inst >> 4) & 0xf;
918 if (record_full_arch_list_add_reg (regcache, reg))
919 return -1;
920 }
921 break;
922 case 0x1e: /* st.b */
923 {
924 int reg = (inst >> 4) & 0xf;
925 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
926 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
927 4, byte_order);
928 if (record_full_arch_list_add_mem (tmpu32, 1))
929 return -1;
930 }
931 break;
932 case 0x1f: /* sta.b */
933 {
934 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
935 if (record_full_arch_list_add_mem (tmpu32, 1))
936 return -1;
937 }
938 break;
939 case 0x20: /* ldi.s (immediate) */
940 case 0x21: /* ld.s (register indirect) */
941 case 0x22: /* lda.s */
942 {
943 int reg = (inst >> 4) & 0xf;
944 if (record_full_arch_list_add_reg (regcache, reg))
945 return -1;
946 }
947 break;
948 case 0x23: /* st.s */
949 {
950 int reg = (inst >> 4) & 0xf;
951 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
952 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
953 4, byte_order);
954 if (record_full_arch_list_add_mem (tmpu32, 2))
955 return -1;
956 }
957 break;
958 case 0x24: /* sta.s */
959 {
960 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
961 if (record_full_arch_list_add_mem (tmpu32, 2))
962 return -1;
963 }
964 break;
965 case 0x25: /* jmp */
966 {
967 /* Do nothing. */
968 }
969 break;
970 case 0x26: /* and */
971 case 0x27: /* lshr */
972 case 0x28: /* ashl */
973 case 0x29: /* sub */
974 case 0x2a: /* neg */
975 case 0x2b: /* or */
976 case 0x2c: /* not */
977 case 0x2d: /* ashr */
978 case 0x2e: /* xor */
979 case 0x2f: /* mul */
980 {
981 int reg = (inst >> 4) & 0xf;
982 if (record_full_arch_list_add_reg (regcache, reg))
983 return -1;
984 }
985 break;
986 case 0x30: /* swi */
987 {
988 /* We currently implement support for libgloss'
989 system calls. */
990
991 int inum = moxie_process_readu (addr+2, buf, 4, byte_order);
992
993 switch (inum)
994 {
995 case 0x1: /* SYS_exit */
996 {
997 /* Do nothing. */
998 }
999 break;
1000 case 0x2: /* SYS_open */
1001 {
1002 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1003 return -1;
1004 }
1005 break;
1006 case 0x4: /* SYS_read */
1007 {
1008 uint32_t length, ptr;
1009
1010 /* Read buffer pointer is in $r1. */
1011 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr);
1012 ptr = extract_unsigned_integer ((gdb_byte *) & ptr,
1013 4, byte_order);
1014
1015 /* String length is at 0x12($fp). */
1016 regcache_raw_read (regcache,
1017 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
1018 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1019 4, byte_order);
1020 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);
1021
1022 if (record_full_arch_list_add_mem (ptr, length))
1023 return -1;
1024 }
1025 break;
1026 case 0x5: /* SYS_write */
1027 {
1028 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
1029 return -1;
1030 }
1031 break;
1032 default:
1033 break;
1034 }
1035 }
1036 break;
1037 case 0x31: /* div.l */
1038 case 0x32: /* udiv.l */
1039 case 0x33: /* mod.l */
1040 case 0x34: /* umod.l */
1041 {
1042 int reg = (inst >> 4) & 0xf;
1043 if (record_full_arch_list_add_reg (regcache, reg))
1044 return -1;
1045 }
1046 break;
1047 case 0x35: /* brk */
1048 /* Do nothing. */
1049 break;
1050 case 0x36: /* ldo.b */
1051 {
1052 int reg = (inst >> 4) & 0xf;
1053 if (record_full_arch_list_add_reg (regcache, reg))
1054 return -1;
1055 }
1056 break;
1057 case 0x37: /* sto.b */
1058 {
1059 int reg = (inst >> 4) & 0xf;
1060 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1061 byte_order)) << 16 ) >> 16;
1062 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1063 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1064 4, byte_order);
1065 tmpu32 += offset;
1066 if (record_full_arch_list_add_mem (tmpu32, 1))
1067 return -1;
1068 }
1069 break;
1070 case 0x38: /* ldo.s */
1071 {
1072 int reg = (inst >> 4) & 0xf;
1073 if (record_full_arch_list_add_reg (regcache, reg))
1074 return -1;
1075 }
1076 break;
1077 case 0x39: /* sto.s */
1078 {
1079 int reg = (inst >> 4) & 0xf;
1080 uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
1081 byte_order)) << 16 ) >> 16;
1082 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32);
1083 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32,
1084 4, byte_order);
1085 tmpu32 += offset;
1086 if (record_full_arch_list_add_mem (tmpu32, 2))
1087 return -1;
1088 }
1089 break;
1090 default:
1091 /* Do nothing. */
1092 break;
1093 }
1094 }
1095
1096 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
1097 return -1;
1098 if (record_full_arch_list_add_end ())
1099 return -1;
1100 return 0;
1101 }
1102
1103 /* Allocate and initialize the moxie gdbarch object. */
1104
1105 static struct gdbarch *
1106 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1107 {
1108 struct gdbarch *gdbarch;
1109 struct gdbarch_tdep *tdep;
1110
1111 /* If there is already a candidate, use it. */
1112 arches = gdbarch_list_lookup_by_info (arches, &info);
1113 if (arches != NULL)
1114 return arches->gdbarch;
1115
1116 /* Allocate space for the new architecture. */
1117 tdep = XNEW (struct gdbarch_tdep);
1118 gdbarch = gdbarch_alloc (&info, tdep);
1119
1120 set_gdbarch_read_pc (gdbarch, moxie_read_pc);
1121 set_gdbarch_write_pc (gdbarch, moxie_write_pc);
1122 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
1123
1124 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
1125 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
1126 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
1127 set_gdbarch_register_name (gdbarch, moxie_register_name);
1128 set_gdbarch_register_type (gdbarch, moxie_register_type);
1129
1130 set_gdbarch_return_value (gdbarch, moxie_return_value);
1131
1132 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
1133 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1134 set_gdbarch_breakpoint_kind_from_pc (gdbarch,
1135 moxie_breakpoint::kind_from_pc);
1136 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1137 moxie_breakpoint::bp_from_kind);
1138 set_gdbarch_frame_align (gdbarch, moxie_frame_align);
1139
1140 frame_base_set_default (gdbarch, &moxie_frame_base);
1141
1142 /* Methods for saving / extracting a dummy frame's ID. The ID's
1143 stack address must match the SP value returned by
1144 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
1145 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
1146
1147 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
1148
1149 set_gdbarch_print_insn (gdbarch, print_insn_moxie);
1150
1151 /* Hook in ABI-specific overrides, if they have been registered. */
1152 gdbarch_init_osabi (info, gdbarch);
1153
1154 /* Hook in the default unwinders. */
1155 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
1156
1157 /* Single stepping. */
1158 set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
1159
1160 /* Support simple overlay manager. */
1161 set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
1162
1163 /* Support reverse debugging. */
1164 set_gdbarch_process_record (gdbarch, moxie_process_record);
1165
1166 return gdbarch;
1167 }
1168
1169 /* Register this machine's init routine. */
1170
1171 void
1172 _initialize_moxie_tdep (void)
1173 {
1174 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
1175 }