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

Subversion Repositories openrisc

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

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 230 jeremybenn
CONST struct or32_opcode or1ksim_or32_opcodes[] = {
93 19 jeremybenn
 
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 230 jeremybenn
static CONST int NUM_OPCODES =
580
  ((sizeof (or1ksim_or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
581 19 jeremybenn
 
582
/* Calculates instruction length in bytes. Always 4 for OR32. */
583
int
584 230 jeremybenn
or1ksim_insn_len (int insn_index)
585 19 jeremybenn
{
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 230 jeremybenn
static int
592 19 jeremybenn
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 230 jeremybenn
static int
609 19 jeremybenn
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 230 jeremybenn
  for (pinsn = or1ksim_or32_opcodes; strlen (pinsn->name); pinsn++)
620 19 jeremybenn
    {
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
/* Returns name of the specified instruction index */
637
CONST char *
638 230 jeremybenn
or1ksim_insn_name (int index)
639 19 jeremybenn
{
640 230 jeremybenn
  if (index >= 0 && index < NUM_OPCODES)
641
    return or1ksim_or32_opcodes[index].name;
642 19 jeremybenn
  else
643
    return "???";
644
}
645
 
646
/*** Finite automata for instruction decoding building code ***/
647
 
648
/* Find symbols in encoding.  */
649 230 jeremybenn
static unsigned long
650 19 jeremybenn
insn_extract (param_ch, enc_initial)
651
     char param_ch;
652
     char *enc_initial;
653
{
654
  char *enc;
655
  unsigned long ret = 0;
656
  unsigned opc_pos = 32;
657
  for (enc = enc_initial; *enc != '\0';)
658
    if ((*enc == '0') && (*(enc + 1) == 'x'))
659
      {
660
        unsigned long tmp = strtol (enc + 2, NULL, 16);
661
        opc_pos -= 4;
662
        if (param_ch == '0' || param_ch == '1')
663
          {
664
            if (param_ch == '0')
665
              tmp = 15 - tmp;
666
            ret |= tmp << opc_pos;
667
          }
668
        enc += 3;
669
      }
670
    else
671
      {
672
        if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha (*enc))
673
          {
674
            opc_pos--;
675
            if (param_ch == *enc)
676
              ret |= 1 << opc_pos;
677
          }
678
        enc++;
679
      }
680
  return ret;
681
}
682
 
683
#define MAX_AUTOMATA_SIZE (1200)
684
#define MAX_OP_TABLE_SIZE (1200)
685
#define MAX_LEN           (8)
686
 
687
#ifndef MIN
688
# define MIN(x,y)          ((x) < (y) ? (x) : (y))
689
#endif
690
 
691 230 jeremybenn
unsigned long *or1ksim_automata;
692 19 jeremybenn
int nuncovered;
693
int curpass = 0;
694
 
695
/* MM: Struct that holds runtime build information about instructions.  */
696 230 jeremybenn
struct temp_insn_struct *or1ksim_ti;
697 19 jeremybenn
 
698 230 jeremybenn
static struct insn_op_struct *op_data;
699 19 jeremybenn
 
700 230 jeremybenn
struct insn_op_struct **or1ksim_op_start;
701
 
702 19 jeremybenn
static void
703
or32_debug (int level, const char *format, ...)
704
{
705
#if DEBUG
706
  char *p;
707
  va_list ap;
708
 
709
  if ((p = malloc (1000)) == NULL)
710
    return;
711
  va_start (ap, format);
712
  (void) vsnprintf (p, 1000, format, ap);
713
  va_end (ap);
714
  printf ("%s\n", p);
715
  fflush (stdout);
716
  free (p);
717
#endif
718
}
719
 
720
/* Recursive utility function used to find best match and to build automata.  */
721
static unsigned long *
722
cover_insn (unsigned long *cur, int pass, unsigned int mask)
723
{
724
  int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
725
  unsigned long cur_mask = mask;
726
  unsigned long *next;
727
 
728 230 jeremybenn
  for (i = 0; i < NUM_OPCODES; i++)
729
    if (or1ksim_ti[i].in_pass == pass)
730 19 jeremybenn
      {
731 230 jeremybenn
        cur_mask &= or1ksim_ti[i].insn_mask;
732 19 jeremybenn
        ninstr++;
733
        last_match = i;
734
      }
735
 
736
  or32_debug (8, "%08X %08lX\n", mask, cur_mask);
737
  if (ninstr == 0)
738
    return 0;
739
  if (ninstr == 1)
740
    {
741
      /* Leaf holds instruction index. */
742 230 jeremybenn
      or32_debug (8, "%i>I%i %s\n", cur - or1ksim_automata, last_match,
743
             or1ksim_or32_opcodes[last_match].name);
744 19 jeremybenn
      *cur = LEAF_FLAG | last_match;
745
      cur++;
746
      nuncovered--;
747
    }
748
  else
749
    {
750
      /* Find longest match.  */
751
      for (i = 0; i < 32; i++)
752
        {
753
          int len;
754
          for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
755
            {
756
              unsigned long m = (1UL << ((unsigned long) len)) - 1;
757
              or32_debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)", len, m,
758
                     cur_mask, i, (cur_mask >> (unsigned) i),
759
                     (cur_mask >> (unsigned) i) & m);
760
              if ((m & (cur_mask >> (unsigned) i)) == m)
761
                {
762
                  best_len = len;
763
                  best_first = i;
764
                  or32_debug (9, "!");
765
                }
766
              else
767
                break;
768
            }
769
        }
770
      or32_debug (9, "\n");
771
      if (!best_len)
772
        {
773
          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
774
                   mask);
775 230 jeremybenn
          for (i = 0; i < NUM_OPCODES; i++)
776
            if (or1ksim_ti[i].in_pass == pass)
777
              fprintf (stderr, "%s ", or1ksim_or32_opcodes[i].name);
778 19 jeremybenn
 
779
          fprintf (stderr, "\n");
780
          exit (1);
781
        }
782 230 jeremybenn
      or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - or1ksim_automata, best_len,
783 19 jeremybenn
             best_first, ninstr);
784
      *cur = best_first;
785
      cur++;
786
      *cur = (1 << best_len) - 1;
787
      cur++;
788
      next = cur;
789
      /* Allocate space for pointers.  */
790
      cur += 1 << best_len;
791
      cur_mask = (1 << (unsigned long) best_len) - 1;
792
 
793
      for (i = 0; i < (1 << (unsigned long) best_len); i++)
794
        {
795
          int j;
796
          unsigned long *c;
797
          curpass++;
798 230 jeremybenn
          for (j = 0; j < NUM_OPCODES; j++)
799
            if (or1ksim_ti[j].in_pass == pass
800
                && ((or1ksim_ti[j].insn >> best_first) & cur_mask) ==
801 19 jeremybenn
                (unsigned long) i
802 230 jeremybenn
                && ((or1ksim_ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
803
              or1ksim_ti[j].in_pass = curpass;
804 19 jeremybenn
 
805
          or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
806
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
807
          if (c)
808
            {
809 230 jeremybenn
              or32_debug (8, "%i> #%X -> %u\n", next - or1ksim_automata, i,
810
                     cur - or1ksim_automata);
811
              *next = cur - or1ksim_automata;
812 19 jeremybenn
              cur = c;
813
            }
814
          else
815
            {
816 230 jeremybenn
              or32_debug (8, "%i> N/A\n", next - or1ksim_automata);
817 19 jeremybenn
              *next = 0;
818
            }
819
          next++;
820
        }
821
    }
822
  return cur;
823
}
824
 
825
/* Returns number of nonzero bits. */
826
static int
827
num_ones (unsigned long value)
828
{
829
  int c = 0;
830
  while (value)
831
    {
832
      if (value & 1)
833
        c++;
834
      value >>= 1;
835
    }
836
  return c;
837
}
838
 
839
/* Utility function, which converts parameters from or32_opcode format to more binary form.
840 230 jeremybenn
   Parameters are stored in or1ksim_ti struct.  */
841 19 jeremybenn
 
842
static struct insn_op_struct *
843
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
844
{
845
  char *args = opcode->args;
846
  int i, type;
847
  int num_cur_op = 0;;
848
 
849
  i = 0;
850
  type = 0;
851
  /* In case we don't have any parameters, we add dummy read from r0.  */
852
  if (!(*args))
853
    {
854
      cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
855
      cur->data = 0;
856
      or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
857
      cur++;
858
      return cur;
859
    }
860
 
861
  while (*args != '\0')
862
    {
863
      if (*args == 'r')
864
        {
865
          args++;
866
          type |= OPTYPE_REG;
867
          if (*args == 'D')
868
            type |= OPTYPE_DST;
869
        }
870
      else if (isalpha (*args))
871
        {
872
          unsigned long arg;
873
          arg = insn_extract (*args, opcode->encoding);
874
          or32_debug (9, "%s : %08lX ------\n", opcode->name, arg);
875
          if (letter_signed (*args))
876
            {
877
              type |= OPTYPE_SIG;
878
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
879
            }
880
 
881
          num_cur_op = 0;
882
          /* Split argument to sequences of consecutive ones.  */
883
          while (arg)
884
            {
885
              int shr = 0;
886
              unsigned long tmp = arg, mask = 0;
887
              while ((tmp & 1) == 0)
888
                {
889
                  shr++;
890
                  tmp >>= 1;
891
                }
892
              while (tmp & 1)
893
                {
894
                  mask++;
895
                  tmp >>= 1;
896
                }
897
              cur->type = type | shr;
898
              cur->data = mask;
899
              arg &= ~(((1 << mask) - 1) << shr);
900
              or32_debug (6, "|%08lX %08lX\n", cur->type, cur->data);
901
              cur++;
902
              num_cur_op++;
903
            }
904
          args++;
905
        }
906
      else if (*args == '(')
907
        {
908
          /* Next param is displacement.  Later we will treat them as one operand.  */
909
          /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
910
           * operand */
911
          while (num_cur_op > 0)
912
            {
913
              cur[-num_cur_op].type |= type | OPTYPE_DIS;
914
              num_cur_op--;
915
            }
916
          cur[-1].type |= OPTYPE_OP;
917
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
918
          type = 0;
919
          i++;
920
          args++;
921
        }
922
      else if (*args == OPERAND_DELIM)
923
        {
924
          cur--;
925
          cur->type = type | cur->type | OPTYPE_OP;
926
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
927
          cur++;
928
          type = 0;
929
          i++;
930
          args++;
931
        }
932
      else if (*args == '0')
933
        {
934
          cur->type = type;
935
          cur->data = 0;
936
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
937
          cur++;
938
          type = 0;
939
          i++;
940
          args++;
941
        }
942
      else if (*args == ')')
943
        args++;
944
      else
945
        {
946
          fprintf (stderr, "%s : parse error in args.\n", opcode->name);
947
          exit (1);
948
        }
949
    }
950
  cur--;
951
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
952
  or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
953
  cur++;
954
  return cur;
955
}
956
 
957 220 jeremybenn
/* -------------------------------------------------------------------------- */
958 230 jeremybenn
/*!Constructs new automata based on or1ksim_or32_opcodes array.
959 19 jeremybenn
 
960 220 jeremybenn
   @param[in] quiet  If non-zero (TRUE) do not print informational messages. */
961
/* -------------------------------------------------------------------------- */
962 19 jeremybenn
void
963 230 jeremybenn
or1ksim_build_automata (int  quiet)
964 19 jeremybenn
{
965
  int i;
966
  unsigned long *end;
967
  struct insn_op_struct *cur;
968
 
969 230 jeremybenn
  or1ksim_automata =
970 19 jeremybenn
    (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
971 230 jeremybenn
  or1ksim_ti =
972 19 jeremybenn
    (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
973 230 jeremybenn
                                        NUM_OPCODES);
974 19 jeremybenn
 
975 230 jeremybenn
  nuncovered = NUM_OPCODES;
976 19 jeremybenn
 
977
#ifdef HAVE_EXECUTION
978 220 jeremybenn
  if (!quiet)
979
    {
980
      printf ("Building automata... ");
981
    }
982 19 jeremybenn
#endif
983
 
984
  /* Build temporary information about instructions.  */
985 230 jeremybenn
  for (i = 0; i < NUM_OPCODES; i++)
986 19 jeremybenn
    {
987
      unsigned long ones, zeros;
988 230 jeremybenn
      char *encoding = or1ksim_or32_opcodes[i].encoding;
989 19 jeremybenn
      ones = insn_extract ('1', encoding);
990
      zeros = insn_extract ('0', encoding);
991 230 jeremybenn
      or1ksim_ti[i].insn_mask = ones | zeros;
992
      or1ksim_ti[i].insn = ones;
993
      or1ksim_ti[i].in_pass = curpass = 0;
994
      /*debug(9, "%s: %s %08X %08X\n", or1ksim_or32_opcodes[i].name,
995
         or1ksim_or32_opcodes[i].encoding, or1ksim_ti[i].insn_mask, or1ksim_ti[i].insn); */
996 19 jeremybenn
    }
997
 
998
  /* Until all are covered search for best criteria to separate them.  */
999 230 jeremybenn
  end = cover_insn (or1ksim_automata, curpass, 0xFFFFFFFF);
1000
  if (end - or1ksim_automata > MAX_AUTOMATA_SIZE)
1001 19 jeremybenn
    {
1002
      fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
1003
      exit (1);
1004
    }
1005
#ifdef HAVE_EXECUTION
1006 220 jeremybenn
  if (!quiet)
1007
    {
1008 230 jeremybenn
      printf ("done, num uncovered: %i/%i.\n", nuncovered, NUM_OPCODES);
1009 220 jeremybenn
    }
1010 19 jeremybenn
#endif
1011
 
1012
#ifdef HAVE_EXECUTION
1013 220 jeremybenn
  if (!quiet)
1014
    {
1015
      printf ("Parsing operands data... ");
1016
    }
1017 19 jeremybenn
#endif
1018
  op_data =
1019
    (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
1020
                                      sizeof (struct insn_op_struct));
1021 230 jeremybenn
  or1ksim_op_start =
1022
    (struct insn_op_struct **) malloc (NUM_OPCODES *
1023 19 jeremybenn
                                       sizeof (struct insn_op_struct *));
1024
  cur = op_data;
1025 230 jeremybenn
  for (i = 0; i < NUM_OPCODES; i++)
1026 19 jeremybenn
    {
1027 230 jeremybenn
      or1ksim_op_start[i] = cur;
1028
      cur = parse_params (&or1ksim_or32_opcodes[i], cur);
1029 19 jeremybenn
      if (cur - op_data > MAX_OP_TABLE_SIZE)
1030
        {
1031
          fprintf (stderr,
1032
                   "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
1033
          exit (1);
1034
        }
1035
    }
1036
#ifdef HAVE_EXECUTION
1037 220 jeremybenn
  if (!quiet)
1038
    {
1039
      printf ("done.\n");
1040
    }
1041 19 jeremybenn
#endif
1042
}
1043
 
1044
void
1045 230 jeremybenn
or1ksim_destruct_automata ()
1046 19 jeremybenn
{
1047 230 jeremybenn
  free (or1ksim_ti);
1048
  free (or1ksim_automata);
1049 19 jeremybenn
  free (op_data);
1050 230 jeremybenn
  free (or1ksim_op_start);
1051 19 jeremybenn
}
1052
 
1053
/* Decodes instruction and returns instruction index.  */
1054
int
1055 230 jeremybenn
or1ksim_insn_decode (unsigned int insn)
1056 19 jeremybenn
{
1057 230 jeremybenn
  unsigned long *a = or1ksim_automata;
1058 19 jeremybenn
  int i;
1059
  while (!(*a & LEAF_FLAG))
1060
    {
1061
      unsigned int first = *a;
1062 230 jeremybenn
      //debug(9, "%i ", a - or1ksim_automata);
1063 19 jeremybenn
      a++;
1064
      i = (insn >> first) & *a;
1065
      a++;
1066
      if (!*(a + i))
1067
        {                       /* Invalid instruction found?  */
1068
          //debug(9, "XXX\n", i);
1069
          return -1;
1070
        }
1071 230 jeremybenn
      a = or1ksim_automata + *(a + i);
1072 19 jeremybenn
    }
1073
  i = *a & ~LEAF_FLAG;
1074
  //debug(9, "%i\n", i);
1075
  /* Final check - do we have direct match?
1076 230 jeremybenn
     (based on or1ksim_or32_opcodes this should be the only possibility,
1077 19 jeremybenn
     but in case of invalid/missing instruction we must perform a check)  */
1078 230 jeremybenn
  if ((or1ksim_ti[i].insn_mask & insn) == or1ksim_ti[i].insn)
1079 19 jeremybenn
    return i;
1080
  else
1081
    return -1;
1082
}
1083
 
1084
static char disassembled_str[50];
1085 230 jeremybenn
char *or1ksim_disassembled = &disassembled_str[0];
1086 19 jeremybenn
 
1087
/* Automagically does zero- or sign- extension and also finds correct
1088
   sign bit position if sign extension is correct extension. Which extension
1089
   is proper is figured out from letter description. */
1090
 
1091
unsigned long
1092 230 jeremybenn
or1ksim_extend_imm (unsigned long imm, char l)
1093 19 jeremybenn
{
1094
  unsigned long mask;
1095
  int letter_bits;
1096
 
1097
  /* First truncate all bits above valid range for this letter
1098
     in case it is zero extend. */
1099
  letter_bits = letter_range (l);
1100
  mask = (1 << letter_bits) - 1;
1101
  imm &= mask;
1102
 
1103
  /* Do sign extend if this is the right one. */
1104
  if (letter_signed (l) && (imm >> (letter_bits - 1)))
1105
    imm |= (~mask);
1106
 
1107
  return imm;
1108
}
1109
 
1110
unsigned long
1111 230 jeremybenn
or1ksim_or32_extract (param_ch, enc_initial, insn)
1112 19 jeremybenn
     char param_ch;
1113
     char *enc_initial;
1114
     unsigned long insn;
1115
{
1116
  char *enc;
1117
  unsigned long ret = 0;
1118
  int opc_pos = 0;
1119
  int param_pos = 0;
1120
 
1121
  for (enc = enc_initial; *enc != '\0'; enc++)
1122
    if (*enc == param_ch)
1123
      {
1124
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0')
1125
            && (*(enc - 1) == 'x'))
1126
          continue;
1127
        else
1128
          param_pos++;
1129
      }
1130
 
1131
#if DEBUG
1132 230 jeremybenn
  printf ("or1ksim_or32_extract: %x ", param_pos);
1133 19 jeremybenn
#endif
1134
  opc_pos = 32;
1135
  for (enc = enc_initial; *enc != '\0';)
1136
    if ((*enc == '0') && (*(enc + 1) == 'x'))
1137
      {
1138
        opc_pos -= 4;
1139
        if ((param_ch == '0') || (param_ch == '1'))
1140
          {
1141
            unsigned long tmp = strtol (enc, NULL, 16);
1142
#if DEBUG
1143
            printf (" enc=%s, tmp=%x ", enc, tmp);
1144
#endif
1145
            if (param_ch == '0')
1146
              tmp = 15 - tmp;
1147
            ret |= tmp << opc_pos;
1148
          }
1149
        enc += 3;
1150
      }
1151
    else if ((*enc == '0') || (*enc == '1'))
1152
      {
1153
        opc_pos--;
1154
        if (param_ch == *enc)
1155
          ret |= 1 << opc_pos;
1156
        enc++;
1157
      }
1158
    else if (*enc == param_ch)
1159
      {
1160
        opc_pos--;
1161
        param_pos--;
1162
#if DEBUG
1163
        printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos,
1164
                param_pos);
1165
#endif
1166
        if (islower (param_ch))
1167
          ret -= ((insn >> opc_pos) & 0x1) << param_pos;
1168
        else
1169
          ret += ((insn >> opc_pos) & 0x1) << param_pos;
1170
        enc++;
1171
      }
1172
    else if (isalpha (*enc))
1173
      {
1174
        opc_pos--;
1175
        enc++;
1176
      }
1177
    else if (*enc == '-')
1178
      {
1179
        opc_pos--;
1180
        enc++;
1181
      }
1182
    else
1183
      enc++;
1184
 
1185
#if DEBUG
1186
  printf ("ret=%x\n", ret);
1187
#endif
1188
  return ret;
1189
}
1190
 
1191
/* Print register. Used only by print_insn. */
1192
 
1193
static char *
1194
or32_print_register (dest, param_ch, encoding, insn)
1195
     char *dest;
1196
     char param_ch;
1197
     char *encoding;
1198
     unsigned long insn;
1199
{
1200 230 jeremybenn
  int regnum = or1ksim_or32_extract (param_ch, encoding, insn);
1201 19 jeremybenn
 
1202
  sprintf (dest, "r%d", regnum);
1203
  while (*dest)
1204
    dest++;
1205
  return dest;
1206
}
1207
 
1208
/* Print immediate. Used only by print_insn. */
1209
 
1210
static char *
1211
or32_print_immediate (dest, param_ch, encoding, insn)
1212
     char *dest;
1213
     char param_ch;
1214
     char *encoding;
1215
     unsigned long insn;
1216
{
1217 230 jeremybenn
  int imm = or1ksim_or32_extract (param_ch, encoding, insn);
1218 19 jeremybenn
 
1219 230 jeremybenn
  imm = or1ksim_extend_imm (imm, param_ch);
1220 19 jeremybenn
 
1221
  if (letter_signed (param_ch))
1222
    {
1223
      if (imm < 0)
1224
        sprintf (dest, "%d", imm);
1225
      else
1226
        sprintf (dest, "0x%x", imm);
1227
    }
1228
  else
1229
    sprintf (dest, "%#x", imm);
1230
  while (*dest)
1231
    dest++;
1232
  return dest;
1233
}
1234
 
1235
/* Disassemble one instruction from insn to disassemble.
1236
   Return the size of the instruction.  */
1237
 
1238
int
1239 230 jeremybenn
or1ksim_disassemble_insn (insn)
1240 19 jeremybenn
     unsigned long insn;
1241
{
1242 230 jeremybenn
  return or1ksim_disassemble_index (insn, or1ksim_insn_decode (insn));
1243 19 jeremybenn
}
1244
 
1245
/* Disassemble one instruction from insn index.
1246
   Return the size of the instruction.  */
1247
 
1248
int
1249 230 jeremybenn
or1ksim_disassemble_index (insn, index)
1250 19 jeremybenn
     unsigned long insn;
1251
     int index;
1252
{
1253 230 jeremybenn
  char *dest = or1ksim_disassembled;
1254 19 jeremybenn
  if (index >= 0)
1255
    {
1256 230 jeremybenn
      struct or32_opcode const *opcode = &or1ksim_or32_opcodes[index];
1257 19 jeremybenn
      char *s;
1258
 
1259
      strcpy (dest, opcode->name);
1260
      while (*dest)
1261
        dest++;
1262
      *dest++ = ' ';
1263
      *dest = 0;
1264
 
1265
      for (s = opcode->args; *s != '\0'; ++s)
1266
        {
1267
          switch (*s)
1268
            {
1269
            case '\0':
1270 230 jeremybenn
              return or1ksim_insn_len (insn);
1271 19 jeremybenn
 
1272
            case 'r':
1273
              dest = or32_print_register (dest, *++s, opcode->encoding, insn);
1274
              break;
1275
 
1276
            default:
1277
              if (strchr (opcode->encoding, *s))
1278
                dest =
1279
                  or32_print_immediate (dest, *s, opcode->encoding, insn);
1280
              else
1281
                {
1282
                  *dest++ = *s;
1283
                  *dest = 0;
1284
                }
1285
            }
1286
        }
1287
    }
1288
  else
1289
    {
1290
      /* This used to be %8x for binutils.  */
1291
      sprintf (dest, ".word 0x%08lx", insn);
1292
      while (*dest)
1293
        dest++;
1294
    }
1295 230 jeremybenn
  return or1ksim_insn_len (insn);
1296 19 jeremybenn
}

powered by: WebSVN 2.1.0

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