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

Subversion Repositories openrisc

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

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 116 jeremybenn
  {"l.maci", "rA,I", "01 0x3  ----- AAAAA IIII IIII IIII IIII",
308 19 jeremybenn
   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 104 jeremybenn
  {"l.lws", "rD,I(rA)", "10 0x2  DDDDD AAAAA IIII IIII IIII IIII",
323
   EF (l_lws), 0, it_load},
324 19 jeremybenn
  {"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 114 jeremybenn
  {"l.addic", "rD,rA,I", "10 0x8  DDDDD AAAAA IIII IIII IIII IIII",
336
   EF (l_addc), OR32_W_FLAG, it_arith},
337 19 jeremybenn
  {"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 127 jeremybenn
#if HAVE_UNSIGNED_XORI
342
  {"l.xori", "rD,rA,K", "10 0xB  DDDDD AAAAA KKKK KKKK KKKK KKKK",
343
   EF (l_xor), 0, it_arith},
344
#else
345 19 jeremybenn
  {"l.xori", "rD,rA,I", "10 0xB  DDDDD AAAAA IIII IIII IIII IIII",
346
   EF (l_xor), 0, it_arith},
347 127 jeremybenn
#endif
348 19 jeremybenn
  {"l.muli", "rD,rA,I", "10 0xC  DDDDD AAAAA IIII IIII IIII IIII",
349
   EF (l_mul), 0, it_arith},
350
  {"l.mfspr", "rD,rA,K", "10 0xD  DDDDD AAAAA KKKK KKKK KKKK KKKK",
351
   EF (l_mfspr), 0, it_move},
352
  {"l.slli", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 00LL LLLL",
353
   EF (l_sll), 0, it_shift},
354
  {"l.srli", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 01LL LLLL",
355
   EF (l_srl), 0, it_shift},
356
  {"l.srai", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 10LL LLLL",
357
   EF (l_sra), 0, it_shift},
358 122 jeremybenn
  {"l.rori", "rD,rA,L", "10 0xE  DDDDD AAAAA ---- ---- 11LL LLLL",
359
   EF (l_ror), 0, it_shift},
360 19 jeremybenn
 
361
  {"l.sfeqi", "rA,I", "10 0xF  00000 AAAAA IIII IIII IIII IIII",
362
   EF (l_sfeq), OR32_W_FLAG, it_compare},
363
  {"l.sfnei", "rA,I", "10 0xF  00001 AAAAA IIII IIII IIII IIII",
364
   EF (l_sfne), OR32_W_FLAG, it_compare},
365
  {"l.sfgtui", "rA,I", "10 0xF  00010 AAAAA IIII IIII IIII IIII",
366
   EF (l_sfgtu), OR32_W_FLAG, it_compare},
367
  {"l.sfgeui", "rA,I", "10 0xF  00011 AAAAA IIII IIII IIII IIII",
368
   EF (l_sfgeu), OR32_W_FLAG, it_compare},
369
  {"l.sfltui", "rA,I", "10 0xF  00100 AAAAA IIII IIII IIII IIII",
370
   EF (l_sfltu), OR32_W_FLAG, it_compare},
371
  {"l.sfleui", "rA,I", "10 0xF  00101 AAAAA IIII IIII IIII IIII",
372
   EF (l_sfleu), OR32_W_FLAG, it_compare},
373
  {"l.sfgtsi", "rA,I", "10 0xF  01010 AAAAA IIII IIII IIII IIII",
374
   EF (l_sfgts), OR32_W_FLAG, it_compare},
375
  {"l.sfgesi", "rA,I", "10 0xF  01011 AAAAA IIII IIII IIII IIII",
376
   EF (l_sfges), OR32_W_FLAG, it_compare},
377
  {"l.sfltsi", "rA,I", "10 0xF  01100 AAAAA IIII IIII IIII IIII",
378
   EF (l_sflts), OR32_W_FLAG, it_compare},
379
  {"l.sflesi", "rA,I", "10 0xF  01101 AAAAA IIII IIII IIII IIII",
380
   EF (l_sfles), OR32_W_FLAG, it_compare},
381
 
382
  {"l.mtspr", "rA,rB,K", "11 0x0  KKKKK AAAAA BBBB BKKK KKKK KKKK",
383
   EF (l_mtspr), 0, it_move},
384
  {"l.mac", "rA,rB", "11 0x1  ----- AAAAA BBBB B--- ---- 0x1",
385
   EF (l_mac), 0, it_mac},
386
  {"l.msb", "rA,rB", "11 0x1  ----- AAAAA BBBB B--- ---- 0x2",
387
   EF (l_msb), 0, it_mac},
388
 
389
  {"lf.add.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x0",
390
   EF (lf_add_s), 0, it_float},
391
  {"lf.sub.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x1",
392
   EF (lf_sub_s), 0, it_float},
393
  {"lf.mul.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x2",
394
   EF (lf_mul_s), 0, it_float},
395
  {"lf.div.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x3",
396
   EF (lf_div_s), 0, it_float},
397
  {"lf.itof.s", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x0 0x4",
398
   EF (lf_itof_s), 0, it_float},
399
  {"lf.ftoi.s", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x0 0x5",
400
   EF (lf_ftoi_s), 0, it_float},
401
  {"lf.rem.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x6",
402
   EF (lf_rem_s), 0, it_float},
403
  {"lf.madd.s", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x0 0x7",
404
   EF (lf_madd_s), 0, it_float},
405
  {"lf.sfeq.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0x8",
406
   EF (lf_sfeq_s), 0, it_float},
407
  {"lf.sfne.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0x9",
408
   EF (lf_sfne_s), 0, it_float},
409
  {"lf.sfgt.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xA",
410
   EF (lf_sfgt_s), 0, it_float},
411
  {"lf.sfge.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xB",
412
   EF (lf_sfge_s), 0, it_float},
413
  {"lf.sflt.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xC",
414
   EF (lf_sflt_s), 0, it_float},
415
  {"lf.sfle.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x0 0xD",
416
   EF (lf_sfle_s), 0, it_float},
417
  {"lf.cust1.s", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0xD ----", EFI,
418
   0, it_float},
419
 
420
  {"lf.add.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0,
421
   it_float},
422
  {"lf.sub.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0,
423
   it_float},
424
  {"lf.mul.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0,
425
   it_float},
426
  {"lf.div.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0,
427
   it_float},
428
  {"lf.itof.d", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x1 0x4", EFI, 0,
429
   it_float},
430
  {"lf.ftoi.d", "rD,rA", "11 0x2  DDDDD AAAAA 0000 0--- 0x1 0x5", EFI, 0,
431
   it_float},
432
  {"lf.rem.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0,
433
   it_float},
434
  {"lf.madd.d", "rD,rA,rB", "11 0x2  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0,
435
   it_float},
436
  {"lf.sfeq.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0,
437
   it_float},
438
  {"lf.sfne.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0,
439
   it_float},
440
  {"lf.sfgt.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0,
441
   it_float},
442
  {"lf.sfge.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0,
443
   it_float},
444
  {"lf.sflt.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0,
445
   it_float},
446
  {"lf.sfle.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0,
447
   it_float},
448
  {"lf.cust1.d", "rA,rB", "11 0x2  ----- AAAAA BBBB B--- 0xE ----", EFI, 0,
449
   it_float},
450
 
451
  {"l.sd", "I(rA),rB", "11 0x4  IIIII AAAAA BBBB BIII IIII IIII", EFI,
452
   0, it_store},
453
  {"l.sw", "I(rA),rB", "11 0x5  IIIII AAAAA BBBB BIII IIII IIII",
454
   EF (l_sw), 0, it_store},
455
  {"l.sb", "I(rA),rB", "11 0x6  IIIII AAAAA BBBB BIII IIII IIII",
456
   EF (l_sb), 0, it_store},
457
  {"l.sh", "I(rA),rB", "11 0x7  IIIII AAAAA BBBB BIII IIII IIII",
458
   EF (l_sh), 0, it_store},
459
 
460
  {"l.add", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x0",
461
   EF (l_add), OR32_W_FLAG, it_arith},
462
  {"l.addc", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x1",
463
   EF (l_addc), OR32_W_FLAG, it_arith},
464
  {"l.sub", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x2",
465
   EF (l_sub), 0, it_arith},
466
  {"l.and", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x3",
467
   EF (l_and), OR32_W_FLAG, it_arith},
468
  {"l.or", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x4",
469
   EF (l_or), 0, it_arith},
470
  {"l.xor", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x5",
471
   EF (l_xor), 0, it_arith},
472
  {"l.mul", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0x6",
473
   EF (l_mul), 0, it_arith},
474
 
475
  {"l.sll", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0x8",
476
   EF (l_sll), 0, it_shift},
477
  {"l.srl", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0x8",
478
   EF (l_srl), 0, it_shift},
479
  {"l.sra", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0x8",
480
   EF (l_sra), 0, it_shift},
481 122 jeremybenn
  {"l.ror", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0x8",
482
   EF (l_ror), 0, it_shift},
483 19 jeremybenn
  {"l.div", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0x9",
484
   EF (l_div), 0, it_arith},
485
  {"l.divu", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xA",
486
   EF (l_divu), 0, it_arith},
487 118 jeremybenn
  {"l.mulu", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xB",
488
   EF (l_mulu), 0, it_arith},
489 19 jeremybenn
  {"l.extbs", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 01-- 0xC",
490
   EF (l_extbs), 0, it_move},
491
  {"l.exths", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 00-- 0xC",
492
   EF (l_exths), 0, it_move},
493
  {"l.extws", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 00-- 0xD",
494
   EF (l_extws), 0, it_move},
495
  {"l.extbz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 11-- 0xC",
496
   EF (l_extbz), 0, it_move},
497
  {"l.exthz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 10-- 0xC",
498
   EF (l_exthz), 0, it_move},
499
  {"l.extwz", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 01-- 0xD",
500
   EF (l_extwz), 0, it_move},
501
  {"l.cmov", "rD,rA,rB", "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xE",
502
   EF (l_cmov), OR32_R_FLAG, it_move},
503
  {"l.ff1", "rD,rA", "11 0x8  DDDDD AAAAA ---- --00 ---- 0xF",
504
   EF (l_ff1), 0, it_arith},
505 115 jeremybenn
  {"l.fl1", "rD,rA", "11 0x8  DDDDD AAAAA ---- --01 ---- 0xF",
506
   EF (l_fl1), 0, it_arith},
507 19 jeremybenn
 
508
  {"l.sfeq", "rA,rB", "11 0x9  00000 AAAAA BBBB B--- ---- ----",
509
   EF (l_sfeq), OR32_W_FLAG, it_compare},
510
  {"l.sfne", "rA,rB", "11 0x9  00001 AAAAA BBBB B--- ---- ----",
511
   EF (l_sfne), OR32_W_FLAG, it_compare},
512
  {"l.sfgtu", "rA,rB", "11 0x9  00010 AAAAA BBBB B--- ---- ----",
513
   EF (l_sfgtu), OR32_W_FLAG, it_compare},
514
  {"l.sfgeu", "rA,rB", "11 0x9  00011 AAAAA BBBB B--- ---- ----",
515
   EF (l_sfgeu), OR32_W_FLAG, it_compare},
516
  {"l.sfltu", "rA,rB", "11 0x9  00100 AAAAA BBBB B--- ---- ----",
517
   EF (l_sfltu), OR32_W_FLAG, it_compare},
518
  {"l.sfleu", "rA,rB", "11 0x9  00101 AAAAA BBBB B--- ---- ----",
519
   EF (l_sfleu), OR32_W_FLAG, it_compare},
520
  {"l.sfgts", "rA,rB", "11 0x9  01010 AAAAA BBBB B--- ---- ----",
521
   EF (l_sfgts), OR32_W_FLAG, it_compare},
522
  {"l.sfges", "rA,rB", "11 0x9  01011 AAAAA BBBB B--- ---- ----",
523
   EF (l_sfges), OR32_W_FLAG, it_compare},
524
  {"l.sflts", "rA,rB", "11 0x9  01100 AAAAA BBBB B--- ---- ----",
525
   EF (l_sflts), OR32_W_FLAG, it_compare},
526
  {"l.sfles", "rA,rB", "11 0x9  01101 AAAAA BBBB B--- ---- ----",
527
   EF (l_sfles), OR32_W_FLAG, it_compare},
528
 
529
  {"l.cust5", "rD,rA,rB,L,K", "11 0xC  DDDDD AAAAA BBBB BLLL LLLK KKKK", EFI,
530
   0, it_unknown},
531
  {"l.cust6", "", "11 0xD  ----- ----- ---- ---- ---- ----", EFI,
532
   0, it_unknown},
533
  {"l.cust7", "", "11 0xE  ----- ----- ---- ---- ---- ----", EFI,
534
   0, it_unknown},
535
  {"l.cust8", "", "11 0xF  ----- ----- ---- ---- ---- ----", EFI,
536
   0, it_unknown},
537
 
538
/* This section should not be defined in or1ksim, since it contains duplicates,
539
   which would cause machine builder to complain.  */
540
#ifdef HAS_CUST
541
  {"l.cust5_1", "rD", "11 0xC  DDDDD ----- ---- ---- ---- ----", EFI,
542
   0, it_unknown},
543
  {"l.cust5_2", "rD,rA", "11 0xC  DDDDD AAAAA ---- ---- ---- ----", EFI,
544
   0, it_unknown},
545
  {"l.cust5_3", "rD,rA,rB", "11 0xC  DDDDD AAAAA BBBB B--- ---- ----", EFI,
546
   0, it_unknown},
547
 
548
  {"l.cust6_1", "rD", "11 0xD  DDDDD ----- ---- ---- ---- ----", EFI,
549
   0, it_unknown},
550
  {"l.cust6_2", "rD,rA", "11 0xD  DDDDD AAAAA ---- ---- ---- ----", EFI,
551
   0, it_unknown},
552
  {"l.cust6_3", "rD,rA,rB", "11 0xD  DDDDD AAAAA BBBB B--- ---- ----", EFI,
553
   0, it_unknown},
554
 
555
  {"l.cust7_1", "rD", "11 0xE  DDDDD ----- ---- ---- ---- ----", EFI,
556
   0, it_unknown},
557
  {"l.cust7_2", "rD,rA", "11 0xE  DDDDD AAAAA ---- ---- ---- ----", EFI,
558
   0, it_unknown},
559
  {"l.cust7_3", "rD,rA,rB", "11 0xE  DDDDD AAAAA BBBB B--- ---- ----", EFI,
560
   0, it_unknown},
561
 
562
  {"l.cust8_1", "rD", "11 0xF  DDDDD ----- ---- ---- ---- ----", EFI,
563
   0, it_unknown},
564
  {"l.cust8_2", "rD,rA", "11 0xF  DDDDD AAAAA ---- ---- ---- ----", EFI,
565
   0, it_unknown},
566
  {"l.cust8_3", "rD,rA,rB", "11 0xF  DDDDD AAAAA BBBB B--- ---- ----", EFI,
567
   0, it_unknown},
568
#endif
569
 
570
  {"", "", "", EFI, 0, 0} /* Dummy entry, not included in num_opcodes.  This
571
                                 * lets code examine entry i+1 without checking
572
                                 * if we've run off the end of the table.  */
573
};
574
 
575
#undef EFI
576
#undef EFN
577
#undef EF
578
 
579
CONST int num_opcodes =
580
  ((sizeof (or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
581
 
582
/* Calculates instruction length in bytes. Always 4 for OR32. */
583
int
584
insn_len (int insn_index)
585
{
586
  insn_index = 0;                /* Just to get rid that warning.  */
587
  return 4;
588
}
589
 
590
/* Is individual insn's operand signed or unsigned? */
591
int
592
letter_signed (char l)
593
{
594
  CONST struct or32_letter *pletter;
595
 
596
  for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
597
    if (pletter->letter == l)
598
      return pletter->sign;
599
 
600
  printf ("letter_signed(%c): Unknown letter.\n", l);
601
  return 0;
602
}
603
 
604
/* Simple cache for letter ranges */
605
static int range_cache[256] = { 0 };
606
 
607
/* Number of letters in the individual lettered operand. */
608
int
609
letter_range (char l)
610
{
611
  CONST struct or32_opcode *pinsn;
612
  char *enc;
613
  int range = 0;
614
 
615
  /* Is value cached? */
616
  if ((range = range_cache[(unsigned char) l]))
617
    return range;
618
 
619
  for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn++)
620
    {
621
      if (strchr (pinsn->encoding, l))
622
        {
623
          for (enc = pinsn->encoding; *enc != '\0'; enc++)
624
            if ((*enc == '0') && (*(enc + 1) == 'x'))
625
              enc += 2;
626
            else if (*enc == l)
627
              range++;
628
          return range_cache[(unsigned char) l] = range;
629
        }
630
    }
631
 
632
  printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
633
  exit (1);
634
}
635
 
636
/* MM: Returns index of given instruction name.  */
637
int
638
insn_index (char *insn)
639
{
640
  int i, found = -1;
641
  for (i = 0; i < num_opcodes; i++)
642
    if (!strcmp (or32_opcodes[i].name, insn))
643
      {
644
        found = i;
645
        break;
646
      }
647
  return found;
648
}
649
 
650
/* Returns name of the specified instruction index */
651
CONST char *
652
insn_name (int index)
653
{
654
  if (index >= 0 && index < num_opcodes)
655
    return or32_opcodes[index].name;
656
  else
657
    return "???";
658
}
659
 
660
#if defined(HAVE_EXECUTION) && SIMPLE_EXECUTION
661
void
662
l_none (struct iqueue_entry *current)
663
{
664
}
665
#elif defined(HAVE_EXECUTION) && DYNAMIC_EXECUTION
666
void
667
l_none (struct op_queue *opq, int *param_t, int delay_slot)
668
{
669
}
670
#else
671
void
672
l_none ()
673
{
674
}
675
#endif
676
 
677
/*** Finite automata for instruction decoding building code ***/
678
 
679
/* Find symbols in encoding.  */
680
unsigned long
681
insn_extract (param_ch, enc_initial)
682
     char param_ch;
683
     char *enc_initial;
684
{
685
  char *enc;
686
  unsigned long ret = 0;
687
  unsigned opc_pos = 32;
688
  for (enc = enc_initial; *enc != '\0';)
689
    if ((*enc == '0') && (*(enc + 1) == 'x'))
690
      {
691
        unsigned long tmp = strtol (enc + 2, NULL, 16);
692
        opc_pos -= 4;
693
        if (param_ch == '0' || param_ch == '1')
694
          {
695
            if (param_ch == '0')
696
              tmp = 15 - tmp;
697
            ret |= tmp << opc_pos;
698
          }
699
        enc += 3;
700
      }
701
    else
702
      {
703
        if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha (*enc))
704
          {
705
            opc_pos--;
706
            if (param_ch == *enc)
707
              ret |= 1 << opc_pos;
708
          }
709
        enc++;
710
      }
711
  return ret;
712
}
713
 
714
#define MAX_AUTOMATA_SIZE (1200)
715
#define MAX_OP_TABLE_SIZE (1200)
716
#define MAX_LEN           (8)
717
 
718
#ifndef MIN
719
# define MIN(x,y)          ((x) < (y) ? (x) : (y))
720
#endif
721
 
722
unsigned long *automata;
723
int nuncovered;
724
int curpass = 0;
725
 
726
/* MM: Struct that holds runtime build information about instructions.  */
727
struct temp_insn_struct *ti;
728
 
729
struct insn_op_struct *op_data, **op_start;
730
 
731
static void
732
or32_debug (int level, const char *format, ...)
733
{
734
#if DEBUG
735
  char *p;
736
  va_list ap;
737
 
738
  if ((p = malloc (1000)) == NULL)
739
    return;
740
  va_start (ap, format);
741
  (void) vsnprintf (p, 1000, format, ap);
742
  va_end (ap);
743
  printf ("%s\n", p);
744
  fflush (stdout);
745
  free (p);
746
#endif
747
}
748
 
749
/* Recursive utility function used to find best match and to build automata.  */
750
static unsigned long *
751
cover_insn (unsigned long *cur, int pass, unsigned int mask)
752
{
753
  int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
754
  unsigned long cur_mask = mask;
755
  unsigned long *next;
756
 
757
  for (i = 0; i < num_opcodes; i++)
758
    if (ti[i].in_pass == pass)
759
      {
760
        cur_mask &= ti[i].insn_mask;
761
        ninstr++;
762
        last_match = i;
763
      }
764
 
765
  or32_debug (8, "%08X %08lX\n", mask, cur_mask);
766
  if (ninstr == 0)
767
    return 0;
768
  if (ninstr == 1)
769
    {
770
      /* Leaf holds instruction index. */
771
      or32_debug (8, "%i>I%i %s\n", cur - automata, last_match,
772
             or32_opcodes[last_match].name);
773
      *cur = LEAF_FLAG | last_match;
774
      cur++;
775
      nuncovered--;
776
    }
777
  else
778
    {
779
      /* Find longest match.  */
780
      for (i = 0; i < 32; i++)
781
        {
782
          int len;
783
          for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
784
            {
785
              unsigned long m = (1UL << ((unsigned long) len)) - 1;
786
              or32_debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)", len, m,
787
                     cur_mask, i, (cur_mask >> (unsigned) i),
788
                     (cur_mask >> (unsigned) i) & m);
789
              if ((m & (cur_mask >> (unsigned) i)) == m)
790
                {
791
                  best_len = len;
792
                  best_first = i;
793
                  or32_debug (9, "!");
794
                }
795
              else
796
                break;
797
            }
798
        }
799
      or32_debug (9, "\n");
800
      if (!best_len)
801
        {
802
          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
803
                   mask);
804
          for (i = 0; i < num_opcodes; i++)
805
            if (ti[i].in_pass == pass)
806
              fprintf (stderr, "%s ", or32_opcodes[i].name);
807
 
808
          fprintf (stderr, "\n");
809
          exit (1);
810
        }
811
      or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len,
812
             best_first, ninstr);
813
      *cur = best_first;
814
      cur++;
815
      *cur = (1 << best_len) - 1;
816
      cur++;
817
      next = cur;
818
      /* Allocate space for pointers.  */
819
      cur += 1 << best_len;
820
      cur_mask = (1 << (unsigned long) best_len) - 1;
821
 
822
      for (i = 0; i < (1 << (unsigned long) best_len); i++)
823
        {
824
          int j;
825
          unsigned long *c;
826
          curpass++;
827
          for (j = 0; j < num_opcodes; j++)
828
            if (ti[j].in_pass == pass
829
                && ((ti[j].insn >> best_first) & cur_mask) ==
830
                (unsigned long) i
831
                && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
832
              ti[j].in_pass = curpass;
833
 
834
          or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
835
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
836
          if (c)
837
            {
838
              or32_debug (8, "%i> #%X -> %u\n", next - automata, i,
839
                     cur - automata);
840
              *next = cur - automata;
841
              cur = c;
842
            }
843
          else
844
            {
845
              or32_debug (8, "%i> N/A\n", next - automata);
846
              *next = 0;
847
            }
848
          next++;
849
        }
850
    }
851
  return cur;
852
}
853
 
854
/* Returns number of nonzero bits. */
855
static int
856
num_ones (unsigned long value)
857
{
858
  int c = 0;
859
  while (value)
860
    {
861
      if (value & 1)
862
        c++;
863
      value >>= 1;
864
    }
865
  return c;
866
}
867
 
868
/* Utility function, which converts parameters from or32_opcode format to more binary form.
869
   Parameters are stored in ti struct.  */
870
 
871
static struct insn_op_struct *
872
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
873
{
874
  char *args = opcode->args;
875
  int i, type;
876
  int num_cur_op = 0;;
877
 
878
  i = 0;
879
  type = 0;
880
  /* In case we don't have any parameters, we add dummy read from r0.  */
881
  if (!(*args))
882
    {
883
      cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
884
      cur->data = 0;
885
      or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
886
      cur++;
887
      return cur;
888
    }
889
 
890
  while (*args != '\0')
891
    {
892
      if (*args == 'r')
893
        {
894
          args++;
895
          type |= OPTYPE_REG;
896
          if (*args == 'D')
897
            type |= OPTYPE_DST;
898
        }
899
      else if (isalpha (*args))
900
        {
901
          unsigned long arg;
902
          arg = insn_extract (*args, opcode->encoding);
903
          or32_debug (9, "%s : %08lX ------\n", opcode->name, arg);
904
          if (letter_signed (*args))
905
            {
906
              type |= OPTYPE_SIG;
907
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
908
            }
909
 
910
          num_cur_op = 0;
911
          /* Split argument to sequences of consecutive ones.  */
912
          while (arg)
913
            {
914
              int shr = 0;
915
              unsigned long tmp = arg, mask = 0;
916
              while ((tmp & 1) == 0)
917
                {
918
                  shr++;
919
                  tmp >>= 1;
920
                }
921
              while (tmp & 1)
922
                {
923
                  mask++;
924
                  tmp >>= 1;
925
                }
926
              cur->type = type | shr;
927
              cur->data = mask;
928
              arg &= ~(((1 << mask) - 1) << shr);
929
              or32_debug (6, "|%08lX %08lX\n", cur->type, cur->data);
930
              cur++;
931
              num_cur_op++;
932
            }
933
          args++;
934
        }
935
      else if (*args == '(')
936
        {
937
          /* Next param is displacement.  Later we will treat them as one operand.  */
938
          /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
939
           * operand */
940
          while (num_cur_op > 0)
941
            {
942
              cur[-num_cur_op].type |= type | OPTYPE_DIS;
943
              num_cur_op--;
944
            }
945
          cur[-1].type |= OPTYPE_OP;
946
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
947
          type = 0;
948
          i++;
949
          args++;
950
        }
951
      else if (*args == OPERAND_DELIM)
952
        {
953
          cur--;
954
          cur->type = type | cur->type | OPTYPE_OP;
955
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
956
          cur++;
957
          type = 0;
958
          i++;
959
          args++;
960
        }
961
      else if (*args == '0')
962
        {
963
          cur->type = type;
964
          cur->data = 0;
965
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
966
          cur++;
967
          type = 0;
968
          i++;
969
          args++;
970
        }
971
      else if (*args == ')')
972
        args++;
973
      else
974
        {
975
          fprintf (stderr, "%s : parse error in args.\n", opcode->name);
976
          exit (1);
977
        }
978
    }
979
  cur--;
980
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
981
  or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
982
  cur++;
983
  return cur;
984
}
985
 
986 220 jeremybenn
/* -------------------------------------------------------------------------- */
987
/*!Constructs new automata based on or32_opcodes array.
988 19 jeremybenn
 
989 220 jeremybenn
   @param[in] quiet  If non-zero (TRUE) do not print informational messages. */
990
/* -------------------------------------------------------------------------- */
991 19 jeremybenn
void
992 220 jeremybenn
build_automata (int  quiet)
993 19 jeremybenn
{
994
  int i;
995
  unsigned long *end;
996
  struct insn_op_struct *cur;
997
 
998
  automata =
999
    (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
1000
  ti =
1001
    (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
1002
                                        num_opcodes);
1003
 
1004
  nuncovered = num_opcodes;
1005
 
1006
#ifdef HAVE_EXECUTION
1007 220 jeremybenn
  if (!quiet)
1008
    {
1009
      printf ("Building automata... ");
1010
    }
1011 19 jeremybenn
#endif
1012
 
1013
  /* Build temporary information about instructions.  */
1014
  for (i = 0; i < num_opcodes; i++)
1015
    {
1016
      unsigned long ones, zeros;
1017
      char *encoding = or32_opcodes[i].encoding;
1018
      ones = insn_extract ('1', encoding);
1019
      zeros = insn_extract ('0', encoding);
1020
      ti[i].insn_mask = ones | zeros;
1021
      ti[i].insn = ones;
1022
      ti[i].in_pass = curpass = 0;
1023
      /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
1024
         or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn); */
1025
    }
1026
 
1027
  /* Until all are covered search for best criteria to separate them.  */
1028
  end = cover_insn (automata, curpass, 0xFFFFFFFF);
1029
  if (end - automata > MAX_AUTOMATA_SIZE)
1030
    {
1031
      fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
1032
      exit (1);
1033
    }
1034
#ifdef HAVE_EXECUTION
1035 220 jeremybenn
  if (!quiet)
1036
    {
1037
      printf ("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
1038
    }
1039 19 jeremybenn
#endif
1040
 
1041
#ifdef HAVE_EXECUTION
1042 220 jeremybenn
  if (!quiet)
1043
    {
1044
      printf ("Parsing operands data... ");
1045
    }
1046 19 jeremybenn
#endif
1047
  op_data =
1048
    (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
1049
                                      sizeof (struct insn_op_struct));
1050
  op_start =
1051
    (struct insn_op_struct **) malloc (num_opcodes *
1052
                                       sizeof (struct insn_op_struct *));
1053
  cur = op_data;
1054
  for (i = 0; i < num_opcodes; i++)
1055
    {
1056
      op_start[i] = cur;
1057
      cur = parse_params (&or32_opcodes[i], cur);
1058
      if (cur - op_data > MAX_OP_TABLE_SIZE)
1059
        {
1060
          fprintf (stderr,
1061
                   "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
1062
          exit (1);
1063
        }
1064
    }
1065
#ifdef HAVE_EXECUTION
1066 220 jeremybenn
  if (!quiet)
1067
    {
1068
      printf ("done.\n");
1069
    }
1070 19 jeremybenn
#endif
1071
}
1072
 
1073
void
1074
destruct_automata ()
1075
{
1076
  free (ti);
1077
  free (automata);
1078
  free (op_data);
1079
  free (op_start);
1080
}
1081
 
1082
/* Decodes instruction and returns instruction index.  */
1083
int
1084
insn_decode (unsigned int insn)
1085
{
1086
  unsigned long *a = automata;
1087
  int i;
1088
  while (!(*a & LEAF_FLAG))
1089
    {
1090
      unsigned int first = *a;
1091
      //debug(9, "%i ", a - automata);
1092
      a++;
1093
      i = (insn >> first) & *a;
1094
      a++;
1095
      if (!*(a + i))
1096
        {                       /* Invalid instruction found?  */
1097
          //debug(9, "XXX\n", i);
1098
          return -1;
1099
        }
1100
      a = automata + *(a + i);
1101
    }
1102
  i = *a & ~LEAF_FLAG;
1103
  //debug(9, "%i\n", i);
1104
  /* Final check - do we have direct match?
1105
     (based on or32_opcodes this should be the only possibility,
1106
     but in case of invalid/missing instruction we must perform a check)  */
1107
  if ((ti[i].insn_mask & insn) == ti[i].insn)
1108
    return i;
1109
  else
1110
    return -1;
1111
}
1112
 
1113
static char disassembled_str[50];
1114
char *disassembled = &disassembled_str[0];
1115
 
1116
/* Automagically does zero- or sign- extension and also finds correct
1117
   sign bit position if sign extension is correct extension. Which extension
1118
   is proper is figured out from letter description. */
1119
 
1120
unsigned long
1121
extend_imm (unsigned long imm, char l)
1122
{
1123
  unsigned long mask;
1124
  int letter_bits;
1125
 
1126
  /* First truncate all bits above valid range for this letter
1127
     in case it is zero extend. */
1128
  letter_bits = letter_range (l);
1129
  mask = (1 << letter_bits) - 1;
1130
  imm &= mask;
1131
 
1132
  /* Do sign extend if this is the right one. */
1133
  if (letter_signed (l) && (imm >> (letter_bits - 1)))
1134
    imm |= (~mask);
1135
 
1136
  return imm;
1137
}
1138
 
1139
unsigned long
1140
or32_extract (param_ch, enc_initial, insn)
1141
     char param_ch;
1142
     char *enc_initial;
1143
     unsigned long insn;
1144
{
1145
  char *enc;
1146
  unsigned long ret = 0;
1147
  int opc_pos = 0;
1148
  int param_pos = 0;
1149
 
1150
  for (enc = enc_initial; *enc != '\0'; enc++)
1151
    if (*enc == param_ch)
1152
      {
1153
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0')
1154
            && (*(enc - 1) == 'x'))
1155
          continue;
1156
        else
1157
          param_pos++;
1158
      }
1159
 
1160
#if DEBUG
1161
  printf ("or32_extract: %x ", param_pos);
1162
#endif
1163
  opc_pos = 32;
1164
  for (enc = enc_initial; *enc != '\0';)
1165
    if ((*enc == '0') && (*(enc + 1) == 'x'))
1166
      {
1167
        opc_pos -= 4;
1168
        if ((param_ch == '0') || (param_ch == '1'))
1169
          {
1170
            unsigned long tmp = strtol (enc, NULL, 16);
1171
#if DEBUG
1172
            printf (" enc=%s, tmp=%x ", enc, tmp);
1173
#endif
1174
            if (param_ch == '0')
1175
              tmp = 15 - tmp;
1176
            ret |= tmp << opc_pos;
1177
          }
1178
        enc += 3;
1179
      }
1180
    else if ((*enc == '0') || (*enc == '1'))
1181
      {
1182
        opc_pos--;
1183
        if (param_ch == *enc)
1184
          ret |= 1 << opc_pos;
1185
        enc++;
1186
      }
1187
    else if (*enc == param_ch)
1188
      {
1189
        opc_pos--;
1190
        param_pos--;
1191
#if DEBUG
1192
        printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos,
1193
                param_pos);
1194
#endif
1195
        if (islower (param_ch))
1196
          ret -= ((insn >> opc_pos) & 0x1) << param_pos;
1197
        else
1198
          ret += ((insn >> opc_pos) & 0x1) << param_pos;
1199
        enc++;
1200
      }
1201
    else if (isalpha (*enc))
1202
      {
1203
        opc_pos--;
1204
        enc++;
1205
      }
1206
    else if (*enc == '-')
1207
      {
1208
        opc_pos--;
1209
        enc++;
1210
      }
1211
    else
1212
      enc++;
1213
 
1214
#if DEBUG
1215
  printf ("ret=%x\n", ret);
1216
#endif
1217
  return ret;
1218
}
1219
 
1220
/* Print register. Used only by print_insn. */
1221
 
1222
static char *
1223
or32_print_register (dest, param_ch, encoding, insn)
1224
     char *dest;
1225
     char param_ch;
1226
     char *encoding;
1227
     unsigned long insn;
1228
{
1229
  int regnum = or32_extract (param_ch, encoding, insn);
1230
 
1231
  sprintf (dest, "r%d", regnum);
1232
  while (*dest)
1233
    dest++;
1234
  return dest;
1235
}
1236
 
1237
/* Print immediate. Used only by print_insn. */
1238
 
1239
static char *
1240
or32_print_immediate (dest, param_ch, encoding, insn)
1241
     char *dest;
1242
     char param_ch;
1243
     char *encoding;
1244
     unsigned long insn;
1245
{
1246
  int imm = or32_extract (param_ch, encoding, insn);
1247
 
1248
  imm = extend_imm (imm, param_ch);
1249
 
1250
  if (letter_signed (param_ch))
1251
    {
1252
      if (imm < 0)
1253
        sprintf (dest, "%d", imm);
1254
      else
1255
        sprintf (dest, "0x%x", imm);
1256
    }
1257
  else
1258
    sprintf (dest, "%#x", imm);
1259
  while (*dest)
1260
    dest++;
1261
  return dest;
1262
}
1263
 
1264
/* Disassemble one instruction from insn to disassemble.
1265
   Return the size of the instruction.  */
1266
 
1267
int
1268
disassemble_insn (insn)
1269
     unsigned long insn;
1270
{
1271
  return disassemble_index (insn, insn_decode (insn));
1272
}
1273
 
1274
/* Disassemble one instruction from insn index.
1275
   Return the size of the instruction.  */
1276
 
1277
int
1278
disassemble_index (insn, index)
1279
     unsigned long insn;
1280
     int index;
1281
{
1282
  char *dest = disassembled;
1283
  if (index >= 0)
1284
    {
1285
      struct or32_opcode const *opcode = &or32_opcodes[index];
1286
      char *s;
1287
 
1288
      strcpy (dest, opcode->name);
1289
      while (*dest)
1290
        dest++;
1291
      *dest++ = ' ';
1292
      *dest = 0;
1293
 
1294
      for (s = opcode->args; *s != '\0'; ++s)
1295
        {
1296
          switch (*s)
1297
            {
1298
            case '\0':
1299
              return insn_len (insn);
1300
 
1301
            case 'r':
1302
              dest = or32_print_register (dest, *++s, opcode->encoding, insn);
1303
              break;
1304
 
1305
            default:
1306
              if (strchr (opcode->encoding, *s))
1307
                dest =
1308
                  or32_print_immediate (dest, *s, opcode->encoding, insn);
1309
              else
1310
                {
1311
                  *dest++ = *s;
1312
                  *dest = 0;
1313
                }
1314
            }
1315
        }
1316
    }
1317
  else
1318
    {
1319
      /* This used to be %8x for binutils.  */
1320
      sprintf (dest, ".word 0x%08lx", insn);
1321
      while (*dest)
1322
        dest++;
1323
    }
1324
  return insn_len (insn);
1325
}

powered by: WebSVN 2.1.0

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