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