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