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