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