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