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