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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [or32.c] - Blame information for rev 99

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

Line No. Rev Author Line
1 19 jeremybenn
/* Table of opcodes for the OpenRISC 1000 ISA.
2
 
3
   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributed by Damjan Lampret (lampret@opencores.org).
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10
   This file is also part of gen_or1k_isa, GDB and GAS.
11
 
12
   This program is free software; you can redistribute it and/or modify it
13
   under the terms of the GNU General Public License as published by the Free
14
   Software Foundation; either version 3 of the License, or (at your option)
15
   any later version.
16
 
17
   This program is distributed in the hope that it will be useful, but WITHOUT
18
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
20
   more details.
21
 
22
   You should have received a copy of the GNU General Public License along
23
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
24
 
25
/* This program is commented throughout in a fashion suitable for processing
26
   with Doxygen. */
27
 
28
 
29
/* Autoconf and/or portability configuration */
30
#include "config.h"
31
#include "port.h"
32
 
33
/* System includes */
34
#include <stdlib.h>
35
#include <stdio.h>
36
 
37
/* Package includes */
38
#include "opcode/or32.h"
39
 
40
/* We treat all letters the same in encode/decode routines so
41
   we need to assign some characteristics to them like signess etc.*/
42
CONST struct or32_letter or32_letters[] = {
43
  {'A', NUM_UNSIGNED},
44
  {'B', NUM_UNSIGNED},
45
  {'D', NUM_UNSIGNED},
46
  {'I', NUM_SIGNED},
47
  {'K', NUM_UNSIGNED},
48
  {'L', NUM_UNSIGNED},
49
  {'N', NUM_SIGNED},
50
  {'0', NUM_UNSIGNED},
51
  {'\0', 0}                      /* dummy entry */
52
};
53
 
54
/* Opcode encoding:
55
   machine[31:30]: first two bits of opcode
56
                   00 - neither of source operands is GPR
57
                   01 - second source operand is GPR (rB)
58
                   10 - first source operand is GPR (rA)
59
                   11 - both source operands are GPRs (rA and rB)
60
   machine[29:26]: next four bits of opcode
61
   machine[25:00]: instruction operands (specific to individual instruction)
62
 
63
  Recommendation: irrelevant instruction bits should be set with a value of
64
  bits in same positions of instruction preceding current instruction in the
65
  code (when assembling).
66
*/
67
 
68
#ifdef HAVE_EXECUTION
69
# if SIMPLE_EXECUTION
70
#  define EFN &l_none
71
#  define EF(func) &(func)
72
#  define EFI &l_invalid
73
# elif COMPLEX_EXECUTION
74
#  define EFN "l_none"
75
#  define EFI "l_invalid"
76
#  ifdef __GNUC__
77
#   define EF(func) #func
78
#  else
79
#   define EF(func) "func"
80
#  endif
81
# else /* DYNAMIC_EXECUTION */
82
#  define EFN &l_none
83
#  define EF(func) &(gen_ ##func)
84
#  define EFI &gen_l_invalid
85
# endif
86
#else /* HAVE_EXECUTION */
87
# define EFN &l_none
88
# define EF(func) EFN
89
# define EFI EFN
90
#endif /* HAVE_EXECUTION */
91
 
92
CONST struct or32_opcode or32_opcodes[] = {
93
 
94
  {"l.j", "N", "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN",
95
   EF (l_j), OR32_IF_DELAY, it_jump},
96
  {"l.jal", "N", "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN",
97
   EF (l_jal), OR32_IF_DELAY, it_jump},
98
  {"l.bnf", "N", "00 0x3  NNNNN NNNNN NNNN NNNN NNNN NNNN",
99
   EF (l_bnf), OR32_IF_DELAY | OR32_R_FLAG, it_branch},
100
  {"l.bf", "N", "00 0x4  NNNNN NNNNN NNNN NNNN NNNN NNNN",
101
   EF (l_bf), OR32_IF_DELAY | OR32_R_FLAG, it_branch},
102
  {"l.nop", "K", "00 0x5  01--- ----- KKKK KKKK KKKK KKKK",
103
   EF (l_nop), 0, it_nop},
104
  {"l.movhi", "rD,K", "00 0x6  DDDDD ----0 KKKK KKKK KKKK KKKK",
105
   EF (l_movhi), 0, it_movimm},
106
  {"l.macrc", "rD", "00 0x6  DDDDD ----1 0000 0000 0000 0000",
107
   EF (l_macrc), 0, it_mac},
108
  {"l.sys", "K", "00 0x8  00000 00000 KKKK KKKK KKKK KKKK",
109
   EF (l_sys), 0, it_exception},
110
  {"l.trap", "K", "00 0x8  01000 00000 KKKK KKKK KKKK KKKK",
111
   EF (l_trap), 0, it_exception},
112
  {"l.msync", "", "00 0x8  10000 00000 0000 0000 0000 0000", EFN,
113
   0, it_unknown},
114
  {"l.psync", "", "00 0x8  10100 00000 0000 0000 0000 0000", EFN,
115
   0, it_unknown},
116
  {"l.csync", "", "00 0x8  11000 00000 0000 0000 0000 0000", EFN,
117
   0, it_unknown},
118
  {"l.rfe", "", "00 0x9  ----- ----- ---- ---- ---- ----",
119
   EF (l_rfe), 0, it_exception},
120
  {"lv.all_eq.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0,
121
   it_unknown},
122
  {"lv.all_eq.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0,
123
   it_unknown},
124
  {"lv.all_ge.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0,
125
   it_unknown},
126
  {"lv.all_ge.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0,
127
   it_unknown},
128
  {"lv.all_gt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0,
129
   it_unknown},
130
  {"lv.all_gt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0,
131
   it_unknown},
132
  {"lv.all_le.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0,
133
   it_unknown},
134
  {"lv.all_le.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0,
135
   it_unknown},
136
  {"lv.all_lt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0,
137
   it_unknown},
138
  {"lv.all_lt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0,
139
   it_unknown},
140
  {"lv.all_ne.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0,
141
   it_unknown},
142
  {"lv.all_ne.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0,
143
   it_unknown},
144
  {"lv.any_eq.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0,
145
   it_unknown},
146
  {"lv.any_eq.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0,
147
   it_unknown},
148
  {"lv.any_ge.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0,
149
   it_unknown},
150
  {"lv.any_ge.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0,
151
   it_unknown},
152
  {"lv.any_gt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0,
153
   it_unknown},
154
  {"lv.any_gt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0,
155
   it_unknown},
156
  {"lv.any_le.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0,
157
   it_unknown},
158
  {"lv.any_le.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0,
159
   it_unknown},
160
  {"lv.any_lt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0,
161
   it_unknown},
162
  {"lv.any_lt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0,
163
   it_unknown},
164
  {"lv.any_ne.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0,
165
   it_unknown},
166
  {"lv.any_ne.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0,
167
   it_unknown},
168
  {"lv.add.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0,
169
   it_unknown},
170
  {"lv.add.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0,
171
   it_unknown},
172
  {"lv.adds.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0,
173
   it_unknown},
174
  {"lv.adds.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0,
175
   it_unknown},
176
  {"lv.addu.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0,
177
   it_unknown},
178
  {"lv.addu.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0,
179
   it_unknown},
180
  {"lv.addus.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0,
181
   it_unknown},
182
  {"lv.addus.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0,
183
   it_unknown},
184
  {"lv.and", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0,
185
   it_unknown},
186
  {"lv.avg.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0,
187
   it_unknown},
188
  {"lv.avg.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0,
189
   it_unknown},
190
  {"lv.cmp_eq.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0,
191
   it_unknown},
192
  {"lv.cmp_eq.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0,
193
   it_unknown},
194
  {"lv.cmp_ge.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0,
195
   it_unknown},
196
  {"lv.cmp_ge.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0,
197
   it_unknown},
198
  {"lv.cmp_gt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0,
199
   it_unknown},
200
  {"lv.cmp_gt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0,
201
   it_unknown},
202
  {"lv.cmp_le.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0,
203
   it_unknown},
204
  {"lv.cmp_le.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0,
205
   it_unknown},
206
  {"lv.cmp_lt.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0,
207
   it_unknown},
208
  {"lv.cmp_lt.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0,
209
   it_unknown},
210
  {"lv.cmp_ne.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0,
211
   it_unknown},
212
  {"lv.cmp_ne.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0,
213
   it_unknown},
214
  {"lv.madds.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0,
215
   it_unknown},
216
  {"lv.max.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0,
217
   it_unknown},
218
  {"lv.max.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0,
219
   it_unknown},
220
  {"lv.merge.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0,
221
   it_unknown},
222
  {"lv.merge.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0,
223
   it_unknown},
224
  {"lv.min.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0,
225
   it_unknown},
226
  {"lv.min.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0,
227
   it_unknown},
228
  {"lv.msubs.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0,
229
   it_unknown},
230
  {"lv.muls.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0,
231
   it_unknown},
232
  {"lv.nand", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0,
233
   it_unknown},
234
  {"lv.nor", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0,
235
   it_unknown},
236
  {"lv.or", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0,
237
   it_unknown},
238
  {"lv.pack.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0,
239
   it_unknown},
240
  {"lv.pack.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0,
241
   it_unknown},
242
  {"lv.packs.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0,
243
   it_unknown},
244
  {"lv.packs.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0,
245
   it_unknown},
246
  {"lv.packus.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0,
247
   it_unknown},
248
  {"lv.packus.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0,
249
   it_unknown},
250
  {"lv.perm.n", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0,
251
   it_unknown},
252
  {"lv.rl.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0,
253
   it_unknown},
254
  {"lv.rl.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0,
255
   it_unknown},
256
  {"lv.sll.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0,
257
   it_unknown},
258
  {"lv.sll.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0,
259
   it_unknown},
260
  {"lv.sll", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0,
261
   it_unknown},
262
  {"lv.srl.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0,
263
   it_unknown},
264
  {"lv.srl.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0,
265
   it_unknown},
266
  {"lv.sra.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0,
267
   it_unknown},
268
  {"lv.sra.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0,
269
   it_unknown},
270
  {"lv.srl", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0,
271
   it_unknown},
272
  {"lv.sub.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0,
273
   it_unknown},
274
  {"lv.sub.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0,
275
   it_unknown},
276
  {"lv.subs.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0,
277
   it_unknown},
278
  {"lv.subs.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0,
279
   it_unknown},
280
  {"lv.subu.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0,
281
   it_unknown},
282
  {"lv.subu.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0,
283
   it_unknown},
284
  {"lv.subus.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0,
285
   it_unknown},
286
  {"lv.subus.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0,
287
   it_unknown},
288
  {"lv.unpack.b", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0,
289
   it_unknown},
290
  {"lv.unpack.h", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0,
291
   it_unknown},
292
  {"lv.xor", "rD,rA,rB", "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0,
293
   it_unknown},
294
  {"lv.cust1", "", "00 0xA  ----- ----- ---- ---- 0xC ----", EFI, 0,
295
   it_unknown},
296
  {"lv.cust2", "", "00 0xA  ----- ----- ---- ---- 0xD ----", EFI, 0,
297
   it_unknown},
298
  {"lv.cust3", "", "00 0xA  ----- ----- ---- ---- 0xE ----", EFI, 0,
299
   it_unknown},
300
  {"lv.cust4", "", "00 0xA  ----- ----- ---- ---- 0xF ----", EFI, 0,
301
   it_unknown},
302
 
303
  {"l.jr", "rB", "01 0x1  ----- ----- BBBB B--- ---- ----",
304
   EF (l_jr), OR32_IF_DELAY, it_jump},
305
  {"l.jalr", "rB", "01 0x2  ----- ----- BBBB B--- ---- ----",
306
   EF (l_jalr), OR32_IF_DELAY, it_jump},
307
  {"l.maci", "rA,I", "01 0x3  IIIII AAAAA ---- -III IIII IIII",
308
   EF (l_mac), 0, it_mac},
309
  {"l.cust1", "", "01 0xC  ----- ----- ---- ---- ---- ----",
310
   EF (l_cust1), 0, it_unknown},
311
  {"l.cust2", "", "01 0xD  ----- ----- ---- ---- ---- ----",
312
   EF (l_cust2), 0, it_unknown},
313
  {"l.cust3", "", "01 0xE  ----- ----- ---- ---- ---- ----",
314
   EF (l_cust3), 0, it_unknown},
315
  {"l.cust4", "", "01 0xF  ----- ----- ---- ---- ---- ----",
316
   EF (l_cust4), 0, it_unknown},
317
 
318
  {"l.ld", "rD,I(rA)", "10 0x0  DDDDD AAAAA IIII IIII IIII IIII", EFI,
319
   0, it_load},
320
  {"l.lwz", "rD,I(rA)", "10 0x1  DDDDD AAAAA IIII IIII IIII IIII",
321
   EF (l_lwz), 0, it_load},
322
  {"l.lws", "rD,I(rA)", "10 0x2  DDDDD AAAAA IIII IIII IIII IIII", EFI,
323
   0, it_load},
324
  {"l.lbz", "rD,I(rA)", "10 0x3  DDDDD AAAAA IIII IIII IIII IIII",
325
   EF (l_lbz), 0, it_load},
326
  {"l.lbs", "rD,I(rA)", "10 0x4  DDDDD AAAAA IIII IIII IIII IIII",
327
   EF (l_lbs), 0, it_load},
328
  {"l.lhz", "rD,I(rA)", "10 0x5  DDDDD AAAAA IIII IIII IIII IIII",
329
   EF (l_lhz), 0, it_load},
330
  {"l.lhs", "rD,I(rA)", "10 0x6  DDDDD AAAAA IIII IIII IIII IIII",
331
   EF (l_lhs), 0, it_load},
332
 
333
  {"l.addi", "rD,rA,I", "10 0x7  DDDDD AAAAA IIII IIII IIII IIII",
334
   EF (l_add), OR32_W_FLAG, it_arith},
335
  {"l.addic", "rD,rA,I", "10 0x8  DDDDD AAAAA IIII IIII IIII IIII", EFI,
336
   0, it_arith},
337
  {"l.andi", "rD,rA,K", "10 0x9  DDDDD AAAAA KKKK KKKK KKKK KKKK",
338
   EF (l_and), OR32_W_FLAG, it_arith},
339
  {"l.ori", "rD,rA,K", "10 0xA  DDDDD AAAAA KKKK KKKK KKKK KKKK",
340
   EF (l_or), 0, it_arith},
341
  {"l.xori", "rD,rA,I", "10 0xB  DDDDD AAAAA IIII IIII IIII IIII",
342
   EF (l_xor), 0, it_arith},
343
  {"l.muli", "rD,rA,I", "10 0xC  DDDDD AAAAA IIII IIII IIII IIII",
344
   EF (l_mul), 0, it_arith},
345
  {"l.mfspr", "rD,rA,K", "10 0xD  DDDDD AAAAA KKKK KKKK KKKK KKKK",
346
   EF (l_mfspr), 0, it_move},
347
  {"l.slli", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 00LL LLLL",
348
   EF (l_sll), 0, it_shift},
349
  {"l.srli", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 01LL LLLL",
350
   EF (l_srl), 0, it_shift},
351
  {"l.srai", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 10LL LLLL",
352
   EF (l_sra), 0, it_shift},
353
  {"l.rori", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 11LL LLLL", EFI,
354
   0, it_shift},
355
 
356
  {"l.sfeqi", "rA,I", "10 0xF  00000 AAAAA IIII IIII IIII IIII",
357
   EF (l_sfeq), OR32_W_FLAG, it_compare},
358
  {"l.sfnei", "rA,I", "10 0xF  00001 AAAAA IIII IIII IIII IIII",
359
   EF (l_sfne), OR32_W_FLAG, it_compare},
360
  {"l.sfgtui", "rA,I", "10 0xF  00010 AAAAA IIII IIII IIII IIII",
361
   EF (l_sfgtu), OR32_W_FLAG, it_compare},
362
  {"l.sfgeui", "rA,I", "10 0xF  00011 AAAAA IIII IIII IIII IIII",
363
   EF (l_sfgeu), OR32_W_FLAG, it_compare},
364
  {"l.sfltui", "rA,I", "10 0xF  00100 AAAAA IIII IIII IIII IIII",
365
   EF (l_sfltu), OR32_W_FLAG, it_compare},
366
  {"l.sfleui", "rA,I", "10 0xF  00101 AAAAA IIII IIII IIII IIII",
367
   EF (l_sfleu), OR32_W_FLAG, it_compare},
368
  {"l.sfgtsi", "rA,I", "10 0xF  01010 AAAAA IIII IIII IIII IIII",
369
   EF (l_sfgts), OR32_W_FLAG, it_compare},
370
  {"l.sfgesi", "rA,I", "10 0xF  01011 AAAAA IIII IIII IIII IIII",
371
   EF (l_sfges), OR32_W_FLAG, it_compare},
372
  {"l.sfltsi", "rA,I", "10 0xF  01100 AAAAA IIII IIII IIII IIII",
373
   EF (l_sflts), OR32_W_FLAG, it_compare},
374
  {"l.sflesi", "rA,I", "10 0xF  01101 AAAAA IIII IIII IIII IIII",
375
   EF (l_sfles), OR32_W_FLAG, it_compare},
376
 
377
  {"l.mtspr", "rA,rB,K", "11 0x0  KKKKK AAAAA BBBB BKKK KKKK KKKK",
378
   EF (l_mtspr), 0, it_move},
379
  {"l.mac", "rA,rB", "11 0x1  ----- AAAAA BBBB B--- ---- 0x1",
380
   EF (l_mac), 0, it_mac},
381
  {"l.msb", "rA,rB", "11 0x1  ----- AAAAA BBBB B--- ---- 0x2",
382
   EF (l_msb), 0, it_mac},
383
 
384
  {"lf.add.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x0",
385
   EF (lf_add_s), 0, it_float},
386
  {"lf.sub.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x1",
387
   EF (lf_sub_s), 0, it_float},
388
  {"lf.mul.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x2",
389
   EF (lf_mul_s), 0, it_float},
390
  {"lf.div.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x3",
391
   EF (lf_div_s), 0, it_float},
392
  {"lf.itof.s", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x0 0x4",
393
   EF (lf_itof_s), 0, it_float},
394
  {"lf.ftoi.s", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x0 0x5",
395
   EF (lf_ftoi_s), 0, it_float},
396
  {"lf.rem.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x6",
397
   EF (lf_rem_s), 0, it_float},
398
  {"lf.madd.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x7",
399
   EF (lf_madd_s), 0, it_float},
400
  {"lf.sfeq.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0x8",
401
   EF (lf_sfeq_s), 0, it_float},
402
  {"lf.sfne.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0x9",
403
   EF (lf_sfne_s), 0, it_float},
404
  {"lf.sfgt.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xA",
405
   EF (lf_sfgt_s), 0, it_float},
406
  {"lf.sfge.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xB",
407
   EF (lf_sfge_s), 0, it_float},
408
  {"lf.sflt.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xC",
409
   EF (lf_sflt_s), 0, it_float},
410
  {"lf.sfle.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xD",
411
   EF (lf_sfle_s), 0, it_float},
412
  {"lf.cust1.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0xD ----", EFI,
413
   0, it_float},
414
 
415
  {"lf.add.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0,
416
   it_float},
417
  {"lf.sub.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0,
418
   it_float},
419
  {"lf.mul.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0,
420
   it_float},
421
  {"lf.div.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0,
422
   it_float},
423
  {"lf.itof.d", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x1 0x4", EFI, 0,
424
   it_float},
425
  {"lf.ftoi.d", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x1 0x5", EFI, 0,
426
   it_float},
427
  {"lf.rem.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0,
428
   it_float},
429
  {"lf.madd.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0,
430
   it_float},
431
  {"lf.sfeq.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0,
432
   it_float},
433
  {"lf.sfne.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0,
434
   it_float},
435
  {"lf.sfgt.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0,
436
   it_float},
437
  {"lf.sfge.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0,
438
   it_float},
439
  {"lf.sflt.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0,
440
   it_float},
441
  {"lf.sfle.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0,
442
   it_float},
443
  {"lf.cust1.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0xE ----", EFI, 0,
444
   it_float},
445
 
446
  {"l.sd", "I(rA),rB", "11 0x4  IIIII AAAAA BBBB BIII IIII IIII", EFI,
447
   0, it_store},
448
  {"l.sw", "I(rA),rB", "11 0x5  IIIII AAAAA BBBB BIII IIII IIII",
449
   EF (l_sw), 0, it_store},
450
  {"l.sb", "I(rA),rB", "11 0x6  IIIII AAAAA BBBB BIII IIII IIII",
451
   EF (l_sb), 0, it_store},
452
  {"l.sh", "I(rA),rB", "11 0x7  IIIII AAAAA BBBB BIII IIII IIII",
453
   EF (l_sh), 0, it_store},
454
 
455
  {"l.add", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x0",
456
   EF (l_add), OR32_W_FLAG, it_arith},
457
  {"l.addc", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x1",
458
   EF (l_addc), OR32_W_FLAG, it_arith},
459
  {"l.sub", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x2",
460
   EF (l_sub), 0, it_arith},
461
  {"l.and", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x3",
462
   EF (l_and), OR32_W_FLAG, it_arith},
463
  {"l.or", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x4",
464
   EF (l_or), 0, it_arith},
465
  {"l.xor", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x5",
466
   EF (l_xor), 0, it_arith},
467
  {"l.mul", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0x6",
468
   EF (l_mul), 0, it_arith},
469
 
470
  {"l.sll", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0x8",
471
   EF (l_sll), 0, it_shift},
472
  {"l.srl", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0x8",
473
   EF (l_srl), 0, it_shift},
474
  {"l.sra", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0x8",
475
   EF (l_sra), 0, it_shift},
476
  {"l.ror", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0x8", EFI,
477
   0, it_shift},
478
  {"l.div", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0x9",
479
   EF (l_div), 0, it_arith},
480
  {"l.divu", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xA",
481
   EF (l_divu), 0, it_arith},
482
  {"l.mulu", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xB", EFI,
483
   0, it_arith},
484
  {"l.extbs", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 01-- 0xC",
485
   EF (l_extbs), 0, it_move},
486
  {"l.exths", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 00-- 0xC",
487
   EF (l_exths), 0, it_move},
488
  {"l.extws", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 00-- 0xD",
489
   EF (l_extws), 0, it_move},
490
  {"l.extbz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 11-- 0xC",
491
   EF (l_extbz), 0, it_move},
492
  {"l.exthz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 10-- 0xC",
493
   EF (l_exthz), 0, it_move},
494
  {"l.extwz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 01-- 0xD",
495
   EF (l_extwz), 0, it_move},
496
  {"l.cmov", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xE",
497
   EF (l_cmov), OR32_R_FLAG, it_move},
498
  {"l.ff1", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 ---- 0xF",
499
   EF (l_ff1), 0, it_arith},
500
  {"l.fl1", "rD,rA", "11 0x8  DDDDD AAAAA ---- --01 ---- 0xF", EFI, 0,
501
   it_arith},
502
 
503
  {"l.sfeq", "rA,rB", "11 0x9  00000 AAAAA BBBB B--- ---- ----",
504
   EF (l_sfeq), OR32_W_FLAG, it_compare},
505
  {"l.sfne", "rA,rB", "11 0x9  00001 AAAAA BBBB B--- ---- ----",
506
   EF (l_sfne), OR32_W_FLAG, it_compare},
507
  {"l.sfgtu", "rA,rB", "11 0x9  00010 AAAAA BBBB B--- ---- ----",
508
   EF (l_sfgtu), OR32_W_FLAG, it_compare},
509
  {"l.sfgeu", "rA,rB", "11 0x9  00011 AAAAA BBBB B--- ---- ----",
510
   EF (l_sfgeu), OR32_W_FLAG, it_compare},
511
  {"l.sfltu", "rA,rB", "11 0x9  00100 AAAAA BBBB B--- ---- ----",
512
   EF (l_sfltu), OR32_W_FLAG, it_compare},
513
  {"l.sfleu", "rA,rB", "11 0x9  00101 AAAAA BBBB B--- ---- ----",
514
   EF (l_sfleu), OR32_W_FLAG, it_compare},
515
  {"l.sfgts", "rA,rB", "11 0x9  01010 AAAAA BBBB B--- ---- ----",
516
   EF (l_sfgts), OR32_W_FLAG, it_compare},
517
  {"l.sfges", "rA,rB", "11 0x9  01011 AAAAA BBBB B--- ---- ----",
518
   EF (l_sfges), OR32_W_FLAG, it_compare},
519
  {"l.sflts", "rA,rB", "11 0x9  01100 AAAAA BBBB B--- ---- ----",
520
   EF (l_sflts), OR32_W_FLAG, it_compare},
521
  {"l.sfles", "rA,rB", "11 0x9  01101 AAAAA BBBB B--- ---- ----",
522
   EF (l_sfles), OR32_W_FLAG, it_compare},
523
 
524
  {"l.cust5", "rD,rA,rB,L,K", "11 0xC  DDDDD AAAAA BBBB BLLL LLLK KKKK", EFI,
525
   0, it_unknown},
526
  {"l.cust6", "", "11 0xD  ----- ----- ---- ---- ---- ----", EFI,
527
   0, it_unknown},
528
  {"l.cust7", "", "11 0xE  ----- ----- ---- ---- ---- ----", EFI,
529
   0, it_unknown},
530
  {"l.cust8", "", "11 0xF  ----- ----- ---- ---- ---- ----", EFI,
531
   0, it_unknown},
532
 
533
/* This section should not be defined in or1ksim, since it contains duplicates,
534
   which would cause machine builder to complain.  */
535
#ifdef HAS_CUST
536
  {"l.cust5_1", "rD", "11 0xC  DDDDD ----- ---- ---- ---- ----", EFI,
537
   0, it_unknown},
538
  {"l.cust5_2", "rD,rA", "11 0xC  DDDDD AAAAA ---- ---- ---- ----", EFI,
539
   0, it_unknown},
540
  {"l.cust5_3", "rD,rA,rB", "11 0xC  DDDDD AAAAA BBBB B--- ---- ----", EFI,
541
   0, it_unknown},
542
 
543
  {"l.cust6_1", "rD", "11 0xD  DDDDD ----- ---- ---- ---- ----", EFI,
544
   0, it_unknown},
545
  {"l.cust6_2", "rD,rA", "11 0xD  DDDDD AAAAA ---- ---- ---- ----", EFI,
546
   0, it_unknown},
547
  {"l.cust6_3", "rD,rA,rB", "11 0xD  DDDDD AAAAA BBBB B--- ---- ----", EFI,
548
   0, it_unknown},
549
 
550
  {"l.cust7_1", "rD", "11 0xE  DDDDD ----- ---- ---- ---- ----", EFI,
551
   0, it_unknown},
552
  {"l.cust7_2", "rD,rA", "11 0xE  DDDDD AAAAA ---- ---- ---- ----", EFI,
553
   0, it_unknown},
554
  {"l.cust7_3", "rD,rA,rB", "11 0xE  DDDDD AAAAA BBBB B--- ---- ----", EFI,
555
   0, it_unknown},
556
 
557
  {"l.cust8_1", "rD", "11 0xF  DDDDD ----- ---- ---- ---- ----", EFI,
558
   0, it_unknown},
559
  {"l.cust8_2", "rD,rA", "11 0xF  DDDDD AAAAA ---- ---- ---- ----", EFI,
560
   0, it_unknown},
561
  {"l.cust8_3", "rD,rA,rB", "11 0xF  DDDDD AAAAA BBBB B--- ---- ----", EFI,
562
   0, it_unknown},
563
#endif
564
 
565
  {"", "", "", EFI, 0, 0} /* Dummy entry, not included in num_opcodes.  This
566
                                 * lets code examine entry i+1 without checking
567
                                 * if we've run off the end of the table.  */
568
};
569
 
570
#undef EFI
571
#undef EFN
572
#undef EF
573
 
574
CONST int num_opcodes =
575
  ((sizeof (or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
576
 
577
/* Calculates instruction length in bytes. Always 4 for OR32. */
578
int
579
insn_len (int insn_index)
580
{
581
  insn_index = 0;                /* Just to get rid that warning.  */
582
  return 4;
583
}
584
 
585
/* Is individual insn's operand signed or unsigned? */
586
int
587
letter_signed (char l)
588
{
589
  CONST struct or32_letter *pletter;
590
 
591
  for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
592
    if (pletter->letter == l)
593
      return pletter->sign;
594
 
595
  printf ("letter_signed(%c): Unknown letter.\n", l);
596
  return 0;
597
}
598
 
599
/* Simple cache for letter ranges */
600
static int range_cache[256] = { 0 };
601
 
602
/* Number of letters in the individual lettered operand. */
603
int
604
letter_range (char l)
605
{
606
  CONST struct or32_opcode *pinsn;
607
  char *enc;
608
  int range = 0;
609
 
610
  /* Is value cached? */
611
  if ((range = range_cache[(unsigned char) l]))
612
    return range;
613
 
614
  for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn++)
615
    {
616
      if (strchr (pinsn->encoding, l))
617
        {
618
          for (enc = pinsn->encoding; *enc != '\0'; enc++)
619
            if ((*enc == '0') && (*(enc + 1) == 'x'))
620
              enc += 2;
621
            else if (*enc == l)
622
              range++;
623
          return range_cache[(unsigned char) l] = range;
624
        }
625
    }
626
 
627
  printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
628
  exit (1);
629
}
630
 
631
/* MM: Returns index of given instruction name.  */
632
int
633
insn_index (char *insn)
634
{
635
  int i, found = -1;
636
  for (i = 0; i < num_opcodes; i++)
637
    if (!strcmp (or32_opcodes[i].name, insn))
638
      {
639
        found = i;
640
        break;
641
      }
642
  return found;
643
}
644
 
645
/* Returns name of the specified instruction index */
646
CONST char *
647
insn_name (int index)
648
{
649
  if (index >= 0 && index < num_opcodes)
650
    return or32_opcodes[index].name;
651
  else
652
    return "???";
653
}
654
 
655
#if defined(HAVE_EXECUTION) && SIMPLE_EXECUTION
656
void
657
l_none (struct iqueue_entry *current)
658
{
659
}
660
#elif defined(HAVE_EXECUTION) && DYNAMIC_EXECUTION
661
void
662
l_none (struct op_queue *opq, int *param_t, int delay_slot)
663
{
664
}
665
#else
666
void
667
l_none ()
668
{
669
}
670
#endif
671
 
672
/*** Finite automata for instruction decoding building code ***/
673
 
674
/* Find symbols in encoding.  */
675
unsigned long
676
insn_extract (param_ch, enc_initial)
677
     char param_ch;
678
     char *enc_initial;
679
{
680
  char *enc;
681
  unsigned long ret = 0;
682
  unsigned opc_pos = 32;
683
  for (enc = enc_initial; *enc != '\0';)
684
    if ((*enc == '0') && (*(enc + 1) == 'x'))
685
      {
686
        unsigned long tmp = strtol (enc + 2, NULL, 16);
687
        opc_pos -= 4;
688
        if (param_ch == '0' || param_ch == '1')
689
          {
690
            if (param_ch == '0')
691
              tmp = 15 - tmp;
692
            ret |= tmp << opc_pos;
693
          }
694
        enc += 3;
695
      }
696
    else
697
      {
698
        if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha (*enc))
699
          {
700
            opc_pos--;
701
            if (param_ch == *enc)
702
              ret |= 1 << opc_pos;
703
          }
704
        enc++;
705
      }
706
  return ret;
707
}
708
 
709
#define MAX_AUTOMATA_SIZE (1200)
710
#define MAX_OP_TABLE_SIZE (1200)
711
#define MAX_LEN           (8)
712
 
713
#ifndef MIN
714
# define MIN(x,y)          ((x) < (y) ? (x) : (y))
715
#endif
716
 
717
unsigned long *automata;
718
int nuncovered;
719
int curpass = 0;
720
 
721
/* MM: Struct that holds runtime build information about instructions.  */
722
struct temp_insn_struct *ti;
723
 
724
struct insn_op_struct *op_data, **op_start;
725
 
726
static void
727
or32_debug (int level, const char *format, ...)
728
{
729
#if DEBUG
730
  char *p;
731
  va_list ap;
732
 
733
  if ((p = malloc (1000)) == NULL)
734
    return;
735
  va_start (ap, format);
736
  (void) vsnprintf (p, 1000, format, ap);
737
  va_end (ap);
738
  printf ("%s\n", p);
739
  fflush (stdout);
740
  free (p);
741
#endif
742
}
743
 
744
/* Recursive utility function used to find best match and to build automata.  */
745
static unsigned long *
746
cover_insn (unsigned long *cur, int pass, unsigned int mask)
747
{
748
  int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
749
  unsigned long cur_mask = mask;
750
  unsigned long *next;
751
 
752
  for (i = 0; i < num_opcodes; i++)
753
    if (ti[i].in_pass == pass)
754
      {
755
        cur_mask &= ti[i].insn_mask;
756
        ninstr++;
757
        last_match = i;
758
      }
759
 
760
  or32_debug (8, "%08X %08lX\n", mask, cur_mask);
761
  if (ninstr == 0)
762
    return 0;
763
  if (ninstr == 1)
764
    {
765
      /* Leaf holds instruction index. */
766
      or32_debug (8, "%i>I%i %s\n", cur - automata, last_match,
767
             or32_opcodes[last_match].name);
768
      *cur = LEAF_FLAG | last_match;
769
      cur++;
770
      nuncovered--;
771
    }
772
  else
773
    {
774
      /* Find longest match.  */
775
      for (i = 0; i < 32; i++)
776
        {
777
          int len;
778
          for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
779
            {
780
              unsigned long m = (1UL << ((unsigned long) len)) - 1;
781
              or32_debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)", len, m,
782
                     cur_mask, i, (cur_mask >> (unsigned) i),
783
                     (cur_mask >> (unsigned) i) & m);
784
              if ((m & (cur_mask >> (unsigned) i)) == m)
785
                {
786
                  best_len = len;
787
                  best_first = i;
788
                  or32_debug (9, "!");
789
                }
790
              else
791
                break;
792
            }
793
        }
794
      or32_debug (9, "\n");
795
      if (!best_len)
796
        {
797
          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
798
                   mask);
799
          for (i = 0; i < num_opcodes; i++)
800
            if (ti[i].in_pass == pass)
801
              fprintf (stderr, "%s ", or32_opcodes[i].name);
802
 
803
          fprintf (stderr, "\n");
804
          exit (1);
805
        }
806
      or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len,
807
             best_first, ninstr);
808
      *cur = best_first;
809
      cur++;
810
      *cur = (1 << best_len) - 1;
811
      cur++;
812
      next = cur;
813
      /* Allocate space for pointers.  */
814
      cur += 1 << best_len;
815
      cur_mask = (1 << (unsigned long) best_len) - 1;
816
 
817
      for (i = 0; i < (1 << (unsigned long) best_len); i++)
818
        {
819
          int j;
820
          unsigned long *c;
821
          curpass++;
822
          for (j = 0; j < num_opcodes; j++)
823
            if (ti[j].in_pass == pass
824
                && ((ti[j].insn >> best_first) & cur_mask) ==
825
                (unsigned long) i
826
                && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
827
              ti[j].in_pass = curpass;
828
 
829
          or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
830
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
831
          if (c)
832
            {
833
              or32_debug (8, "%i> #%X -> %u\n", next - automata, i,
834
                     cur - automata);
835
              *next = cur - automata;
836
              cur = c;
837
            }
838
          else
839
            {
840
              or32_debug (8, "%i> N/A\n", next - automata);
841
              *next = 0;
842
            }
843
          next++;
844
        }
845
    }
846
  return cur;
847
}
848
 
849
/* Returns number of nonzero bits. */
850
static int
851
num_ones (unsigned long value)
852
{
853
  int c = 0;
854
  while (value)
855
    {
856
      if (value & 1)
857
        c++;
858
      value >>= 1;
859
    }
860
  return c;
861
}
862
 
863
/* Utility function, which converts parameters from or32_opcode format to more binary form.
864
   Parameters are stored in ti struct.  */
865
 
866
static struct insn_op_struct *
867
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
868
{
869
  char *args = opcode->args;
870
  int i, type;
871
  int num_cur_op = 0;;
872
 
873
  i = 0;
874
  type = 0;
875
  /* In case we don't have any parameters, we add dummy read from r0.  */
876
  if (!(*args))
877
    {
878
      cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
879
      cur->data = 0;
880
      or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
881
      cur++;
882
      return cur;
883
    }
884
 
885
  while (*args != '\0')
886
    {
887
      if (*args == 'r')
888
        {
889
          args++;
890
          type |= OPTYPE_REG;
891
          if (*args == 'D')
892
            type |= OPTYPE_DST;
893
        }
894
      else if (isalpha (*args))
895
        {
896
          unsigned long arg;
897
          arg = insn_extract (*args, opcode->encoding);
898
          or32_debug (9, "%s : %08lX ------\n", opcode->name, arg);
899
          if (letter_signed (*args))
900
            {
901
              type |= OPTYPE_SIG;
902
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
903
            }
904
 
905
          num_cur_op = 0;
906
          /* Split argument to sequences of consecutive ones.  */
907
          while (arg)
908
            {
909
              int shr = 0;
910
              unsigned long tmp = arg, mask = 0;
911
              while ((tmp & 1) == 0)
912
                {
913
                  shr++;
914
                  tmp >>= 1;
915
                }
916
              while (tmp & 1)
917
                {
918
                  mask++;
919
                  tmp >>= 1;
920
                }
921
              cur->type = type | shr;
922
              cur->data = mask;
923
              arg &= ~(((1 << mask) - 1) << shr);
924
              or32_debug (6, "|%08lX %08lX\n", cur->type, cur->data);
925
              cur++;
926
              num_cur_op++;
927
            }
928
          args++;
929
        }
930
      else if (*args == '(')
931
        {
932
          /* Next param is displacement.  Later we will treat them as one operand.  */
933
          /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
934
           * operand */
935
          while (num_cur_op > 0)
936
            {
937
              cur[-num_cur_op].type |= type | OPTYPE_DIS;
938
              num_cur_op--;
939
            }
940
          cur[-1].type |= OPTYPE_OP;
941
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
942
          type = 0;
943
          i++;
944
          args++;
945
        }
946
      else if (*args == OPERAND_DELIM)
947
        {
948
          cur--;
949
          cur->type = type | cur->type | OPTYPE_OP;
950
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
951
          cur++;
952
          type = 0;
953
          i++;
954
          args++;
955
        }
956
      else if (*args == '0')
957
        {
958
          cur->type = type;
959
          cur->data = 0;
960
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
961
          cur++;
962
          type = 0;
963
          i++;
964
          args++;
965
        }
966
      else if (*args == ')')
967
        args++;
968
      else
969
        {
970
          fprintf (stderr, "%s : parse error in args.\n", opcode->name);
971
          exit (1);
972
        }
973
    }
974
  cur--;
975
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
976
  or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
977
  cur++;
978
  return cur;
979
}
980
 
981
/* Constructs new automata based on or32_opcodes array.  */
982
 
983
void
984
build_automata ()
985
{
986
  int i;
987
  unsigned long *end;
988
  struct insn_op_struct *cur;
989
 
990
  automata =
991
    (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
992
  ti =
993
    (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
994
                                        num_opcodes);
995
 
996
  nuncovered = num_opcodes;
997
 
998
#ifdef HAVE_EXECUTION
999
  printf ("Building automata... ");
1000
#endif
1001
 
1002
  /* Build temporary information about instructions.  */
1003
  for (i = 0; i < num_opcodes; i++)
1004
    {
1005
      unsigned long ones, zeros;
1006
      char *encoding = or32_opcodes[i].encoding;
1007
      ones = insn_extract ('1', encoding);
1008
      zeros = insn_extract ('0', encoding);
1009
      ti[i].insn_mask = ones | zeros;
1010
      ti[i].insn = ones;
1011
      ti[i].in_pass = curpass = 0;
1012
      /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
1013
         or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn); */
1014
    }
1015
 
1016
  /* Until all are covered search for best criteria to separate them.  */
1017
  end = cover_insn (automata, curpass, 0xFFFFFFFF);
1018
  if (end - automata > MAX_AUTOMATA_SIZE)
1019
    {
1020
      fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
1021
      exit (1);
1022
    }
1023
#ifdef HAVE_EXECUTION
1024
  printf ("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
1025
#endif
1026
 
1027
#ifdef HAVE_EXECUTION
1028
  printf ("Parsing operands data... ");
1029
#endif
1030
  op_data =
1031
    (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
1032
                                      sizeof (struct insn_op_struct));
1033
  op_start =
1034
    (struct insn_op_struct **) malloc (num_opcodes *
1035
                                       sizeof (struct insn_op_struct *));
1036
  cur = op_data;
1037
  for (i = 0; i < num_opcodes; i++)
1038
    {
1039
      op_start[i] = cur;
1040
      cur = parse_params (&or32_opcodes[i], cur);
1041
      if (cur - op_data > MAX_OP_TABLE_SIZE)
1042
        {
1043
          fprintf (stderr,
1044
                   "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
1045
          exit (1);
1046
        }
1047
    }
1048
#ifdef HAVE_EXECUTION
1049
  printf ("done.\n");
1050
#endif
1051
}
1052
 
1053
void
1054
destruct_automata ()
1055
{
1056
  free (ti);
1057
  free (automata);
1058
  free (op_data);
1059
  free (op_start);
1060
}
1061
 
1062
/* Decodes instruction and returns instruction index.  */
1063
int
1064
insn_decode (unsigned int insn)
1065
{
1066
  unsigned long *a = automata;
1067
  int i;
1068
  while (!(*a & LEAF_FLAG))
1069
    {
1070
      unsigned int first = *a;
1071
      //debug(9, "%i ", a - automata);
1072
      a++;
1073
      i = (insn >> first) & *a;
1074
      a++;
1075
      if (!*(a + i))
1076
        {                       /* Invalid instruction found?  */
1077
          //debug(9, "XXX\n", i);
1078
          return -1;
1079
        }
1080
      a = automata + *(a + i);
1081
    }
1082
  i = *a & ~LEAF_FLAG;
1083
  //debug(9, "%i\n", i);
1084
  /* Final check - do we have direct match?
1085
     (based on or32_opcodes this should be the only possibility,
1086
     but in case of invalid/missing instruction we must perform a check)  */
1087
  if ((ti[i].insn_mask & insn) == ti[i].insn)
1088
    return i;
1089
  else
1090
    return -1;
1091
}
1092
 
1093
static char disassembled_str[50];
1094
char *disassembled = &disassembled_str[0];
1095
 
1096
/* Automagically does zero- or sign- extension and also finds correct
1097
   sign bit position if sign extension is correct extension. Which extension
1098
   is proper is figured out from letter description. */
1099
 
1100
unsigned long
1101
extend_imm (unsigned long imm, char l)
1102
{
1103
  unsigned long mask;
1104
  int letter_bits;
1105
 
1106
  /* First truncate all bits above valid range for this letter
1107
     in case it is zero extend. */
1108
  letter_bits = letter_range (l);
1109
  mask = (1 << letter_bits) - 1;
1110
  imm &= mask;
1111
 
1112
  /* Do sign extend if this is the right one. */
1113
  if (letter_signed (l) && (imm >> (letter_bits - 1)))
1114
    imm |= (~mask);
1115
 
1116
  return imm;
1117
}
1118
 
1119
unsigned long
1120
or32_extract (param_ch, enc_initial, insn)
1121
     char param_ch;
1122
     char *enc_initial;
1123
     unsigned long insn;
1124
{
1125
  char *enc;
1126
  unsigned long ret = 0;
1127
  int opc_pos = 0;
1128
  int param_pos = 0;
1129
 
1130
  for (enc = enc_initial; *enc != '\0'; enc++)
1131
    if (*enc == param_ch)
1132
      {
1133
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0')
1134
            && (*(enc - 1) == 'x'))
1135
          continue;
1136
        else
1137
          param_pos++;
1138
      }
1139
 
1140
#if DEBUG
1141
  printf ("or32_extract: %x ", param_pos);
1142
#endif
1143
  opc_pos = 32;
1144
  for (enc = enc_initial; *enc != '\0';)
1145
    if ((*enc == '0') && (*(enc + 1) == 'x'))
1146
      {
1147
        opc_pos -= 4;
1148
        if ((param_ch == '0') || (param_ch == '1'))
1149
          {
1150
            unsigned long tmp = strtol (enc, NULL, 16);
1151
#if DEBUG
1152
            printf (" enc=%s, tmp=%x ", enc, tmp);
1153
#endif
1154
            if (param_ch == '0')
1155
              tmp = 15 - tmp;
1156
            ret |= tmp << opc_pos;
1157
          }
1158
        enc += 3;
1159
      }
1160
    else if ((*enc == '0') || (*enc == '1'))
1161
      {
1162
        opc_pos--;
1163
        if (param_ch == *enc)
1164
          ret |= 1 << opc_pos;
1165
        enc++;
1166
      }
1167
    else if (*enc == param_ch)
1168
      {
1169
        opc_pos--;
1170
        param_pos--;
1171
#if DEBUG
1172
        printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos,
1173
                param_pos);
1174
#endif
1175
        if (islower (param_ch))
1176
          ret -= ((insn >> opc_pos) & 0x1) << param_pos;
1177
        else
1178
          ret += ((insn >> opc_pos) & 0x1) << param_pos;
1179
        enc++;
1180
      }
1181
    else if (isalpha (*enc))
1182
      {
1183
        opc_pos--;
1184
        enc++;
1185
      }
1186
    else if (*enc == '-')
1187
      {
1188
        opc_pos--;
1189
        enc++;
1190
      }
1191
    else
1192
      enc++;
1193
 
1194
#if DEBUG
1195
  printf ("ret=%x\n", ret);
1196
#endif
1197
  return ret;
1198
}
1199
 
1200
/* Print register. Used only by print_insn. */
1201
 
1202
static char *
1203
or32_print_register (dest, param_ch, encoding, insn)
1204
     char *dest;
1205
     char param_ch;
1206
     char *encoding;
1207
     unsigned long insn;
1208
{
1209
  int regnum = or32_extract (param_ch, encoding, insn);
1210
 
1211
  sprintf (dest, "r%d", regnum);
1212
  while (*dest)
1213
    dest++;
1214
  return dest;
1215
}
1216
 
1217
/* Print immediate. Used only by print_insn. */
1218
 
1219
static char *
1220
or32_print_immediate (dest, param_ch, encoding, insn)
1221
     char *dest;
1222
     char param_ch;
1223
     char *encoding;
1224
     unsigned long insn;
1225
{
1226
  int imm = or32_extract (param_ch, encoding, insn);
1227
 
1228
  imm = extend_imm (imm, param_ch);
1229
 
1230
  if (letter_signed (param_ch))
1231
    {
1232
      if (imm < 0)
1233
        sprintf (dest, "%d", imm);
1234
      else
1235
        sprintf (dest, "0x%x", imm);
1236
    }
1237
  else
1238
    sprintf (dest, "%#x", imm);
1239
  while (*dest)
1240
    dest++;
1241
  return dest;
1242
}
1243
 
1244
/* Disassemble one instruction from insn to disassemble.
1245
   Return the size of the instruction.  */
1246
 
1247
int
1248
disassemble_insn (insn)
1249
     unsigned long insn;
1250
{
1251
  return disassemble_index (insn, insn_decode (insn));
1252
}
1253
 
1254
/* Disassemble one instruction from insn index.
1255
   Return the size of the instruction.  */
1256
 
1257
int
1258
disassemble_index (insn, index)
1259
     unsigned long insn;
1260
     int index;
1261
{
1262
  char *dest = disassembled;
1263
  if (index >= 0)
1264
    {
1265
      struct or32_opcode const *opcode = &or32_opcodes[index];
1266
      char *s;
1267
 
1268
      strcpy (dest, opcode->name);
1269
      while (*dest)
1270
        dest++;
1271
      *dest++ = ' ';
1272
      *dest = 0;
1273
 
1274
      for (s = opcode->args; *s != '\0'; ++s)
1275
        {
1276
          switch (*s)
1277
            {
1278
            case '\0':
1279
              return insn_len (insn);
1280
 
1281
            case 'r':
1282
              dest = or32_print_register (dest, *++s, opcode->encoding, insn);
1283
              break;
1284
 
1285
            default:
1286
              if (strchr (opcode->encoding, *s))
1287
                dest =
1288
                  or32_print_immediate (dest, *s, opcode->encoding, insn);
1289
              else
1290
                {
1291
                  *dest++ = *s;
1292
                  *dest = 0;
1293
                }
1294
            }
1295
        }
1296
    }
1297
  else
1298
    {
1299
      /* This used to be %8x for binutils.  */
1300
      sprintf (dest, ".word 0x%08lx", insn);
1301
      while (*dest)
1302
        dest++;
1303
    }
1304
  return insn_len (insn);
1305
}

powered by: WebSVN 2.1.0

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