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

Subversion Repositories or1k

[/] [or1k/] [tags/] [final_interface/] [gdb-5.0/] [opcodes/] [cgen-dis.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* CGEN generic disassembler support code.
2
 
3
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
4
 
5
   This file is part of the GNU Binutils and GDB, the GNU debugger.
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, or (at your option)
10
   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 along
18
   with this program; if not, write to the Free Software Foundation, Inc.,
19
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sysdep.h"
22
#include <stdio.h>
23
#include "ansidecl.h"
24
#include "libiberty.h"
25
#include "bfd.h"
26
#include "symcat.h"
27
#include "opcode/cgen.h"
28
 
29
/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
30
 
31
   COUNT is the number of elements in INSNS.
32
   ENTSIZE is sizeof (CGEN_IBASE) for the target.
33
   ??? No longer used but leave in for now.
34
   HTABLE points to the hash table.
35
   HENTBUF is a pointer to sufficiently large buffer of hash entries.
36
   The result is a pointer to the next entry to use.
37
 
38
   The table is scanned backwards as additions are made to the front of the
39
   list and we want earlier ones to be prefered.  */
40
 
41
static CGEN_INSN_LIST *
42
hash_insn_array (cd, insns, count, entsize, htable, hentbuf)
43
     CGEN_CPU_DESC cd;
44
     const CGEN_INSN * insns;
45
     int count;
46
     int entsize;
47
     CGEN_INSN_LIST ** htable;
48
     CGEN_INSN_LIST * hentbuf;
49
{
50
  int big_p = CGEN_CPU_ENDIAN (cd) == CGEN_ENDIAN_BIG;
51
  int i;
52
 
53
  for (i = count - 1; i >= 0; --i, ++hentbuf)
54
    {
55
      unsigned int hash;
56
      char buf [4];
57
      unsigned long value;
58
      const CGEN_INSN *insn = &insns[i];
59
 
60
      if (! (* cd->dis_hash_p) (insn))
61
        continue;
62
 
63
      /* We don't know whether the target uses the buffer or the base insn
64
         to hash on, so set both up.  */
65
 
66
      value = CGEN_INSN_BASE_VALUE (insn);
67
      switch (CGEN_INSN_MASK_BITSIZE (insn))
68
        {
69
        case 8:
70
          buf[0] = value;
71
          break;
72
        case 16:
73
          if (big_p)
74
            bfd_putb16 ((bfd_vma) value, buf);
75
          else
76
            bfd_putl16 ((bfd_vma) value, buf);
77
          break;
78
        case 32:
79
          if (big_p)
80
            bfd_putb32 ((bfd_vma) value, buf);
81
          else
82
            bfd_putl32 ((bfd_vma) value, buf);
83
          break;
84
        default:
85
          abort ();
86
        }
87
 
88
      hash = (* cd->dis_hash) (buf, value);
89
      hentbuf->next = htable[hash];
90
      hentbuf->insn = insn;
91
      htable[hash] = hentbuf;
92
    }
93
 
94
  return hentbuf;
95
}
96
 
97
/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
98
   This function is identical to hash_insn_array except the insns are
99
   in a list.  */
100
 
101
static CGEN_INSN_LIST *
102
hash_insn_list (cd, insns, htable, hentbuf)
103
     CGEN_CPU_DESC cd;
104
     const CGEN_INSN_LIST *insns;
105
     CGEN_INSN_LIST **htable;
106
     CGEN_INSN_LIST *hentbuf;
107
{
108
  int big_p = CGEN_CPU_ENDIAN (cd) == CGEN_ENDIAN_BIG;
109
  const CGEN_INSN_LIST *ilist;
110
 
111
  for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
112
    {
113
      unsigned int hash;
114
      char buf[4];
115
      unsigned long value;
116
 
117
      if (! (* cd->dis_hash_p) (ilist->insn))
118
        continue;
119
 
120
      /* We don't know whether the target uses the buffer or the base insn
121
         to hash on, so set both up.  */
122
 
123
      value = CGEN_INSN_BASE_VALUE (ilist->insn);
124
      switch (CGEN_INSN_MASK_BITSIZE (ilist->insn))
125
        {
126
        case 8:
127
          buf[0] = value;
128
          break;
129
        case 16:
130
          if (big_p)
131
            bfd_putb16 ((bfd_vma) value, buf);
132
          else
133
            bfd_putl16 ((bfd_vma) value, buf);
134
          break;
135
        case 32:
136
          if (big_p)
137
            bfd_putb32 ((bfd_vma) value, buf);
138
          else
139
            bfd_putl32 ((bfd_vma) value, buf);
140
          break;
141
        default:
142
          abort ();
143
        }
144
 
145
      hash = (* cd->dis_hash) (buf, value);
146
      hentbuf->next = htable [hash];
147
      hentbuf->insn = ilist->insn;
148
      htable [hash] = hentbuf;
149
    }
150
 
151
  return hentbuf;
152
}
153
 
154
/* Build the disassembler instruction hash table.  */
155
 
156
static void
157
build_dis_hash_table (cd)
158
     CGEN_CPU_DESC cd;
159
{
160
  int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
161
  CGEN_INSN_TABLE *insn_table = & cd->insn_table;
162
  CGEN_INSN_TABLE *macro_insn_table = & cd->macro_insn_table;
163
  unsigned int hash_size = cd->dis_hash_size;
164
  CGEN_INSN_LIST *hash_entry_buf;
165
  CGEN_INSN_LIST **dis_hash_table;
166
  CGEN_INSN_LIST *dis_hash_table_entries;
167
 
168
  /* The space allocated for the hash table consists of two parts:
169
     the hash table and the hash lists.  */
170
 
171
  dis_hash_table = (CGEN_INSN_LIST **)
172
    xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
173
  memset (dis_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
174
  dis_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
175
    xmalloc (count * sizeof (CGEN_INSN_LIST));
176
 
177
  /* Add compiled in insns.
178
     Don't include the first one as it is a reserved entry.  */
179
  /* ??? It was the end of all hash chains, and also the special
180
     "invalid insn" marker.  May be able to do it differently now.  */
181
 
182
  hash_entry_buf = hash_insn_array (cd,
183
                                    insn_table->init_entries + 1,
184
                                    insn_table->num_init_entries - 1,
185
                                    insn_table->entry_size,
186
                                    dis_hash_table, hash_entry_buf);
187
 
188
  /* Add compiled in macro-insns.  */
189
 
190
  hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
191
                                    macro_insn_table->num_init_entries,
192
                                    macro_insn_table->entry_size,
193
                                    dis_hash_table, hash_entry_buf);
194
 
195
  /* Add runtime added insns.
196
     Later added insns will be prefered over earlier ones.  */
197
 
198
  hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
199
                                   dis_hash_table, hash_entry_buf);
200
 
201
  /* Add runtime added macro-insns.  */
202
 
203
  hash_insn_list (cd, macro_insn_table->new_entries,
204
                  dis_hash_table, hash_entry_buf);
205
 
206
  cd->dis_hash_table = dis_hash_table;
207
  cd->dis_hash_table_entries = dis_hash_table_entries;
208
}
209
 
210
/* Return the first entry in the hash list for INSN.  */
211
 
212
CGEN_INSN_LIST *
213
cgen_dis_lookup_insn (cd, buf, value)
214
     CGEN_CPU_DESC cd;
215
     const char * buf;
216
     CGEN_INSN_INT value;
217
{
218
  unsigned int hash;
219
 
220
  if (cd->dis_hash_table == NULL)
221
    build_dis_hash_table (cd);
222
 
223
  hash = (* cd->dis_hash) (buf, value);
224
 
225
  return cd->dis_hash_table[hash];
226
}

powered by: WebSVN 2.1.0

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