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