OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [xstormy16-tdep.c] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Target-dependent code for the Sanyo Xstormy16a (LC590000) processor.
2
 
3
   Copyright 2001, 2002 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "value.h"
24
#include "inferior.h"
25
#include "symfile.h"
26
#include "arch-utils.h"
27
#include "regcache.h"
28
#include "gdbcore.h"
29
#include "objfiles.h"
30
 
31
struct gdbarch_tdep
32
{
33
  /* gdbarch target dependent data here. Currently unused for Xstormy16. */
34
};
35
 
36
/* Extra info which is saved in each frame_info. */
37
struct frame_extra_info
38
{
39
  int framesize;
40
  int frameless_p;
41
};
42
 
43
enum gdb_regnum
44
{
45
  /* Xstormy16 has 16 general purpose registers (R0-R15) plus PC.
46
     Functions will return their values in register R2-R7 as they fit.
47
     Otherwise a hidden pointer to an big enough area is given as argument
48
     to the function in r2. Further arguments are beginning in r3 then.
49
     R13 is used as frame pointer when GCC compiles w/o optimization
50
     R14 is used as "PSW", displaying the CPU status.
51
     R15 is used implicitely as stack pointer. */
52
  E_R0_REGNUM,
53
  E_R1_REGNUM,
54
  E_R2_REGNUM, E_1ST_ARG_REGNUM = E_R2_REGNUM, E_PTR_RET_REGNUM = E_R2_REGNUM,
55
  E_R3_REGNUM,
56
  E_R4_REGNUM,
57
  E_R5_REGNUM,
58
  E_R6_REGNUM,
59
  E_R7_REGNUM, E_LST_ARG_REGNUM = E_R7_REGNUM,
60
  E_R8_REGNUM,
61
  E_R9_REGNUM,
62
  E_R10_REGNUM,
63
  E_R11_REGNUM,
64
  E_R12_REGNUM,
65
  E_R13_REGNUM, E_FP_REGNUM = E_R13_REGNUM,
66
  E_R14_REGNUM, E_PSW_REGNUM = E_R14_REGNUM,
67
  E_R15_REGNUM, E_SP_REGNUM = E_R15_REGNUM,
68
  E_PC_REGNUM,
69
  E_NUM_REGS
70
};
71
 
72
/* Size of instructions, registers, etc. */
73
enum
74
{
75
  xstormy16_inst_size = 2,
76
  xstormy16_reg_size = 2,
77
  xstormy16_pc_size = 4
78
};
79
 
80
/* Size of return datatype which fits into the remaining return registers. */
81
#define E_MAX_RETTYPE_SIZE(regnum)      ((E_LST_ARG_REGNUM - (regnum) + 1) \
82
                                        * xstormy16_reg_size)
83
 
84
/* Size of return datatype which fits into all return registers. */
85
enum
86
{
87
  E_MAX_RETTYPE_SIZE_IN_REGS = E_MAX_RETTYPE_SIZE (E_R2_REGNUM)
88
};
89
 
90
 
91
/* Size of all registers as a whole. */
92
enum
93
{
94
  E_ALL_REGS_SIZE = (E_NUM_REGS - 1) * xstormy16_reg_size + xstormy16_pc_size
95
};
96
 
97
/* Function: xstormy16_register_name
98
   Returns the name of the standard Xstormy16 register N. */
99
 
100
static const char *
101
xstormy16_register_name (int regnum)
102
{
103
  static char *register_names[] = {
104
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105
    "r8", "r9", "r10", "r11", "r12", "r13",
106
    "psw", "sp", "pc"
107
  };
108
 
109
  if (regnum < 0 ||
110
      regnum >= sizeof (register_names) / sizeof (register_names[0]))
111
    internal_error (__FILE__, __LINE__,
112
                    "xstormy16_register_name: illegal register number %d",
113
                    regnum);
114
  else
115
    return register_names[regnum];
116
 
117
}
118
 
119
/* Function: xstormy16_register_byte
120
   Returns the byte position in the register cache for register N. */
121
 
122
static int
123
xstormy16_register_byte (int regnum)
124
{
125
  if (regnum < 0 || regnum >= E_NUM_REGS)
126
    internal_error (__FILE__, __LINE__,
127
                    "xstormy16_register_byte: illegal register number %d",
128
                    regnum);
129
  else
130
    /* All registers occupy 2 bytes in the regcache except for PC
131
       which is the last one. Therefore the byte position is still
132
       simply a multiple of 2. */
133
    return regnum * xstormy16_reg_size;
134
}
135
 
136
/* Function: xstormy16_register_raw_size
137
   Returns the number of bytes occupied by the register on the target. */
138
 
139
static int
140
xstormy16_register_raw_size (int regnum)
141
{
142
  if (regnum < 0 || regnum >= E_NUM_REGS)
143
    internal_error (__FILE__, __LINE__,
144
                    "xstormy16_register_raw_size: illegal register number %d",
145
                    regnum);
146
  /* Only the PC has 4 Byte, all other registers 2 Byte. */
147
  else if (regnum == E_PC_REGNUM)
148
    return xstormy16_pc_size;
149
  else
150
    return xstormy16_reg_size;
151
}
152
 
153
/* Function: xstormy16_register_virtual_size
154
   Returns the number of bytes occupied by the register as represented
155
   internally by gdb. */
156
 
157
static int
158
xstormy16_register_virtual_size (int regnum)
159
{
160
  return xstormy16_register_raw_size (regnum);
161
}
162
 
163
/* Function: xstormy16_reg_virtual_type
164
   Returns the default type for register N. */
165
 
166
static struct type *
167
xstormy16_reg_virtual_type (int regnum)
168
{
169
  if (regnum < 0 || regnum >= E_NUM_REGS)
170
    internal_error (__FILE__, __LINE__,
171
                    "xstormy16_register_virtual_type: illegal register number %d",
172
                    regnum);
173
  else if (regnum == E_PC_REGNUM)
174
    return builtin_type_uint32;
175
  else
176
    return builtin_type_uint16;
177
}
178
 
179
/* Function: xstormy16_get_saved_register
180
   Find a register's saved value on the call stack. */
181
 
182
static void
183
xstormy16_get_saved_register (char *raw_buffer,
184
                              int *optimized,
185
                              CORE_ADDR *addrp,
186
                              struct frame_info *fi,
187
                              int regnum, enum lval_type *lval)
188
{
189
  generic_get_saved_register (raw_buffer, optimized, addrp, fi, regnum, lval);
190
}
191
 
192
/* Function: xstormy16_type_is_scalar
193
   Makes the decision if a given type is a scalar types.  Scalar
194
   types are returned in the registers r2-r7 as they fit. */
195
 
196
static int
197
xstormy16_type_is_scalar (struct type *t)
198
{
199
  return (TYPE_CODE(t) != TYPE_CODE_STRUCT
200
          && TYPE_CODE(t) != TYPE_CODE_UNION
201
          && TYPE_CODE(t) != TYPE_CODE_ARRAY);
202
}
203
 
204
/* Function: xstormy16_extract_return_value
205
   Copy the function's return value into VALBUF.
206
   This function is called only in the context of "target function calls",
207
   ie. when the debugger forces a function to be called in the child, and
208
   when the debugger forces a function to return prematurely via the
209
   "return" command. */
210
 
211
static void
212
xstormy16_extract_return_value (struct type *type, char *regbuf, char *valbuf)
213
{
214
  CORE_ADDR return_buffer;
215
  int offset = 0;
216
 
217
  if (xstormy16_type_is_scalar (type)
218
      && TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
219
    {
220
      /* Scalar return values of <= 12 bytes are returned in
221
         E_1ST_ARG_REGNUM to E_LST_ARG_REGNUM. */
222
      memcpy (valbuf,
223
              &regbuf[REGISTER_BYTE (E_1ST_ARG_REGNUM)] + offset,
224
              TYPE_LENGTH (type));
225
    }
226
  else
227
    {
228
      /* Aggregates and return values > 12 bytes are returned in memory,
229
         pointed to by R2. */
230
      return_buffer =
231
        extract_address (regbuf + REGISTER_BYTE (E_PTR_RET_REGNUM),
232
                         REGISTER_RAW_SIZE (E_PTR_RET_REGNUM));
233
 
234
      read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
235
    }
236
}
237
 
238
/* Function: xstormy16_push_arguments
239
   Setup the function arguments for GDB to call a function in the inferior.
240
   Called only in the context of a target function call from the debugger.
241
   Returns the value of the SP register after the args are pushed.
242
*/
243
 
244
static CORE_ADDR
245
xstormy16_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
246
                          int struct_return, CORE_ADDR struct_addr)
247
{
248
  CORE_ADDR stack_dest = sp;
249
  int argreg = E_1ST_ARG_REGNUM;
250
  int i, j;
251
  int typelen, slacklen;
252
  char *val;
253
 
254
  /* If struct_return is true, then the struct return address will
255
     consume one argument-passing register.  */
256
  if (struct_return)
257
    argreg++;
258
 
259
  /* Arguments are passed in R2-R7 as they fit. If an argument doesn't
260
     fit in the remaining registers we're switching over to the stack.
261
     No argument is put on stack partially and as soon as we switched
262
     over to stack no further argument is put in a register even if it
263
     would fit in the remaining unused registers. */
264
  for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++)
265
    {
266
      typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
267
      if (typelen > E_MAX_RETTYPE_SIZE (argreg))
268
        break;
269
 
270
      /* Put argument into registers wordwise. */
271
      val = VALUE_CONTENTS (args[i]);
272
      for (j = 0; j < typelen; j += xstormy16_reg_size)
273
        write_register (argreg++,
274
                        extract_unsigned_integer (val + j,
275
                                                  typelen - j ==
276
                                                  1 ? 1 :
277
                                                  xstormy16_reg_size));
278
    }
279
 
280
  /* Align SP */
281
  if (stack_dest & 1)
282
    ++stack_dest;
283
 
284
  /* Loop backwards through remaining arguments and push them on the stack,
285
     wordaligned. */
286
  for (j = nargs - 1; j >= i; j--)
287
    {
288
      typelen = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[j]));
289
      slacklen = typelen & 1;
290
      val = alloca (typelen + slacklen);
291
      memcpy (val, VALUE_CONTENTS (args[j]), typelen);
292
      memset (val + typelen, 0, slacklen);
293
 
294
      /* Now write this data to the stack. The stack grows upwards. */
295
      write_memory (stack_dest, val, typelen + slacklen);
296
      stack_dest += typelen + slacklen;
297
    }
298
 
299
  /* And that should do it.  Return the new stack pointer. */
300
  return stack_dest;
301
}
302
 
303
/* Function: xstormy16_push_return_address (pc)
304
   Setup the return address for GDB to call a function in the inferior.
305
   Called only in the context of a target function call from the debugger.
306
   Returns the value of the SP register when the operation is finished
307
   (which may or may not be the same as before).
308
*/
309
 
310
CORE_ADDR
311
xstormy16_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
312
{
313
  unsigned char buf[xstormy16_pc_size];
314
 
315
  store_unsigned_integer (buf, xstormy16_pc_size, CALL_DUMMY_ADDRESS ());
316
  write_memory (sp, buf, xstormy16_pc_size);
317
  return sp + xstormy16_pc_size;
318
}
319
 
320
/* Function: xstormy16_pop_frame
321
   Destroy the innermost (Top-Of-Stack) stack frame, restoring the
322
   machine state that was in effect before the frame was created.
323
   Used in the contexts of the "return" command, and of
324
   target function calls from the debugger.
325
*/
326
 
327
static void
328
xstormy16_pop_frame (void)
329
{
330
  struct frame_info *fi = get_current_frame ();
331
  int i;
332
 
333
  if (fi == NULL)
334
    return;                     /* paranoia */
335
 
336
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
337
    {
338
      generic_pop_dummy_frame ();
339
    }
340
  else
341
    {
342
      /* Restore the saved regs. */
343
      for (i = 0; i < NUM_REGS; i++)
344
        if (fi->saved_regs[i])
345
          {
346
            if (i == SP_REGNUM)
347
              write_register (i, fi->saved_regs[i]);
348
            else if (i == E_PC_REGNUM)
349
              write_register (i, read_memory_integer (fi->saved_regs[i],
350
                                                      xstormy16_pc_size));
351
            else
352
              write_register (i, read_memory_integer (fi->saved_regs[i],
353
                                                      xstormy16_reg_size));
354
          }
355
      /* Restore the PC */
356
      write_register (PC_REGNUM, FRAME_SAVED_PC (fi));
357
      flush_cached_frames ();
358
    }
359
  return;
360
}
361
 
362
/* Function: xstormy16_store_struct_return
363
   Copy the (struct) function return value to its destined location.
364
   Called only in the context of a target function call from the debugger.
365
*/
366
 
367
static void
368
xstormy16_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
369
{
370
  write_register (E_PTR_RET_REGNUM, addr);
371
}
372
 
373
/* Function: xstormy16_store_return_value
374
   Copy the function return value from VALBUF into the
375
   proper location for a function return.
376
   Called only in the context of the "return" command.
377
*/
378
 
379
static void
380
xstormy16_store_return_value (struct type *type, char *valbuf)
381
{
382
  CORE_ADDR return_buffer;
383
  char buf[xstormy16_reg_size];
384
 
385
  if (xstormy16_type_is_scalar (type) && TYPE_LENGTH (type) == 1)
386
    {
387
      /* Add leading zeros to the value. */
388
      memset (buf, 0, xstormy16_reg_size);
389
      memcpy (buf, valbuf, 1);
390
      write_register_gen (E_1ST_ARG_REGNUM, buf);
391
    }
392
  else if (xstormy16_type_is_scalar (type) &&
393
           TYPE_LENGTH (type) <= E_MAX_RETTYPE_SIZE_IN_REGS)
394
    write_register_bytes (REGISTER_BYTE (E_1ST_ARG_REGNUM),
395
                          valbuf, TYPE_LENGTH (type));
396
  else
397
    {
398
      return_buffer = read_register (E_PTR_RET_REGNUM);
399
      write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
400
    }
401
}
402
 
403
/* Function: xstormy16_extract_struct_value_address
404
   Returns the address in which a function should return a struct value.
405
   Used in the contexts of the "return" command, and of
406
   target function calls from the debugger.
407
*/
408
 
409
static CORE_ADDR
410
xstormy16_extract_struct_value_address (char *regbuf)
411
{
412
  return extract_address (regbuf +
413
                          xstormy16_register_byte (E_PTR_RET_REGNUM),
414
                          xstormy16_reg_size);
415
}
416
 
417
/* Function: xstormy16_use_struct_convention
418
   Returns non-zero if the given struct type will be returned using
419
   a special convention, rather than the normal function return method.
420
   7sed in the contexts of the "return" command, and of
421
   target function calls from the debugger.
422
*/
423
 
424
static int
425
xstormy16_use_struct_convention (int gcc_p, struct type *type)
426
{
427
  return !xstormy16_type_is_scalar (type)
428
    || TYPE_LENGTH (type) > E_MAX_RETTYPE_SIZE_IN_REGS;
429
}
430
 
431
/* Function: frame_saved_register
432
   Returns the value that regnum had in frame fi
433
   (saved in fi or in one of its children).
434
*/
435
 
436
static CORE_ADDR
437
xstormy16_frame_saved_register (struct frame_info *fi, int regnum)
438
{
439
  int size = xstormy16_register_raw_size (regnum);
440
  char *buf = (char *) alloca (size);
441
 
442
  generic_get_saved_register (buf, NULL, NULL, fi, regnum, NULL);
443
  return (CORE_ADDR) extract_unsigned_integer (buf, size);
444
}
445
 
446
/* Function: xstormy16_scan_prologue
447
   Decode the instructions within the given address range.
448
   Decide when we must have reached the end of the function prologue.
449
   If a frame_info pointer is provided, fill in its saved_regs etc.
450
 
451
   Returns the address of the first instruction after the prologue.
452
*/
453
 
454
static CORE_ADDR
455
xstormy16_scan_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
456
                         struct frame_info *fi, int *frameless)
457
{
458
  CORE_ADDR sp = 0, fp = 0;
459
  CORE_ADDR next_addr;
460
  ULONGEST inst, inst2;
461
  LONGEST offset;
462
  int regnum;
463
 
464
  if (frameless)
465
    *frameless = 1;
466
  if (fi)
467
    {
468
      /* In a call dummy, don't touch the frame. */
469
      if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
470
        return start_addr;
471
 
472
      /* Grab the frame-relative values of SP and FP, needed below.
473
         The frame_saved_register function will find them on the
474
         stack or in the registers as appropriate. */
475
      sp = xstormy16_frame_saved_register (fi, E_SP_REGNUM);
476
      fp = xstormy16_frame_saved_register (fi, E_FP_REGNUM);
477
 
478
      /* Initialize framesize with size of PC put on stack by CALLF inst. */
479
      fi->extra_info->framesize = xstormy16_pc_size;
480
    }
481
  for (next_addr = start_addr;
482
       next_addr < end_addr; next_addr += xstormy16_inst_size)
483
    {
484
      inst = read_memory_unsigned_integer (next_addr, xstormy16_inst_size);
485
      inst2 = read_memory_unsigned_integer (next_addr + xstormy16_inst_size,
486
                                            xstormy16_inst_size);
487
 
488
      if (inst >= 0x0082 && inst <= 0x008d)     /* push r2 .. push r13 */
489
        {
490
          if (fi)
491
            {
492
              regnum = inst & 0x000f;
493
              fi->saved_regs[regnum] = fi->extra_info->framesize;
494
              fi->extra_info->framesize += xstormy16_reg_size;
495
            }
496
        }
497
 
498
      /* optional stack allocation for args and local vars <= 4 byte */
499
      else if (inst == 0x301f || inst == 0x303f)        /* inc r15, #0x1/#0x3 */
500
        {
501
          if (fi)               /* Record the frame size. */
502
            fi->extra_info->framesize += ((inst & 0x0030) >> 4) + 1;
503
        }
504
 
505
      /* optional stack allocation for args and local vars > 4 && < 16 byte */
506
      else if ((inst & 0xff0f) == 0x510f)       /* 51Hf   add r15, #0xH */
507
        {
508
          if (fi)               /* Record the frame size. */
509
            fi->extra_info->framesize += (inst & 0x00f0) >> 4;
510
        }
511
 
512
      /* optional stack allocation for args and local vars >= 16 byte */
513
      else if (inst == 0x314f && inst2 >= 0x0010)       /* 314f HHHH  add r15, #0xH */
514
        {
515
          if (fi)               /* Record the frame size. */
516
            fi->extra_info->framesize += inst2;
517
          next_addr += xstormy16_inst_size;
518
        }
519
 
520
      else if (inst == 0x46fd)  /* mov r13, r15 */
521
        {
522
          if (fi)               /* Record that the frame pointer is in use. */
523
            fi->extra_info->frameless_p = 0;
524
          if (frameless)
525
            *frameless = 0;
526
        }
527
 
528
      /* optional copying of args in r2-r7 to r10-r13 */
529
      /* Probably only in optimized case but legal action for prologue */
530
      else if ((inst & 0xff00) == 0x4600        /* 46SD   mov rD, rS */
531
               && (inst & 0x00f0) >= 0x0020 && (inst & 0x00f0) <= 0x0070
532
               && (inst & 0x000f) >= 0x00a0 && (inst & 0x000f) <= 0x000d)
533
        ;
534
 
535
      /* optional copying of args in r2-r7 to stack */
536
      /* 72DS HHHH   mov.b (rD, 0xHHHH), r(S-8) (bit3 always 1, bit2-0 = reg) */
537
      /* 73DS HHHH   mov.w (rD, 0xHHHH), r(S-8) */
538
      else if ((inst & 0xfed8) == 0x72d8 && (inst & 0x0007) >= 2)
539
        {
540
          if (fi)
541
            {
542
              regnum = inst & 0x0007;
543
              /* Only 12 of 16 bits of the argument are used for the
544
                 signed offset. */
545
              offset = (LONGEST) (inst2 & 0x0fff);
546
              if (offset & 0x0800)
547
                offset -= 0x1000;
548
 
549
              fi->saved_regs[regnum] = fi->extra_info->framesize + offset;
550
            }
551
          next_addr += xstormy16_inst_size;
552
        }
553
 
554
#if 0
555
      /* 2001-08-10: Not part of the prologue anymore due to change in
556
         ABI. r8 and r9 are not used for argument passing anymore. */
557
 
558
      /* optional copying of r8, r9 to stack */
559
      /* 46S7; 73Df HHHH   mov.w r7,rS; mov.w (rD, 0xHHHH), r7 D=8,9; S=13,15 */
560
      /* 46S7; 72df HHHH   mov.w r7,rS; mov.b (rD, 0xHHHH), r7 D=8,9; S=13,15 */
561
      else if ((inst & 0xffef) == 0x4687 && (inst2 & 0xfedf) == 0x72df)
562
        {
563
          next_addr += xstormy16_inst_size;
564
          if (fi)
565
            {
566
              regnum = (inst & 0x00f0) >> 4;
567
              inst = inst2;
568
              inst2 = read_memory_unsigned_integer (next_addr
569
                                                    + xstormy16_inst_size,
570
                                                    xstormy16_inst_size);
571
              /* Only 12 of 16 bits of the argument are used for the
572
                 signed offset. */
573
              offset = (LONGEST) (inst2 & 0x0fff);
574
              if (offset & 0x0800)
575
                offset -= 0x1000;
576
 
577
              fi->saved_regs[regnum] = fi->extra_info->framesize + offset;
578
            }
579
          next_addr += xstormy16_inst_size;
580
        }
581
#endif
582
 
583
      else                      /* Not a prologue instruction. */
584
        break;
585
    }
586
 
587
  if (fi)
588
    {
589
      /* Special handling for the "saved" address of the SP:
590
         The SP is of course never saved on the stack at all, so
591
         by convention what we put here is simply the previous
592
         _value_ of the SP (as opposed to an address where the
593
         previous value would have been pushed).  */
594
      if (fi->extra_info->frameless_p)
595
        {
596
          fi->saved_regs[E_SP_REGNUM] = sp - fi->extra_info->framesize;
597
          fi->frame = sp;
598
        }
599
      else
600
        {
601
          fi->saved_regs[E_SP_REGNUM] = fp - fi->extra_info->framesize;
602
          fi->frame = fp;
603
        }
604
 
605
      /* So far only offsets to the beginning of the frame are
606
         saved in the saved_regs. Now we now the relation between
607
         sp, fp and framesize. We know the beginning of the frame
608
         so we can translate the register offsets to real addresses. */
609
      for (regnum = 0; regnum < E_SP_REGNUM; ++regnum)
610
        if (fi->saved_regs[regnum])
611
          fi->saved_regs[regnum] += fi->saved_regs[E_SP_REGNUM];
612
 
613
      /* Save address of PC on stack. */
614
      fi->saved_regs[E_PC_REGNUM] = fi->saved_regs[E_SP_REGNUM];
615
    }
616
 
617
  return next_addr;
618
}
619
 
620
/* Function: xstormy16_skip_prologue
621
   If the input address is in a function prologue,
622
   returns the address of the end of the prologue;
623
   else returns the input address.
624
 
625
   Note: the input address is likely to be the function start,
626
   since this function is mainly used for advancing a breakpoint
627
   to the first line, or stepping to the first line when we have
628
   stepped into a function call.  */
629
 
630
static CORE_ADDR
631
xstormy16_skip_prologue (CORE_ADDR pc)
632
{
633
  CORE_ADDR func_addr = 0, func_end = 0;
634
  char *func_name;
635
 
636
  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
637
    {
638
      struct symtab_and_line sal;
639
      struct symbol *sym;
640
 
641
      /* Don't trust line number debug info in frameless functions. */
642
      int frameless = 1;
643
      CORE_ADDR plg_end = xstormy16_scan_prologue (func_addr, func_end,
644
                                                   NULL, &frameless);
645
      if (frameless)
646
        return plg_end;
647
 
648
      /* Found a function.  */
649
      sym = lookup_symbol (func_name, NULL, VAR_NAMESPACE, NULL, NULL);
650
      /* Don't use line number debug info for assembly source files. */
651
      if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
652
        {
653
          sal = find_pc_line (func_addr, 0);
654
          if (sal.end && sal.end < func_end)
655
            {
656
              /* Found a line number, use it as end of prologue.  */
657
              return sal.end;
658
            }
659
        }
660
      /* No useable line symbol.  Use result of prologue parsing method. */
661
      return plg_end;
662
    }
663
 
664
  /* No function symbol -- just return the PC. */
665
 
666
  return (CORE_ADDR) pc;
667
}
668
 
669
/* The epilogue is defined here as the area at the end of a function,
670
   either on the `ret' instruction itself or after an instruction which
671
   destroys the function's stack frame. */
672
static int
673
xstormy16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
674
{
675
  CORE_ADDR addr, func_addr = 0, func_end = 0;
676
 
677
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
678
    {
679
      ULONGEST inst, inst2;
680
      CORE_ADDR addr = func_end - xstormy16_inst_size;
681
 
682
      /* The Xstormy16 epilogue is max. 14 bytes long. */
683
      if (pc < func_end - 7 * xstormy16_inst_size)
684
        return 0;
685
 
686
      /* Check if we're on a `ret' instruction.  Otherwise it's
687
         too dangerous to proceed. */
688
      inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
689
      if (inst != 0x0003)
690
        return 0;
691
 
692
      while ((addr -= xstormy16_inst_size) >= func_addr)
693
        {
694
          inst = read_memory_unsigned_integer (addr, xstormy16_inst_size);
695
          if (inst >= 0x009a && inst <= 0x009d) /* pop r10...r13 */
696
            continue;
697
          if (inst == 0x305f || inst == 0x307f) /* dec r15, #0x1/#0x3 */
698
            break;
699
          inst2 = read_memory_unsigned_integer (addr - xstormy16_inst_size,
700
                                                xstormy16_inst_size);
701
          if (inst2 == 0x314f && inst >= 0x8000)        /* add r15, neg. value */
702
            {
703
              addr -= xstormy16_inst_size;
704
              break;
705
            }
706
          return 0;
707
        }
708
      if (pc > addr)
709
        return 1;
710
    }
711
  return 0;
712
}
713
 
714
/* Function: xstormy16_frame_init_saved_regs
715
   Set up the 'saved_regs' array.
716
   This is a data structure containing the addresses on the stack
717
   where each register has been saved, for each stack frame.
718
   Registers that have not been saved will have zero here.
719
   The stack register is special: rather than the address where the
720
   stack register has been saved, saved_regs[SP_REGNUM] will have the
721
   actual value of the previous frame's stack register.
722
 
723
   This function may be called in any context where the saved register
724
   values may be needed (backtrace, frame_info, get_saved_register).
725
   On many targets, it is called directly by init_extra_frame_info,
726
   in part because the information may be needed immediately by
727
   frame_chain.
728
*/
729
 
730
static void
731
xstormy16_frame_init_saved_regs (struct frame_info *fi)
732
{
733
  CORE_ADDR func_addr, func_end;
734
 
735
  if (!fi->saved_regs)
736
    {
737
      frame_saved_regs_zalloc (fi);
738
 
739
      /* Find the beginning of this function, so we can analyze its
740
         prologue. */
741
      if (find_pc_partial_function (fi->pc, NULL, &func_addr, &func_end))
742
        xstormy16_scan_prologue (func_addr, fi->pc, fi, NULL);
743
      /* Else we're out of luck (can't debug completely stripped code).
744
         FIXME. */
745
    }
746
}
747
 
748
/* Function: xstormy16_frame_saved_pc
749
   Returns the return address for the selected frame.
750
   Called by frame_info, frame_chain_valid, and sometimes by
751
   get_prev_frame.
752
*/
753
 
754
static CORE_ADDR
755
xstormy16_frame_saved_pc (struct frame_info *fi)
756
{
757
  CORE_ADDR saved_pc;
758
 
759
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
760
    {
761
      saved_pc = generic_read_register_dummy (fi->pc, fi->frame, E_PC_REGNUM);
762
    }
763
  else
764
    {
765
      saved_pc = read_memory_unsigned_integer (fi->saved_regs[E_PC_REGNUM],
766
                                               xstormy16_pc_size);
767
    }
768
 
769
  return saved_pc;
770
}
771
 
772
/* Function: xstormy16_init_extra_frame_info
773
   This is the constructor function for the frame_info struct,
774
   called whenever a new frame_info is created (from create_new_frame,
775
   and from get_prev_frame).
776
*/
777
 
778
static void
779
xstormy16_init_extra_frame_info (int fromleaf, struct frame_info *fi)
780
{
781
  if (!fi->extra_info)
782
    {
783
      fi->extra_info = (struct frame_extra_info *)
784
        frame_obstack_alloc (sizeof (struct frame_extra_info));
785
      fi->extra_info->framesize = 0;
786
      fi->extra_info->frameless_p = 1;  /* Default frameless, detect framed */
787
 
788
      /* By default, the fi->frame is set to the value of the FP reg by gdb.
789
         This may not always be right; we may be in a frameless function,
790
         or we may be in the prologue, before the FP has been set up.
791
         Unfortunately, we can't make this determination without first
792
         calling scan_prologue, and we can't do that unles we know the
793
         fi->pc.  */
794
 
795
      if (!fi->pc)
796
        {
797
          /* Sometimes we are called from get_prev_frame without
798
             the PC being set up first.  Long history, don't ask.
799
             Fortunately this will never happen from the outermost
800
             frame, so we should be able to get the saved pc from
801
             the next frame. */
802
          if (fi->next)
803
            fi->pc = xstormy16_frame_saved_pc (fi->next);
804
        }
805
 
806
      /* Take care of the saved_regs right here (non-lazy). */
807
      xstormy16_frame_init_saved_regs (fi);
808
    }
809
}
810
 
811
/* Function: xstormy16_frame_chain
812
   Returns a pointer to the stack frame of the calling function.
813
   Called only from get_prev_frame.  Needed for backtrace, "up", etc.
814
*/
815
 
816
static CORE_ADDR
817
xstormy16_frame_chain (struct frame_info *fi)
818
{
819
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
820
    {
821
      /* Call dummy's frame is the same as caller's.  */
822
      return fi->frame;
823
    }
824
  else
825
    {
826
      /* Return computed offset from this frame's fp. */
827
      return fi->frame - fi->extra_info->framesize;
828
    }
829
}
830
 
831
static int
832
xstormy16_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
833
{
834
  return chain < 0x8000 && FRAME_SAVED_PC (thisframe) >= 0x8000 &&
835
    (thisframe->extra_info->frameless_p ||
836
     thisframe->frame - thisframe->extra_info->framesize == chain);
837
}
838
 
839
/* Function: xstormy16_saved_pc_after_call
840
   Returns the previous PC immediately after a function call.
841
   This function is meant to bypass the regular get_saved_register
842
   mechanism, ie. it is meant to work even if the frame isn't complete.
843
   Called by step_over_function, and sometimes by get_prev_frame.
844
*/
845
 
846
static CORE_ADDR
847
xstormy16_saved_pc_after_call (struct frame_info *ignore)
848
{
849
  CORE_ADDR sp, pc, tmp;
850
 
851
  sp = read_register (E_SP_REGNUM) - xstormy16_pc_size;
852
  pc = read_memory_integer (sp, xstormy16_pc_size);
853
 
854
  /* Skip over jump table entry if necessary.  */
855
  if ((tmp = SKIP_TRAMPOLINE_CODE (pc)))
856
    pc = tmp;
857
 
858
  return pc;
859
}
860
 
861
const static unsigned char *
862
xstormy16_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
863
{
864
  static unsigned char breakpoint[] = { 0x06, 0x0 };
865
  *lenptr = sizeof (breakpoint);
866
  return breakpoint;
867
}
868
 
869
/* Given a pointer to a jump table entry, return the address
870
   of the function it jumps to.  Return 0 if not found. */
871
static CORE_ADDR
872
xstormy16_resolve_jmp_table_entry (CORE_ADDR faddr)
873
{
874
  struct obj_section *faddr_sect = find_pc_section (faddr);
875
 
876
  if (faddr_sect)
877
    {
878
      LONGEST inst, inst2, addr;
879
      char buf[2 * xstormy16_inst_size];
880
 
881
      /* Return faddr if it's not pointing into the jump table. */
882
      if (strcmp (faddr_sect->the_bfd_section->name, ".plt"))
883
        return faddr;
884
 
885
      if (!target_read_memory (faddr, buf, sizeof buf))
886
        {
887
          inst = extract_unsigned_integer (buf, xstormy16_inst_size);
888
          inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
889
                                            xstormy16_inst_size);
890
          addr = inst2 << 8 | (inst & 0xff);
891
          return addr;
892
        }
893
    }
894
  return 0;
895
}
896
 
897
/* Given a function's address, attempt to find (and return) the
898
   address of the corresponding jump table entry.  Return 0 if
899
   not found. */
900
static CORE_ADDR
901
xstormy16_find_jmp_table_entry (CORE_ADDR faddr)
902
{
903
  struct obj_section *faddr_sect = find_pc_section (faddr);
904
 
905
  if (faddr_sect)
906
    {
907
      struct obj_section *osect;
908
 
909
      /* Return faddr if it's already a pointer to a jump table entry. */
910
      if (!strcmp (faddr_sect->the_bfd_section->name, ".plt"))
911
        return faddr;
912
 
913
      ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
914
      {
915
        if (!strcmp (osect->the_bfd_section->name, ".plt"))
916
          break;
917
      }
918
 
919
      if (osect < faddr_sect->objfile->sections_end)
920
        {
921
          CORE_ADDR addr;
922
          for (addr = osect->addr;
923
               addr < osect->endaddr; addr += 2 * xstormy16_inst_size)
924
            {
925
              int status;
926
              LONGEST inst, inst2, faddr2;
927
              char buf[2 * xstormy16_inst_size];
928
 
929
              if (target_read_memory (addr, buf, sizeof buf))
930
                return 0;
931
              inst = extract_unsigned_integer (buf, xstormy16_inst_size);
932
              inst2 = extract_unsigned_integer (buf + xstormy16_inst_size,
933
                                                xstormy16_inst_size);
934
              faddr2 = inst2 << 8 | (inst & 0xff);
935
              if (faddr == faddr2)
936
                return addr;
937
            }
938
        }
939
    }
940
  return 0;
941
}
942
 
943
static CORE_ADDR
944
xstormy16_skip_trampoline_code (CORE_ADDR pc)
945
{
946
  int tmp = xstormy16_resolve_jmp_table_entry (pc);
947
 
948
  if (tmp && tmp != pc)
949
    return tmp;
950
  return 0;
951
}
952
 
953
static int
954
xstormy16_in_solib_call_trampoline (CORE_ADDR pc, char *name)
955
{
956
  return xstormy16_skip_trampoline_code (pc) != 0;
957
}
958
 
959
static CORE_ADDR
960
xstormy16_pointer_to_address (struct type *type, void *buf)
961
{
962
  enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
963
  CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));
964
 
965
  if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
966
    {
967
      CORE_ADDR addr2 = xstormy16_resolve_jmp_table_entry (addr);
968
      if (addr2)
969
        addr = addr2;
970
    }
971
 
972
  return addr;
973
}
974
 
975
static void
976
xstormy16_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
977
{
978
  enum type_code target = TYPE_CODE (TYPE_TARGET_TYPE (type));
979
 
980
  if (target == TYPE_CODE_FUNC || target == TYPE_CODE_METHOD)
981
    {
982
      CORE_ADDR addr2 = xstormy16_find_jmp_table_entry (addr);
983
      if (addr2)
984
        addr = addr2;
985
    }
986
  store_address (buf, TYPE_LENGTH (type), addr);
987
}
988
 
989
static CORE_ADDR
990
xstormy16_stack_align (CORE_ADDR addr)
991
{
992
  if (addr & 1)
993
    ++addr;
994
  return addr;
995
}
996
 
997
void
998
xstormy16_save_dummy_frame_tos (CORE_ADDR sp)
999
{
1000
  generic_save_dummy_frame_tos (sp - xstormy16_pc_size);
1001
}
1002
 
1003
/* Function: xstormy16_gdbarch_init
1004
   Initializer function for the xstormy16 gdbarch vector.
1005
   Called by gdbarch.  Sets up the gdbarch vector(s) for this target. */
1006
 
1007
static struct gdbarch *
1008
xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1009
{
1010
  static LONGEST call_dummy_words[1] = { 0 };
1011
  struct gdbarch_tdep *tdep = NULL;
1012
  struct gdbarch *gdbarch;
1013
 
1014
  /* find a candidate among the list of pre-declared architectures. */
1015
  arches = gdbarch_list_lookup_by_info (arches, &info);
1016
  if (arches != NULL)
1017
    return (arches->gdbarch);
1018
 
1019
#if 0
1020
  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1021
#endif
1022
 
1023
  gdbarch = gdbarch_alloc (&info, 0);
1024
 
1025
  /*
1026
   * Basic register fields and methods.
1027
   */
1028
 
1029
  set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
1030
  set_gdbarch_num_pseudo_regs (gdbarch, 0);
1031
  set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
1032
  set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
1033
  set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1034
  set_gdbarch_register_name (gdbarch, xstormy16_register_name);
1035
  set_gdbarch_register_size (gdbarch, xstormy16_reg_size);
1036
  set_gdbarch_register_bytes (gdbarch, E_ALL_REGS_SIZE);
1037
  set_gdbarch_register_byte (gdbarch, xstormy16_register_byte);
1038
  set_gdbarch_register_raw_size (gdbarch, xstormy16_register_raw_size);
1039
  set_gdbarch_max_register_raw_size (gdbarch, xstormy16_pc_size);
1040
  set_gdbarch_register_virtual_size (gdbarch, xstormy16_register_raw_size);
1041
  set_gdbarch_max_register_virtual_size (gdbarch, 4);
1042
  set_gdbarch_register_virtual_type (gdbarch, xstormy16_reg_virtual_type);
1043
 
1044
  /*
1045
   * Frame Info
1046
   */
1047
  set_gdbarch_init_extra_frame_info (gdbarch,
1048
                                     xstormy16_init_extra_frame_info);
1049
  set_gdbarch_frame_init_saved_regs (gdbarch,
1050
                                     xstormy16_frame_init_saved_regs);
1051
  set_gdbarch_frame_chain (gdbarch, xstormy16_frame_chain);
1052
  set_gdbarch_get_saved_register (gdbarch, xstormy16_get_saved_register);
1053
  set_gdbarch_saved_pc_after_call (gdbarch, xstormy16_saved_pc_after_call);
1054
  set_gdbarch_frame_saved_pc (gdbarch, xstormy16_frame_saved_pc);
1055
  set_gdbarch_skip_prologue (gdbarch, xstormy16_skip_prologue);
1056
  set_gdbarch_frame_chain_valid (gdbarch, xstormy16_frame_chain_valid);
1057
  set_gdbarch_frame_args_address (gdbarch, default_frame_address);
1058
  set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
1059
 
1060
  set_gdbarch_in_function_epilogue_p (gdbarch,
1061
                                      xstormy16_in_function_epilogue_p);
1062
 
1063
  /*
1064
   * Miscelany
1065
   */
1066
  /* Stack grows up. */
1067
  set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
1068
  /* PC stops zero byte after a trap instruction
1069
     (which means: exactly on trap instruction). */
1070
  set_gdbarch_decr_pc_after_break (gdbarch, 0);
1071
  /* This value is almost never non-zero... */
1072
  set_gdbarch_function_start_offset (gdbarch, 0);
1073
  /* This value is almost never non-zero... */
1074
  set_gdbarch_frame_args_skip (gdbarch, 0);
1075
  /* OK to default this value to 'unknown'. */
1076
  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
1077
 
1078
  /* W/o prototype, coerce float args to double. */
1079
  set_gdbarch_coerce_float_to_double (gdbarch,
1080
                                      standard_coerce_float_to_double);
1081
 
1082
  /*
1083
   * Call Dummies
1084
   *
1085
   * These values and methods are used when gdb calls a target function.  */
1086
  set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
1087
  set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
1088
  set_gdbarch_push_return_address (gdbarch, xstormy16_push_return_address);
1089
  set_gdbarch_deprecated_extract_return_value (gdbarch, xstormy16_extract_return_value);
1090
  set_gdbarch_push_arguments (gdbarch, xstormy16_push_arguments);
1091
  set_gdbarch_pop_frame (gdbarch, xstormy16_pop_frame);
1092
  set_gdbarch_store_struct_return (gdbarch, xstormy16_store_struct_return);
1093
  set_gdbarch_deprecated_store_return_value (gdbarch, xstormy16_store_return_value);
1094
  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, xstormy16_extract_struct_value_address);
1095
  set_gdbarch_use_struct_convention (gdbarch,
1096
                                     xstormy16_use_struct_convention);
1097
  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
1098
  set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
1099
  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
1100
  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
1101
  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
1102
  set_gdbarch_call_dummy_length (gdbarch, 0);
1103
  set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
1104
  set_gdbarch_call_dummy_p (gdbarch, 1);
1105
  set_gdbarch_call_dummy_words (gdbarch, call_dummy_words);
1106
  set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
1107
  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
1108
  /* set_gdbarch_call_dummy_stack_adjust */
1109
  set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
1110
  set_gdbarch_breakpoint_from_pc (gdbarch, xstormy16_breakpoint_from_pc);
1111
 
1112
  set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1113
  set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1114
  set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1115
  set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1116
 
1117
  set_gdbarch_address_to_pointer (gdbarch, xstormy16_address_to_pointer);
1118
  set_gdbarch_pointer_to_address (gdbarch, xstormy16_pointer_to_address);
1119
 
1120
  set_gdbarch_stack_align (gdbarch, xstormy16_stack_align);
1121
  set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
1122
 
1123
  set_gdbarch_save_dummy_frame_tos (gdbarch, xstormy16_save_dummy_frame_tos);
1124
 
1125
  set_gdbarch_skip_trampoline_code (gdbarch, xstormy16_skip_trampoline_code);
1126
 
1127
  set_gdbarch_in_solib_call_trampoline (gdbarch,
1128
                                        xstormy16_in_solib_call_trampoline);
1129
 
1130
  return gdbarch;
1131
}
1132
 
1133
/* Function: _initialize_xstormy16_tdep
1134
   Initializer function for the Sanyo Xstormy16a module.
1135
   Called by gdb at start-up. */
1136
 
1137
void
1138
_initialize_xstormy16_tdep (void)
1139
{
1140
  extern int print_insn_xstormy16 ();
1141
 
1142
  register_gdbarch_init (bfd_arch_xstormy16, xstormy16_gdbarch_init);
1143
  tm_print_insn = print_insn_xstormy16;
1144
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.