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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [tic80-tdep.c] - Blame information for rev 105

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

Line No. Rev Author Line
1 104 markom
/* Target-dependent code for the TI TMS320C80 (MVP) for GDB, the GNU debugger.
2
   Copyright 1996, Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
#include "value.h"
23
#include "frame.h"
24
#include "inferior.h"
25
#include "obstack.h"
26
#include "target.h"
27
#include "bfd.h"
28
#include "gdb_string.h"
29
#include "gdbcore.h"
30
#include "symfile.h"
31
 
32
/* Function: frame_find_saved_regs
33
   Return the frame_saved_regs structure for the frame.
34
   Doesn't really work for dummy frames, but it does pass back
35
   an empty frame_saved_regs, so I guess that's better than total failure */
36
 
37
void
38
tic80_frame_find_saved_regs (fi, regaddr)
39
     struct frame_info *fi;
40
     struct frame_saved_regs *regaddr;
41
{
42
  memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs));
43
}
44
 
45
/* Function: skip_prologue
46
   Find end of function prologue.  */
47
 
48
CORE_ADDR
49
tic80_skip_prologue (pc)
50
     CORE_ADDR pc;
51
{
52
  CORE_ADDR func_addr, func_end;
53
  struct symtab_and_line sal;
54
 
55
  /* See what the symbol table says */
56
 
57
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
58
    {
59
      sal = find_pc_line (func_addr, 0);
60
 
61
      if (sal.line != 0 && sal.end < func_end)
62
        return sal.end;
63
      else
64
        /* Either there's no line info, or the line after the prologue is after
65
           the end of the function.  In this case, there probably isn't a
66
           prologue.  */
67
        return pc;
68
    }
69
 
70
  /* We can't find the start of this function, so there's nothing we can do. */
71
  return pc;
72
}
73
 
74
/* Function: tic80_scan_prologue
75
   This function decodes the target function prologue to determine:
76
   1) the size of the stack frame
77
   2) which registers are saved on it
78
   3) the offsets of saved regs
79
   4) the frame size
80
   This information is stored in the "extra" fields of the frame_info.  */
81
 
82
static void
83
tic80_scan_prologue (fi)
84
     struct frame_info *fi;
85
{
86
  struct symtab_and_line sal;
87
  CORE_ADDR prologue_start, prologue_end, current_pc;
88
 
89
  /* Assume there is no frame until proven otherwise.  */
90
  fi->framereg = SP_REGNUM;
91
  fi->framesize = 0;
92
  fi->frameoffset = 0;
93
 
94
  /* this code essentially duplicates skip_prologue,
95
     but we need the start address below.  */
96
 
97
  if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
98
    {
99
      sal = find_pc_line (prologue_start, 0);
100
 
101
      if (sal.line == 0) /* no line info, use current PC */
102
        if (prologue_start != entry_point_address ())
103
          prologue_end = fi->pc;
104
        else
105
          return;               /* _start has no frame or prologue */
106
      else if (sal.end < prologue_end)  /* next line begins after fn end */
107
        prologue_end = sal.end; /* (probably means no prologue)  */
108
    }
109
  else
110
/* FIXME */
111
    prologue_end = prologue_start + 40;         /* We're in the boondocks: allow for */
112
  /* 16 pushes, an add, and "mv fp,sp" */
113
 
114
  prologue_end = min (prologue_end, fi->pc);
115
 
116
  /* Now search the prologue looking for instructions that set up the
117
     frame pointer, adjust the stack pointer, and save registers.  */
118
 
119
  for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 4)
120
    {
121
      unsigned int insn;
122
      int regno;
123
      int offset = 0;
124
 
125
      insn = read_memory_unsigned_integer (current_pc, 4);
126
 
127
      if ((insn & 0x301000) == 0x301000)        /* Long immediate? */
128
/* FIXME - set offset for long immediate instructions */
129
        current_pc += 4;
130
      else
131
        {
132
          offset = insn & 0x7fff;       /* extract 15-bit offset */
133
          if (offset & 0x4000)  /* if negative, sign-extend */
134
            offset = -(0x8000 - offset);
135
        }
136
 
137
      if ((insn & 0x7fd0000) == 0x590000)       /* st.{w,d} reg, xx(r1) */
138
        {
139
          regno = ((insn >> 27) & 0x1f);
140
          fi->fsr.regs[regno] = offset;
141
          if (insn & 0x8000)    /* 64-bit store (st.d)? */
142
            fi->fsr.regs[regno + 1] = offset + 4;
143
        }
144
      else if ((insn & 0xffff8000) == 0x086c8000)       /* addu xx, r1, r1 */
145
        fi->framesize = -offset;
146
      else if ((insn & 0xffff8000) == 0xf06c8000)       /* addu xx, r1, r30 */
147
        {
148
          fi->framereg = FP_REGNUM;     /* fp is now valid */
149
          fi->frameoffset = offset;
150
          break;                /* end of stack adjustments */
151
        }
152
      else if (insn == 0xf03b2001)      /* addu r1, r0, r30 */
153
        {
154
          fi->framereg = FP_REGNUM;     /* fp is now valid */
155
          fi->frameoffset = 0;
156
          break;                /* end of stack adjustments */
157
        }
158
      else
159
/* FIXME - handle long immediate instructions */
160
        break;                  /* anything else isn't prologue */
161
    }
162
}
163
 
164
/* Function: init_extra_frame_info
165
   This function actually figures out the frame address for a given pc and
166
   sp.  This is tricky on the c80 because we sometimes don't use an explicit
167
   frame pointer, and the previous stack pointer isn't necessarily recorded
168
   on the stack.  The only reliable way to get this info is to
169
   examine the prologue.  */
170
 
171
void
172
tic80_init_extra_frame_info (fi)
173
     struct frame_info *fi;
174
{
175
  int reg;
176
 
177
  if (fi->next)
178
    fi->pc = FRAME_SAVED_PC (fi->next);
179
 
180
  /* Because zero is a valid register offset relative to SP, we initialize
181
     the offsets to -1 to indicate unused entries.  */
182
  for (reg = 0; reg < NUM_REGS; reg++)
183
    fi->fsr.regs[reg] = -1;
184
 
185
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
186
    {
187
      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
188
         by assuming it's always FP.  */
189
      fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
190
      fi->framesize = 0;
191
      fi->frameoffset = 0;
192
      return;
193
    }
194
  else
195
    {
196
      tic80_scan_prologue (fi);
197
 
198
      if (!fi->next)            /* this is the innermost frame? */
199
        fi->frame = read_register (fi->framereg);
200
      else
201
        /* not the innermost frame */
202
        /* If this function uses FP as the frame register, and the function
203
           it called saved the FP, get the saved FP.  */ if (fi->framereg == FP_REGNUM &&
204
                             fi->next->fsr.regs[FP_REGNUM] != (unsigned) -1)
205
        fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
206
 
207
      /* Convert SP-relative offsets of saved registers to real addresses.  */
208
      for (reg = 0; reg < NUM_REGS; reg++)
209
        if (fi->fsr.regs[reg] == (unsigned) -1)
210
          fi->fsr.regs[reg] = 0; /* unused entry */
211
        else
212
          fi->fsr.regs[reg] += fi->frame - fi->frameoffset;
213
    }
214
}
215
 
216
/* Function: find_callers_reg
217
   Find REGNUM on the stack.  Otherwise, it's in an active register.  One thing
218
   we might want to do here is to check REGNUM against the clobber mask, and
219
   somehow flag it as invalid if it isn't saved on the stack somewhere.  This
220
   would provide a graceful failure mode when trying to get the value of
221
   caller-saves registers for an inner frame.  */
222
 
223
CORE_ADDR
224
tic80_find_callers_reg (fi, regnum)
225
     struct frame_info *fi;
226
     int regnum;
227
{
228
  for (; fi; fi = fi->next)
229
    if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
230
      return generic_read_register_dummy (fi->pc, fi->frame, regnum);
231
    else if (fi->fsr.regs[regnum] != 0)
232
      return read_memory_integer (fi->fsr.regs[regnum],
233
                                  REGISTER_RAW_SIZE (regnum));
234
  return read_register (regnum);
235
}
236
 
237
/* Function: frame_chain
238
   Given a GDB frame, determine the address of the calling function's frame.
239
   This will be used to create a new GDB frame struct, and then
240
   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
241
   For c80, we save the frame size when we initialize the frame_info.  */
242
 
243
CORE_ADDR
244
tic80_frame_chain (fi)
245
     struct frame_info *fi;
246
{
247
  CORE_ADDR fn_start, callers_pc, fp;
248
 
249
  /* is this a dummy frame? */
250
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
251
    return fi->frame;           /* dummy frame same as caller's frame */
252
 
253
  /* is caller-of-this a dummy frame? */
254
  callers_pc = FRAME_SAVED_PC (fi);     /* find out who called us: */
255
  fp = tic80_find_callers_reg (fi, FP_REGNUM);
256
  if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
257
    return fp;                  /* dummy frame's frame may bear no relation to ours */
258
 
259
  if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
260
    if (fn_start == entry_point_address ())
261
      return 0;                  /* in _start fn, don't chain further */
262
 
263
  if (fi->framereg == FP_REGNUM)
264
    return tic80_find_callers_reg (fi, FP_REGNUM);
265
  else
266
    return fi->frame + fi->framesize;
267
}
268
 
269
/* Function: pop_frame
270
   Discard from the stack the innermost frame,
271
   restoring all saved registers.  */
272
 
273
struct frame_info *
274
tic80_pop_frame (frame)
275
     struct frame_info *frame;
276
{
277
  int regnum;
278
 
279
  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
280
    generic_pop_dummy_frame ();
281
  else
282
    {
283
      for (regnum = 0; regnum < NUM_REGS; regnum++)
284
        if (frame->fsr.regs[regnum] != 0)
285
          write_register (regnum,
286
                          read_memory_integer (frame->fsr.regs[regnum], 4));
287
 
288
      write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
289
      write_register (SP_REGNUM, read_register (FP_REGNUM));
290
#if 0
291
      if (read_register (PSW_REGNUM) & 0x80)
292
        write_register (SPU_REGNUM, read_register (SP_REGNUM));
293
      else
294
        write_register (SPI_REGNUM, read_register (SP_REGNUM));
295
#endif
296
    }
297
  flush_cached_frames ();
298
  return NULL;
299
}
300
 
301
/* Function: frame_saved_pc
302
   Find the caller of this frame.  We do this by seeing if LR_REGNUM is saved
303
   in the stack anywhere, otherwise we get it from the registers. */
304
 
305
CORE_ADDR
306
tic80_frame_saved_pc (fi)
307
     struct frame_info *fi;
308
{
309
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
310
    return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
311
  else
312
    return tic80_find_callers_reg (fi, LR_REGNUM);
313
}
314
 
315
/* Function: tic80_push_return_address (pc, sp)
316
   Set up the return address for the inferior function call.
317
   Necessary for targets that don't actually execute a JSR/BSR instruction
318
   (ie. when using an empty CALL_DUMMY) */
319
 
320
CORE_ADDR
321
tic80_push_return_address (pc, sp)
322
     CORE_ADDR pc;
323
     CORE_ADDR sp;
324
{
325
  write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
326
  return sp;
327
}
328
 
329
 
330
/* Function: push_arguments
331
   Setup the function arguments for calling a function in the inferior.
332
 
333
   On the TI C80 architecture, there are six register pairs (R2/R3 to R12/13)
334
   which are dedicated for passing function arguments.  Up to the first six
335
   arguments (depending on size) may go into these registers.
336
   The rest go on the stack.
337
 
338
   Arguments that are smaller than 4 bytes will still take up a whole
339
   register or a whole 32-bit word on the stack, and will be
340
   right-justified in the register or the stack word.  This includes
341
   chars, shorts, and small aggregate types.
342
 
343
   Arguments that are four bytes or less in size are placed in the
344
   even-numbered register of a register pair, and the odd-numbered
345
   register is not used.
346
 
347
   Arguments of 8 bytes size (such as floating point doubles) are placed
348
   in a register pair.  The least significant 32-bit word is placed in
349
   the even-numbered register, and the most significant word in the
350
   odd-numbered register.
351
 
352
   Aggregate types with sizes between 4 and 8 bytes are passed
353
   entirely on the stack, and are left-justified within the
354
   double-word (as opposed to aggregates smaller than 4 bytes
355
   which are right-justified).
356
 
357
   Aggregates of greater than 8 bytes are first copied onto the stack,
358
   and then a pointer to the copy is passed in the place of the normal
359
   argument (either in a register if available, or on the stack).
360
 
361
   Functions that must return an aggregate type can return it in the
362
   normal return value registers (R2 and R3) if its size is 8 bytes or
363
   less.  For larger return values, the caller must allocate space for
364
   the callee to copy the return value to.  A pointer to this space is
365
   passed as an implicit first argument, always in R0. */
366
 
367
CORE_ADDR
368
tic80_push_arguments (nargs, args, sp, struct_return, struct_addr)
369
     int nargs;
370
     value_ptr *args;
371
     CORE_ADDR sp;
372
     unsigned char struct_return;
373
     CORE_ADDR struct_addr;
374
{
375
  int stack_offset, stack_alloc;
376
  int argreg;
377
  int argnum;
378
  struct type *type;
379
  CORE_ADDR regval;
380
  char *val;
381
  char valbuf[4];
382
  int len;
383
  int odd_sized_struct;
384
  int is_struct;
385
 
386
  /* first force sp to a 4-byte alignment */
387
  sp = sp & ~3;
388
 
389
  argreg = ARG0_REGNUM;
390
  /* The "struct return pointer" pseudo-argument goes in R0 */
391
  if (struct_return)
392
    write_register (argreg++, struct_addr);
393
 
394
  /* Now make sure there's space on the stack */
395
  for (argnum = 0, stack_alloc = 0;
396
       argnum < nargs; argnum++)
397
    stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
398
  sp -= stack_alloc;            /* make room on stack for args */
399
 
400
 
401
  /* Now load as many as possible of the first arguments into
402
     registers, and push the rest onto the stack.  There are 16 bytes
403
     in four registers available.  Loop thru args from first to last.  */
404
 
405
  argreg = ARG0_REGNUM;
406
  for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
407
    {
408
      type = VALUE_TYPE (args[argnum]);
409
      len = TYPE_LENGTH (type);
410
      memset (valbuf, 0, sizeof (valbuf));
411
      val = (char *) VALUE_CONTENTS (args[argnum]);
412
 
413
/* FIXME -- tic80 can take doubleword arguments in register pairs */
414
      is_struct = (type->code == TYPE_CODE_STRUCT);
415
      odd_sized_struct = 0;
416
 
417
      if (!is_struct)
418
        {
419
          if (len < 4)
420
            {                   /* value gets right-justified in the register or stack word */
421
              memcpy (valbuf + (4 - len), val, len);
422
              val = valbuf;
423
            }
424
          if (len > 4 && (len & 3) != 0)
425
            odd_sized_struct = 1;       /* such structs go entirely on stack */
426
        }
427
      else
428
        {
429
          /* Structs are always passed by reference. */
430
          write_register (argreg, sp + stack_offset);
431
          argreg++;
432
        }
433
 
434
      while (len > 0)
435
        {
436
          if (is_struct || argreg > ARGLAST_REGNUM || odd_sized_struct)
437
            {                   /* must go on the stack */
438
              write_memory (sp + stack_offset, val, 4);
439
              stack_offset += 4;
440
            }
441
          /* NOTE WELL!!!!!  This is not an "else if" clause!!!
442
             That's because some things get passed on the stack
443
             AND in the registers!   */
444
          if (!is_struct && argreg <= ARGLAST_REGNUM)
445
            {                   /* there's room in a register */
446
              regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
447
              write_register (argreg, regval);
448
              argreg += 2;      /* FIXME -- what about doubleword args? */
449
            }
450
          /* Store the value 4 bytes at a time.  This means that things
451
             larger than 4 bytes may go partly in registers and partly
452
             on the stack.  */
453
          len -= REGISTER_RAW_SIZE (argreg);
454
          val += REGISTER_RAW_SIZE (argreg);
455
        }
456
    }
457
  return sp;
458
}
459
 
460
/* Function: tic80_write_sp
461
   Because SP is really a read-only register that mirrors either SPU or SPI,
462
   we must actually write one of those two as well, depending on PSW. */
463
 
464
void
465
tic80_write_sp (val)
466
     CORE_ADDR val;
467
{
468
#if 0
469
  unsigned long psw = read_register (PSW_REGNUM);
470
 
471
  if (psw & 0x80)               /* stack mode: user or interrupt */
472
    write_register (SPU_REGNUM, val);
473
  else
474
    write_register (SPI_REGNUM, val);
475
#endif
476
  write_register (SP_REGNUM, val);
477
}
478
 
479
void
480
_initialize_tic80_tdep ()
481
{
482
  tm_print_insn = print_insn_tic80;
483
}

powered by: WebSVN 2.1.0

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