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