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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [arc-ext.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1181 sfurman
/* ARC target-dependent stuff. Extension structure access functions
2
   Copyright 1995, 1997, 2000, 2001 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, Boston, MA 02111-1307, USA.  */
19
 
20
#include "sysdep.h"
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include "bfd.h"
24
#include "arc-ext.h"
25
#include "libiberty.h"
26
 
27
/* Extension structure  */
28
static struct arcExtMap arc_extension_map;
29
 
30
/* Get the name of an extension instruction.  */
31
 
32
const char *
33
arcExtMap_instName(int opcode, int minor, int *flags)
34
{
35
    if (opcode == 3)
36
      {
37
        /* FIXME: ??? need to also check 0/1/2 in bit0 for (3f) brk/sleep/swi  */
38
        if (minor < 0x09 || minor == 0x3f)
39
          return 0;
40
        else
41
          opcode = 0x1f - 0x10 + minor - 0x09 + 1;
42
      }
43
    else
44
      if (opcode < 0x10)
45
        return 0;
46
    else
47
      opcode -= 0x10;
48
    if (!arc_extension_map.instructions[opcode])
49
      return 0;
50
    *flags = arc_extension_map.instructions[opcode]->flags;
51
    return arc_extension_map.instructions[opcode]->name;
52
}
53
 
54
/* Get the name of an extension core register.  */
55
 
56
const char *
57
arcExtMap_coreRegName(int value)
58
{
59
  if (value < 32)
60
    return 0;
61
  return (const char *) arc_extension_map.coreRegisters[value-32];
62
}
63
 
64
/* Get the name of an extension condition code.  */
65
 
66
const char *
67
arcExtMap_condCodeName(int value)
68
{
69
  if (value < 16)
70
    return 0;
71
  return (const char *) arc_extension_map.condCodes[value-16];
72
}
73
 
74
/* Get the name of an extension aux register.  */
75
 
76
const char *
77
arcExtMap_auxRegName(long address)
78
{
79
  /* walk the list of aux reg names and find the name  */
80
  struct ExtAuxRegister *r;
81
 
82
  for (r = arc_extension_map.auxRegisters; r; r = r->next) {
83
    if (r->address == address)
84
      return (const char *) r->name;
85
  }
86
  return 0;
87
}
88
 
89
/* Recursively free auxilliary register strcture pointers until
90
   the list is empty.  */
91
 
92
static void
93
clean_aux_registers(struct ExtAuxRegister *r)
94
{
95
  if (r -> next)
96
    {
97
      clean_aux_registers( r->next);
98
      free(r -> name);
99
      free(r -> next);
100
      r ->next = NULL;
101
    }
102
  else
103
    free(r -> name);
104
}
105
 
106
/* Free memory that has been allocated for the extensions.  */
107
 
108
static void
109
cleanup_ext_map(void)
110
{
111
  struct ExtAuxRegister *r;
112
  struct ExtInstruction *insn;
113
  int i;
114
 
115
  /* clean aux reg structure  */
116
  r = arc_extension_map.auxRegisters;
117
  if (r)
118
    {
119
      (clean_aux_registers(r));
120
      free(r);
121
    }
122
 
123
  /* clean instructions  */
124
  for (i = 0; i < NUM_EXT_INST; i++)
125
    {
126
      insn = arc_extension_map.instructions[i];
127
      if (insn)
128
        free(insn->name);
129
    }
130
 
131
  /* clean core reg struct  */
132
  for (i = 0; i < NUM_EXT_CORE; i++)
133
    {
134
      if (arc_extension_map.coreRegisters[i])
135
        free(arc_extension_map.coreRegisters[i]);
136
    }
137
 
138
  for (i = 0; i < NUM_EXT_COND; i++) {
139
    if (arc_extension_map.condCodes[i])
140
      free(arc_extension_map.condCodes[i]);
141
  }
142
 
143
  memset(&arc_extension_map, 0, sizeof(struct arcExtMap));
144
}
145
 
146
int
147
arcExtMap_add(void *base, unsigned long length)
148
{
149
  unsigned char *block = base;
150
  unsigned char *p = block;
151
 
152
  /* Clean up and reset everything if needed.  */
153
  cleanup_ext_map();
154
 
155
  while (p && p < (block + length))
156
    {
157
      /* p[0] == length of record
158
         p[1] == type of record
159
         For instructions:
160
           p[2]  = opcode
161
           p[3]  = minor opcode (if opcode == 3)
162
           p[4]  = flags
163
           p[5]+ = name
164
         For core regs and condition codes:
165
           p[2]  = value
166
           p[3]+ = name
167
         For aux regs:
168
           p[2..5] = value
169
           p[6]+   = name
170
         (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5])  */
171
 
172
      if (p[0] == 0)
173
        return -1;
174
 
175
      switch (p[1])
176
        {
177
        case EXT_INSTRUCTION:
178
          {
179
            char opcode = p[2];
180
            char minor  = p[3];
181
            char * insn_name = (char *) xmalloc(( (int)*p-5) * sizeof(char));
182
            struct ExtInstruction * insn =
183
              (struct ExtInstruction *) xmalloc(sizeof(struct ExtInstruction));
184
 
185
            if (opcode==3)
186
              opcode = 0x1f - 0x10 + minor - 0x09 + 1;
187
            else
188
              opcode -= 0x10;
189
            insn -> flags = (char) *(p+4);
190
            strcpy(insn_name, (p+5));
191
            insn -> name = insn_name;
192
            arc_extension_map.instructions[(int) opcode] = insn;
193
          }
194
          break;
195
 
196
        case EXT_CORE_REGISTER:
197
          {
198
            char * core_name = (char *) xmalloc(((int)*p-3) * sizeof(char));
199
 
200
            strcpy(core_name, (p+3));
201
            arc_extension_map.coreRegisters[p[2]-32] = core_name;
202
          }
203
          break;
204
 
205
        case EXT_COND_CODE:
206
          {
207
            char * cc_name = (char *) xmalloc( ((int)*p-3) * sizeof(char));
208
            strcpy(cc_name, (p+3));
209
            arc_extension_map.condCodes[p[2]-16] = cc_name;
210
          }
211
          break;
212
 
213
        case EXT_AUX_REGISTER:
214
          {
215
            /* trickier -- need to store linked list to these  */
216
            struct ExtAuxRegister *newAuxRegister =
217
              (struct ExtAuxRegister *)malloc(sizeof(struct ExtAuxRegister));
218
            char * aux_name = (char *) xmalloc ( ((int)*p-6) * sizeof(char));
219
 
220
            strcpy (aux_name, (p+6));
221
            newAuxRegister->name = aux_name;
222
            newAuxRegister->address = p[2]<<24 | p[3]<<16 | p[4]<<8  | p[5];
223
            newAuxRegister->next = arc_extension_map.auxRegisters;
224
            arc_extension_map.auxRegisters = newAuxRegister;
225
          }
226
          break;
227
 
228
        default:
229
          return -1;
230
 
231
        }
232
      p += p[0]; /* move to next record  */
233
    }
234
 
235
  return 0;
236
}
237
 
238
/* Load hw extension descibed in .extArcMap ELF section.  */
239
 
240
void
241
build_ARC_extmap (text_bfd)
242
  bfd *text_bfd;
243
{
244
  char *arcExtMap;
245
  bfd_size_type count;
246
  asection *p;
247
 
248
  for (p = text_bfd->sections; p != NULL; p = p->next)
249
    if (!strcmp (p->name, ".arcextmap"))
250
      {
251
        count = p->_raw_size;
252
        arcExtMap = (char *) xmalloc (count);
253
        if (bfd_get_section_contents (text_bfd, p, (PTR) arcExtMap, 0, count))
254
          {
255
            arcExtMap_add ((PTR) arcExtMap, count);
256
            break;
257
          }
258
        free ((PTR) arcExtMap);
259
      }
260
}

powered by: WebSVN 2.1.0

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