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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [arc-ext.c] - Blame information for rev 1778

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

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

powered by: WebSVN 2.1.0

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