*** empty log message ***
[deliverable/binutils-gdb.git] / opcodes / or32-opc.c
CommitLineData
3b16e843 1/* Table of opcodes for the OpenRISC 1000 ISA.
9b201bb5 2 Copyright 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
3b16e843
NC
3 Contributed by Damjan Lampret (lampret@opencores.org).
4
9b201bb5 5 This file is part of the GNU opcodes library.
3b16e843 6
9b201bb5 7 This library is free software; you can redistribute it and/or modify
3b16e843 8 it under the terms of the GNU General Public License as published by
9b201bb5
NC
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
3b16e843 11
9b201bb5
NC
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
3b16e843
NC
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
47b0e7ad
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
3b16e843
NC
21
22/* We treat all letters the same in encode/decode routines so
23 we need to assign some characteristics to them like signess etc. */
24#include <string.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include "safe-ctype.h"
28#include "ansidecl.h"
29#ifdef HAVE_CONFIG_H
30# include "config.h"
31#endif
32#include "opcode/or32.h"
33
3b16e843 34const struct or32_letter or32_letters[] =
47b0e7ad
NC
35{
36 { 'A', NUM_UNSIGNED },
37 { 'B', NUM_UNSIGNED },
38 { 'D', NUM_UNSIGNED },
39 { 'I', NUM_SIGNED },
40 { 'K', NUM_UNSIGNED },
41 { 'L', NUM_UNSIGNED },
42 { 'N', NUM_SIGNED },
43 { '0', NUM_UNSIGNED },
44 { '\0', 0 } /* Dummy entry. */
45};
3b16e843
NC
46
47/* Opcode encoding:
48 machine[31:30]: first two bits of opcode
49 00 - neither of source operands is GPR
50 01 - second source operand is GPR (rB)
51 10 - first source operand is GPR (rA)
52 11 - both source operands are GPRs (rA and rB)
53 machine[29:26]: next four bits of opcode
54 machine[25:00]: instruction operands (specific to individual instruction)
55
56 Recommendation: irrelevant instruction bits should be set with a value of
57 bits in same positions of instruction preceding current instruction in the
58 code (when assembling). */
59
60#define EFN &l_none
61
62#ifdef HAS_EXECUTION
63#define EF(func) &(func)
64#define EFI &l_invalid
65#else /* HAS_EXECUTION */
66#define EF(func) EFN
67#define EFI EFN
68#endif /* HAS_EXECUTION */
69
70const struct or32_opcode or32_opcodes[] =
47b0e7ad
NC
71{
72 { "l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY },
73 { "l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY },
74 { "l.bnf", "N", "00 0x3 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG},
75 { "l.bf", "N", "00 0x4 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG },
76 { "l.nop", "K", "00 0x5 01--- ----- KKKK KKKK KKKK KKKK", EF(l_nop), 0 },
77 { "l.movhi", "rD,K", "00 0x6 DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/
78 { "l.macrc", "rD", "00 0x6 DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/
79
80 { "l.sys", "K", "00 0x8 00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 },
81 { "l.trap", "K", "00 0x8 01000 00000 KKKK KKKK KKKK KKKK", EF(l_trap), 0 }, /* CZ 21/06/01 */
82 { "l.msync", "", "00 0x8 10000 00000 0000 0000 0000 0000", EFN, 0 },
83 { "l.psync", "", "00 0x8 10100 00000 0000 0000 0000 0000", EFN, 0 },
84 { "l.csync", "", "00 0x8 11000 00000 0000 0000 0000 0000", EFN, 0 },
85 { "l.rfe", "", "00 0x9 ----- ----- ---- ---- ---- ----", EF(l_rfe), OR32_IF_DELAY },
86
87 { "lv.all_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
88 { "lv.all_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
89 { "lv.all_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
90 { "lv.all_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
91 { "lv.all_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
92 { "lv.all_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
93 { "lv.all_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
94 { "lv.all_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
95 { "lv.all_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
96 { "lv.all_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
97 { "lv.all_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
98 { "lv.all_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
99 { "lv.any_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0 },
100 { "lv.any_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0 },
101 { "lv.any_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0 },
102 { "lv.any_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0 },
103 { "lv.any_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0 },
104 { "lv.any_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0 },
105 { "lv.any_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0 },
106 { "lv.any_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0 },
107 { "lv.any_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0 },
108 { "lv.any_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0 },
109 { "lv.any_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0 },
110 { "lv.any_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0 },
111 { "lv.add.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0 },
112 { "lv.add.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0 },
113 { "lv.adds.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0 },
114 { "lv.adds.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0 },
115 { "lv.addu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0 },
116 { "lv.addu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0 },
117 { "lv.addus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0 },
118 { "lv.addus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0 },
119 { "lv.and", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0 },
120 { "lv.avg.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0 },
121 { "lv.avg.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0 },
122 { "lv.cmp_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0 },
123 { "lv.cmp_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0 },
124 { "lv.cmp_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0 },
125 { "lv.cmp_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0 },
126 { "lv.cmp_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0 },
127 { "lv.cmp_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0 },
128 { "lv.cmp_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0 },
129 { "lv.cmp_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0 },
130 { "lv.cmp_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0 },
131 { "lv.cmp_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0 },
132 { "lv.cmp_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0 },
133 { "lv.cmp_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0 },
134 { "lv.madds.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0 },
135 { "lv.max.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0 },
136 { "lv.max.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0 },
137 { "lv.merge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0 },
138 { "lv.merge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0 },
139 { "lv.min.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0 },
140 { "lv.min.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0 },
141 { "lv.msubs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0 },
142 { "lv.muls.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0 },
143 { "lv.nand", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0 },
144 { "lv.nor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0 },
145 { "lv.or", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0 },
146 { "lv.pack.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0 },
147 { "lv.pack.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0 },
148 { "lv.packs.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0 },
149 { "lv.packs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0 },
150 { "lv.packus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0 },
151 { "lv.packus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0 },
152 { "lv.perm.n", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0 },
153 { "lv.rl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0 },
154 { "lv.rl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0 },
155 { "lv.sll.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0 },
156 { "lv.sll.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0 },
157 { "lv.sll", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0 },
158 { "lv.srl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0 },
159 { "lv.srl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0 },
160 { "lv.sra.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0 },
161 { "lv.sra.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0 },
162 { "lv.srl", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0 },
163 { "lv.sub.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0 },
164 { "lv.sub.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0 },
165 { "lv.subs.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0 },
166 { "lv.subs.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0 },
167 { "lv.subu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0 },
168 { "lv.subu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0 },
169 { "lv.subus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0 },
170 { "lv.subus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0 },
171 { "lv.unpack.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0 },
172 { "lv.unpack.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0 },
173 { "lv.xor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0 },
174 { "lv.cust1", "", "00 0xA ----- ----- ---- ---- 0xC ----", EFI, 0 },
175 { "lv.cust2", "", "00 0xA ----- ----- ---- ---- 0xD ----", EFI, 0 },
176 { "lv.cust3", "", "00 0xA ----- ----- ---- ---- 0xE ----", EFI, 0 },
177 { "lv.cust4", "", "00 0xA ----- ----- ---- ---- 0xF ----", EFI, 0 },
178
179 { "lf.add.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
180 { "lf.sub.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
181 { "lf.mul.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
182 { "lf.div.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
183 { "lf.itof.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
184 { "lf.ftoi.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
185 { "lf.rem.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
186 { "lf.madd.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
187 { "lf.sfeq.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
188 { "lf.sfne.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
189 { "lf.sfgt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
190 { "lf.sfge.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
191 { "lf.sflt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
192 { "lf.sfle.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
193 { "lf.cust1.s", "", "00 0xB ----- ----- ---- ---- 0xE ----", EFI, 0 },
194
195 { "lf.add.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
196 { "lf.sub.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
197 { "lf.mul.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
198 { "lf.div.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
199 { "lf.itof.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
200 { "lf.ftoi.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
201 { "lf.rem.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
202 { "lf.madd.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
203 { "lf.sfeq.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
204 { "lf.sfne.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
205 { "lf.sfgt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
206 { "lf.sfge.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
207 { "lf.sflt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
208 { "lf.sfle.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
209 { "lf.cust1.d", "", "00 0xC ----- ----- ---- ---- 0xE ----", EFI, 0 },
210
211 { "lvf.ld", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x0", EFI, 0 },
212 { "lvf.lw", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x1", EFI, 0 },
213 { "lvf.sd", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
214 { "lvf.sw", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
215
216 { "l.jr", "rB", "01 0x1 ----- ----- BBBB B--- ---- ----", EF(l_jr), OR32_IF_DELAY },
217 { "l.jalr", "rB", "01 0x2 ----- ----- BBBB B--- ---- ----", EF(l_jalr), OR32_IF_DELAY },
218 { "l.maci", "rB,I", "01 0x3 IIIII ----- BBBB BIII IIII IIII", EF(l_mac), 0 },
219 { "l.cust1", "", "01 0xC ----- ----- ---- ---- ---- ----", EF(l_cust1), 0 },
220 { "l.cust2", "", "01 0xD ----- ----- ---- ---- ---- ----", EF(l_cust2), 0 },
221 { "l.cust3", "", "01 0xE ----- ----- ---- ---- ---- ----", EF(l_cust3), 0 },
222 { "l.cust4", "", "01 0xF ----- ----- ---- ---- ---- ----", EF(l_cust4), 0 },
223
224 { "l.ld", "rD,I(rA)", "10 0x0 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
225 { "l.lwz", "rD,I(rA)", "10 0x1 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lwz), 0 },
226 { "l.lws", "rD,I(rA)", "10 0x2 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
227 { "l.lbz", "rD,I(rA)", "10 0x3 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbz), 0 },
228 { "l.lbs", "rD,I(rA)", "10 0x4 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbs), 0 },
229 { "l.lhz", "rD,I(rA)", "10 0x5 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhz), 0 },
230 { "l.lhs", "rD,I(rA)", "10 0x6 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhs), 0 },
231
232 { "l.addi", "rD,rA,I", "10 0x7 DDDDD AAAAA IIII IIII IIII IIII", EF(l_add), 0 },
233 { "l.addic", "rD,rA,I", "10 0x8 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
234 { "l.andi", "rD,rA,K", "10 0x9 DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_and), 0 },
235 { "l.ori", "rD,rA,K", "10 0xA DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_or), 0 },
236 { "l.xori", "rD,rA,I", "10 0xB DDDDD AAAAA IIII IIII IIII IIII", EF(l_xor), 0 },
237 { "l.muli", "rD,rA,I", "10 0xC DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
238 { "l.mfspr", "rD,rA,K", "10 0xD DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 },
239 { "l.slli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 },
240 { "l.srli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 },
241 { "l.srai", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 },
242 { "l.rori", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 },
243
244 { "l.sfeqi", "rA,I", "10 0xF 00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), OR32_W_FLAG },
245 { "l.sfnei", "rA,I", "10 0xF 00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), OR32_W_FLAG },
246 { "l.sfgtui", "rA,I", "10 0xF 00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), OR32_W_FLAG },
247 { "l.sfgeui", "rA,I", "10 0xF 00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), OR32_W_FLAG },
248 { "l.sfltui", "rA,I", "10 0xF 00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), OR32_W_FLAG },
249 { "l.sfleui", "rA,I", "10 0xF 00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), OR32_W_FLAG },
250 { "l.sfgtsi", "rA,I", "10 0xF 01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), OR32_W_FLAG },
251 { "l.sfgesi", "rA,I", "10 0xF 01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), OR32_W_FLAG },
252 { "l.sfltsi", "rA,I", "10 0xF 01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), OR32_W_FLAG },
253 { "l.sflesi", "rA,I", "10 0xF 01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), OR32_W_FLAG },
254
255 { "l.mtspr", "rA,rB,K", "11 0x0 KKKKK AAAAA BBBB BKKK KKKK KKKK", EF(l_mtspr), 0 },
256 { "l.mac", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x1", EF(l_mac), 0 }, /*MM*/
257 { "l.msb", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x2", EF(l_msb), 0 }, /*MM*/
258
259 { "l.sd", "I(rA),rB", "11 0x4 IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 },
260 { "l.sw", "I(rA),rB", "11 0x5 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 },
261 { "l.sb", "I(rA),rB", "11 0x6 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 },
262 { "l.sh", "I(rA),rB", "11 0x7 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
3b16e843 263
47b0e7ad
NC
264 { "l.add", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x0", EF(l_add), 0 },
265 { "l.addc", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x1", EFI, 0 },
266 { "l.sub", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x2", EF(l_sub), 0 },
267 { "l.and", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x3", EF(l_and), 0 },
268 { "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
269 { "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
270 { "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
271
272 { "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
273 { "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
274 { "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
275 { "l.ror", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 },
276 { "l.div", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 },
277 { "l.divu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 },
278 { "l.mulu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 },
279 { "l.exths", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xC", EFI, 0 },
280 { "l.extbs", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xC", EFI, 0 },
281 { "l.exthz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0xC", EFI, 0 },
282 { "l.extbz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0xC", EFI, 0 },
283 { "l.extws", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xD", EFI, 0 },
284 { "l.extwz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xD", EFI, 0 },
285 { "l.cmov", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 },
286 { "l.ff1", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 },
287
288 { "l.sfeq", "rA,rB", "11 0x9 00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), OR32_W_FLAG },
289 { "l.sfne", "rA,rB", "11 0x9 00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), OR32_W_FLAG },
290 { "l.sfgtu", "rA,rB", "11 0x9 00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), OR32_W_FLAG },
291 { "l.sfgeu", "rA,rB", "11 0x9 00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), OR32_W_FLAG },
292 { "l.sfltu", "rA,rB", "11 0x9 00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), OR32_W_FLAG },
293 { "l.sfleu", "rA,rB", "11 0x9 00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), OR32_W_FLAG },
294 { "l.sfgts", "rA,rB", "11 0x9 01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), OR32_W_FLAG },
295 { "l.sfges", "rA,rB", "11 0x9 01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), OR32_W_FLAG },
296 { "l.sflts", "rA,rB", "11 0x9 01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), OR32_W_FLAG },
297 { "l.sfles", "rA,rB", "11 0x9 01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), OR32_W_FLAG },
298
299 { "l.cust5", "", "11 0xC ----- ----- ---- ---- ---- ----", EFI, 0 },
300 { "l.cust6", "", "11 0xD ----- ----- ---- ---- ---- ----", EFI, 0 },
301 { "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
302 { "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
303
304 /* This section should not be defined in or1ksim, since it contains duplicates,
305 which would cause machine builder to complain. */
3b16e843 306#ifdef HAS_CUST
47b0e7ad
NC
307 { "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
308 { "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
309 { "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 310
47b0e7ad
NC
311 { "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
312 { "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
313 { "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 314
47b0e7ad
NC
315 { "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
316 { "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
317 { "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 318
47b0e7ad
NC
319 { "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
320 { "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
321 { "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843
NC
322#endif
323
47b0e7ad
NC
324 /* Dummy entry, not included in num_opcodes. This
325 lets code examine entry i+1 without checking
326 if we've run off the end of the table. */
327 { "", "", "", EFI, 0 }
3b16e843
NC
328};
329
330#undef EFI
331#undef EFN
332#undef EF
333
334/* Define dummy, if debug is not defined. */
335
336#if !defined HAS_DEBUG
0fd3a477 337static void ATTRIBUTE_PRINTF_2
5da8bf1b 338debug (int level ATTRIBUTE_UNUSED, const char *format ATTRIBUTE_UNUSED, ...)
3b16e843 339{
3b16e843
NC
340}
341#endif
342
343const unsigned int or32_num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
344
345/* Calculates instruction length in bytes. Always 4 for OR32. */
346
347int
47b0e7ad 348insn_len (int insn_index ATTRIBUTE_UNUSED)
3b16e843
NC
349{
350 return 4;
351}
352
353/* Is individual insn's operand signed or unsigned? */
354
355int
47b0e7ad 356letter_signed (char l)
3b16e843
NC
357{
358 const struct or32_letter *pletter;
359
360 for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
361 if (pletter->letter == l)
362 return pletter->sign;
363
364 printf ("letter_signed(%c): Unknown letter.\n", l);
365 return 0;
366}
367
368/* Number of letters in the individual lettered operand. */
369
370int
47b0e7ad 371letter_range (char l)
3b16e843
NC
372{
373 const struct or32_opcode *pinsn;
374 char *enc;
375 int range = 0;
376
47b0e7ad 377 for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn ++)
3b16e843
NC
378 {
379 if (strchr (pinsn->encoding,l))
380 {
47b0e7ad
NC
381 for (enc = pinsn->encoding; *enc != '\0'; enc ++)
382 if ((*enc == '0') && (*(enc + 1) == 'x'))
3b16e843
NC
383 enc += 2;
384 else if (*enc == l)
385 range++;
386 return range;
387 }
388 }
389
390 printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
391 exit (1);
392}
393
394/* MM: Returns index of given instruction name. */
395
396int
397insn_index (char *insn)
398{
5e37cc46
NC
399 unsigned int i;
400 int found = -1;
3b16e843
NC
401
402 for (i = 0; i < or32_num_opcodes; i++)
403 if (!strcmp (or32_opcodes[i].name, insn))
404 {
405 found = i;
406 break;
407 }
408 return found;
409}
410
411const char *
47b0e7ad 412insn_name (int index)
3b16e843 413{
5e37cc46 414 if (index >= 0 && index < (int) or32_num_opcodes)
3b16e843
NC
415 return or32_opcodes[index].name;
416 else
417 return "???";
418}
419
420void
47b0e7ad 421l_none (void)
3b16e843
NC
422{
423}
424
425/* Finite automata for instruction decoding building code. */
426
427/* Find simbols in encoding. */
47b0e7ad 428
3b16e843 429static unsigned long
47b0e7ad 430insn_extract (char param_ch, char *enc_initial)
3b16e843
NC
431{
432 char *enc;
433 unsigned long ret = 0;
434 unsigned opc_pos = 32;
435
436 for (enc = enc_initial; *enc != '\0'; )
437 if ((*enc == '0') && (*(enc + 1) == 'x'))
438 {
439 unsigned long tmp = strtol (enc+2, NULL, 16);
440
441 opc_pos -= 4;
442 if (param_ch == '0' || param_ch == '1')
443 {
444 if (param_ch == '0')
445 tmp = 15 - tmp;
446 ret |= tmp << opc_pos;
447 }
448 enc += 3;
449 }
450 else
451 {
452 if (*enc == '0' || *enc == '1' || *enc == '-' || ISALPHA (*enc))
453 {
454 opc_pos--;
455 if (param_ch == *enc)
456 ret |= 1 << opc_pos;
457 }
458 enc++;
459 }
460 return ret;
461}
462
47b0e7ad
NC
463#define MAX_AUTOMATA_SIZE 1200
464#define MAX_OP_TABLE_SIZE 1200
465#define LEAF_FLAG 0x80000000
466#define MAX_LEN 8
3b16e843
NC
467
468#ifndef MIN
47b0e7ad 469#define MIN(x, y) ((x) < (y) ? (x) : (y))
3b16e843
NC
470#endif
471
472unsigned long *automata;
473int nuncovered;
474int curpass = 0;
475
476/* MM: Struct that hold runtime build information about instructions. */
477struct temp_insn_struct
478{
479 unsigned long insn;
480 unsigned long insn_mask;
481 int in_pass;
482} *ti;
483
484struct insn_op_struct *op_data, **op_start;
485
486/* Recursive utility function used to find best match and to build automata. */
487
488static unsigned long *
47b0e7ad 489cover_insn (unsigned long * cur, int pass, unsigned int mask)
3b16e843 490{
5e37cc46
NC
491 int best_first = 0, last_match = -1, ninstr = 0;
492 unsigned int best_len = 0;
493 unsigned int i;
3b16e843
NC
494 unsigned long cur_mask = mask;
495 unsigned long *next;
496
497 for (i = 0; i < or32_num_opcodes; i++)
498 if (ti[i].in_pass == pass)
499 {
500 cur_mask &= ti[i].insn_mask;
501 ninstr++;
502 last_match = i;
503 }
504
0fd3a477 505 debug (8, "%08X %08lX\n", mask, cur_mask);
3b16e843
NC
506
507 if (ninstr == 0)
508 return 0;
509
510 if (ninstr == 1)
511 {
512 /* Leaf holds instruction index. */
0fd3a477
JW
513 debug (8, "%li>I%i %s\n",
514 (long)(cur - automata), last_match, or32_opcodes[last_match].name);
3b16e843
NC
515
516 *cur = LEAF_FLAG | last_match;
517 cur++;
518 nuncovered--;
519 }
520 else
521 {
522 /* Find longest match. */
523 for (i = 0; i < 32; i++)
524 {
5e37cc46 525 unsigned int len;
3b16e843
NC
526
527 for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
528 {
47b0e7ad 529 unsigned long m = (1UL << ((unsigned long) len)) - 1;
3b16e843 530
0fd3a477 531 debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)",
3b16e843 532 len,m, cur_mask, i, (cur_mask >> (unsigned)i),
47b0e7ad 533 (cur_mask >> (unsigned) i) & m);
3b16e843 534
47b0e7ad 535 if ((m & (cur_mask >> (unsigned) i)) == m)
3b16e843
NC
536 {
537 best_len = len;
538 best_first = i;
539 debug (9, "!");
540 }
541 else
542 break;
543 }
544 }
545
546 debug (9, "\n");
547
548 if (!best_len)
549 {
550 fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask);
551
552 for (i = 0; i < or32_num_opcodes; i++)
553 if (ti[i].in_pass == pass)
554 fprintf (stderr, "%s ", or32_opcodes[i].name);
555
556 fprintf (stderr, "\n");
557 exit (1);
558 }
559
0fd3a477
JW
560 debug (8, "%li> #### %i << %i (%i) ####\n",
561 (long)(cur - automata), best_len, best_first, ninstr);
3b16e843
NC
562
563 *cur = best_first;
564 cur++;
565 *cur = (1 << best_len) - 1;
566 cur++;
567 next = cur;
568
569 /* Allocate space for pointers. */
570 cur += 1 << best_len;
47b0e7ad 571 cur_mask = (1 << (unsigned long) best_len) - 1;
3b16e843 572
5e37cc46 573 for (i = 0; i < ((unsigned) 1 << best_len); i++)
3b16e843 574 {
5e37cc46 575 unsigned int j;
3b16e843
NC
576 unsigned long *c;
577
578 curpass++;
579 for (j = 0; j < or32_num_opcodes; j++)
580 if (ti[j].in_pass == pass
581 && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i
582 && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
583 ti[j].in_pass = curpass;
584
0fd3a477 585 debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
3b16e843
NC
586 c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
587 if (c)
588 {
0fd3a477 589 debug (8, "%li> #%X -> %lu\n", (long)(next - automata), i, (long)(cur - automata));
3b16e843
NC
590 *next = cur - automata;
591 cur = c;
592 }
593 else
594 {
0fd3a477 595 debug (8, "%li> N/A\n", (long)(next - automata));
3b16e843
NC
596 *next = 0;
597 }
598 next++;
599 }
600 }
601 return cur;
602}
603
604/* Returns number of nonzero bits. */
605
606static int
47b0e7ad 607num_ones (unsigned long value)
3b16e843
NC
608{
609 int c = 0;
610
611 while (value)
612 {
613 if (value & 1)
614 c++;
615 value >>= 1;
616 }
617 return c;
618}
619
47b0e7ad
NC
620/* Utility function, which converts parameters from or32_opcode
621 format to more binary form. Parameters are stored in ti struct. */
3b16e843
NC
622
623static struct insn_op_struct *
47b0e7ad
NC
624parse_params (const struct or32_opcode * opcode,
625 struct insn_op_struct * cur)
3b16e843
NC
626{
627 char *args = opcode->args;
628 int i, type;
629
630 i = 0;
631 type = 0;
632 /* In case we don't have any parameters, we add dummy read from r0. */
633
634 if (!(*args))
635 {
636 cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
637 cur->data = 0;
0fd3a477 638 debug (9, "#%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
639 cur++;
640 return cur;
641 }
642
643 while (*args != '\0')
644 {
645 if (*args == 'r')
646 {
647 args++;
648 type |= OPTYPE_REG;
649 }
650 else if (ISALPHA (*args))
651 {
652 unsigned long arg;
653
654 arg = insn_extract (*args, opcode->encoding);
0fd3a477 655 debug (9, "%s : %08lX ------\n", opcode->name, arg);
3b16e843
NC
656 if (letter_signed (*args))
657 {
658 type |= OPTYPE_SIG;
659 type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
660 }
661
662 /* Split argument to sequences of consecutive ones. */
663 while (arg)
664 {
665 int shr = 0;
666 unsigned long tmp = arg, mask = 0;
667
668 while ((tmp & 1) == 0)
669 {
670 shr++;
671 tmp >>= 1;
672 }
673 while (tmp & 1)
674 {
675 mask++;
676 tmp >>= 1;
677 }
678 cur->type = type | shr;
679 cur->data = mask;
680 arg &= ~(((1 << mask) - 1) << shr);
0fd3a477 681 debug (6, "|%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
682 cur++;
683 }
684 args++;
685 }
686 else if (*args == '(')
687 {
47b0e7ad
NC
688 /* Next param is displacement.
689 Later we will treat them as one operand. */
3b16e843
NC
690 cur--;
691 cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
0fd3a477 692 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
693 cur++;
694 type = 0;
695 i++;
696 args++;
697 }
698 else if (*args == OPERAND_DELIM)
699 {
700 cur--;
701 cur->type = type | cur->type | OPTYPE_OP;
0fd3a477 702 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
703 cur++;
704 type = 0;
705 i++;
706 args++;
707 }
708 else if (*args == '0')
709 {
710 cur->type = type;
711 cur->data = 0;
0fd3a477 712 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
713 cur++;
714 type = 0;
715 i++;
716 args++;
717 }
718 else if (*args == ')')
719 args++;
720 else
721 {
722 fprintf (stderr, "%s : parse error in args.\n", opcode->name);
723 exit (1);
724 }
725 }
726
727 cur--;
728 cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
0fd3a477 729 debug (9, "#%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
730 cur++;
731
732 return cur;
733}
734
735/* Constructs new automata based on or32_opcodes array. */
736
737void
47b0e7ad 738build_automata (void)
3b16e843 739{
5e37cc46 740 unsigned int i;
3b16e843
NC
741 unsigned long *end;
742 struct insn_op_struct *cur;
743
47b0e7ad
NC
744 automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
745 ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes);
3b16e843
NC
746
747 nuncovered = or32_num_opcodes;
748 printf ("Building automata... ");
749 /* Build temporary information about instructions. */
750 for (i = 0; i < or32_num_opcodes; i++)
751 {
752 unsigned long ones, zeros;
753 char *encoding = or32_opcodes[i].encoding;
754
755 ones = insn_extract('1', encoding);
756 zeros = insn_extract('0', encoding);
757
758 ti[i].insn_mask = ones | zeros;
759 ti[i].insn = ones;
760 ti[i].in_pass = curpass = 0;
761
762 /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
763 or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
764 }
765
766 /* Until all are covered search for best criteria to separate them. */
767 end = cover_insn (automata, curpass, 0xFFFFFFFF);
768
769 if (end - automata > MAX_AUTOMATA_SIZE)
770 {
771 fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
772 exit (1);
773 }
774
775 printf ("done, num uncovered: %i/%i.\n", nuncovered, or32_num_opcodes);
776 printf ("Parsing operands data... ");
777
47b0e7ad
NC
778 op_data = malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct));
779 op_start = malloc (or32_num_opcodes * sizeof (struct insn_op_struct *));
3b16e843
NC
780 cur = op_data;
781
782 for (i = 0; i < or32_num_opcodes; i++)
783 {
784 op_start[i] = cur;
785 cur = parse_params (&or32_opcodes[i], cur);
786
787 if (cur - op_data > MAX_OP_TABLE_SIZE)
788 {
789 fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
790 exit (1);
791 }
792 }
793 printf ("done.\n");
794}
795
796void
47b0e7ad 797destruct_automata (void)
3b16e843
NC
798{
799 free (ti);
800 free (automata);
801 free (op_data);
802 free (op_start);
803}
804
805/* Decodes instruction and returns instruction index. */
806
807int
47b0e7ad 808insn_decode (unsigned int insn)
3b16e843
NC
809{
810 unsigned long *a = automata;
811 int i;
812
813 while (!(*a & LEAF_FLAG))
814 {
815 unsigned int first = *a;
816
0fd3a477 817 debug (9, "%li ", (long)(a - automata));
3b16e843
NC
818
819 a++;
820 i = (insn >> first) & *a;
821 a++;
822 if (!*(a + i))
823 {
824 /* Invalid instruction found? */
0fd3a477 825 debug (9, "XXX\n");
3b16e843
NC
826 return -1;
827 }
828 a = automata + *(a + i);
829 }
830
831 i = *a & ~LEAF_FLAG;
832
833 debug (9, "%i\n", i);
834
835 /* Final check - do we have direct match?
836 (based on or32_opcodes this should be the only possibility,
837 but in case of invalid/missing instruction we must perform a check) */
838 if ((ti[i].insn_mask & insn) == ti[i].insn)
839 return i;
840 else
841 return -1;
842}
843
844static char disassembled_str[50];
845char *disassembled = &disassembled_str[0];
846
847/* Automagically does zero- or sign- extension and also finds correct
848 sign bit position if sign extension is correct extension. Which extension
849 is proper is figured out from letter description. */
850
851static unsigned long
47b0e7ad 852extend_imm (unsigned long imm, char l)
3b16e843
NC
853{
854 unsigned long mask;
855 int letter_bits;
856
857 /* First truncate all bits above valid range for this letter
858 in case it is zero extend. */
859 letter_bits = letter_range (l);
860 mask = (1 << letter_bits) - 1;
861 imm &= mask;
862
863 /* Do sign extend if this is the right one. */
864 if (letter_signed(l) && (imm >> (letter_bits - 1)))
865 imm |= (~mask);
866
867 return imm;
868}
869
870static unsigned long
47b0e7ad 871or32_extract (char param_ch, char *enc_initial, unsigned long insn)
3b16e843
NC
872{
873 char *enc;
874 unsigned long ret = 0;
875 int opc_pos = 0;
876 int param_pos = 0;
877
878 for (enc = enc_initial; *enc != '\0'; enc++)
879 if (*enc == param_ch)
880 {
881 if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
882 continue;
883 else
884 param_pos++;
885 }
886
887#if DEBUG
888 printf ("or32_extract: %x ", param_pos);
889#endif
890 opc_pos = 32;
891
892 for (enc = enc_initial; *enc != '\0'; )
893 if ((*enc == '0') && (*(enc + 1) == 'x'))
894 {
895 opc_pos -= 4;
896 if ((param_ch == '0') || (param_ch == '1'))
897 {
898 unsigned long tmp = strtol (enc, NULL, 16);
899#if DEBUG
900 printf (" enc=%s, tmp=%x ", enc, tmp);
901#endif
902 if (param_ch == '0')
903 tmp = 15 - tmp;
904 ret |= tmp << opc_pos;
905 }
906 enc += 3;
907 }
908 else if ((*enc == '0') || (*enc == '1'))
909 {
910 opc_pos--;
911 if (param_ch == *enc)
912 ret |= 1 << opc_pos;
913 enc++;
914 }
915 else if (*enc == param_ch)
916 {
917 opc_pos--;
918 param_pos--;
919#if DEBUG
920 printf ("\n ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
921#endif
922 if (ISLOWER (param_ch))
923 ret -= ((insn >> opc_pos) & 0x1) << param_pos;
924 else
925 ret += ((insn >> opc_pos) & 0x1) << param_pos;
926 enc++;
927 }
928 else if (ISALPHA (*enc))
929 {
930 opc_pos--;
931 enc++;
932 }
933 else if (*enc == '-')
934 {
935 opc_pos--;
936 enc++;
937 }
938 else
939 enc++;
940
941#if DEBUG
942 printf ("ret=%x\n", ret);
943#endif
944 return ret;
945}
946
947/* Print register. Used only by print_insn. */
948
949static void
47b0e7ad 950or32_print_register (char param_ch, char *encoding, unsigned long insn)
3b16e843
NC
951{
952 int regnum = or32_extract(param_ch, encoding, insn);
953
954 sprintf (disassembled, "%sr%d", disassembled, regnum);
955}
956
957/* Print immediate. Used only by print_insn. */
958
959static void
47b0e7ad 960or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
3b16e843
NC
961{
962 int imm = or32_extract (param_ch, encoding, insn);
963
964 imm = extend_imm (imm, param_ch);
965
966 if (letter_signed (param_ch))
967 {
968 if (imm < 0)
969 sprintf (disassembled, "%s%d", disassembled, imm);
970 else
971 sprintf (disassembled, "%s0x%x", disassembled, imm);
972 }
973 else
974 sprintf (disassembled, "%s%#x", disassembled, imm);
975}
976
977/* Disassemble one instruction from insn to disassemble.
978 Return the size of the instruction. */
979
980int
47b0e7ad 981disassemble_insn (unsigned long insn)
3b16e843
NC
982{
983 int index;
984 index = insn_decode (insn);
985
986 if (index >= 0)
987 {
988 struct or32_opcode const *opcode = &or32_opcodes[index];
989 char *s;
990
991 sprintf (disassembled, "%s ", opcode->name);
992 for (s = opcode->args; *s != '\0'; ++s)
993 {
994 switch (*s)
995 {
996 case '\0':
997 return 4;
998
999 case 'r':
1000 or32_print_register (*++s, opcode->encoding, insn);
1001 break;
1002
1003 default:
1004 if (strchr (opcode->encoding, *s))
1005 or32_print_immediate (*s, opcode->encoding, insn);
1006 else
1007 sprintf (disassembled, "%s%c", disassembled, *s);
1008 }
1009 }
1010 }
1011 else
1012 {
1013 /* This used to be %8x for binutils. */
1014 sprintf (disassembled, "%s.word 0x%08lx", disassembled, insn);
1015 }
1016
1017 return insn_len (insn);
1018}
This page took 0.312353 seconds and 4 git commands to generate.