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