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