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