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