Linux process record and replay support.
[deliverable/binutils-gdb.git] / opcodes / or32-opc.c
CommitLineData
3b16e843 1/* Table of opcodes for the OpenRISC 1000 ISA.
4ef2cf8b 2 Copyright 2002, 2004, 2005, 2007, 2008, 2009 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 {
0af1713e
AM
589 debug (8, "%li> #%X -> %lu\n", (long)(next - automata), i,
590 (unsigned long)(cur - automata));
3b16e843
NC
591 *next = cur - automata;
592 cur = c;
593 }
594 else
595 {
0fd3a477 596 debug (8, "%li> N/A\n", (long)(next - automata));
3b16e843
NC
597 *next = 0;
598 }
599 next++;
600 }
601 }
602 return cur;
603}
604
605/* Returns number of nonzero bits. */
606
607static int
47b0e7ad 608num_ones (unsigned long value)
3b16e843
NC
609{
610 int c = 0;
611
612 while (value)
613 {
614 if (value & 1)
615 c++;
616 value >>= 1;
617 }
618 return c;
619}
620
47b0e7ad
NC
621/* Utility function, which converts parameters from or32_opcode
622 format to more binary form. Parameters are stored in ti struct. */
3b16e843
NC
623
624static struct insn_op_struct *
47b0e7ad
NC
625parse_params (const struct or32_opcode * opcode,
626 struct insn_op_struct * cur)
3b16e843
NC
627{
628 char *args = opcode->args;
629 int i, type;
630
631 i = 0;
632 type = 0;
633 /* In case we don't have any parameters, we add dummy read from r0. */
634
635 if (!(*args))
636 {
637 cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
638 cur->data = 0;
0fd3a477 639 debug (9, "#%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
640 cur++;
641 return cur;
642 }
643
644 while (*args != '\0')
645 {
646 if (*args == 'r')
647 {
648 args++;
649 type |= OPTYPE_REG;
650 }
651 else if (ISALPHA (*args))
652 {
653 unsigned long arg;
654
655 arg = insn_extract (*args, opcode->encoding);
0fd3a477 656 debug (9, "%s : %08lX ------\n", opcode->name, arg);
3b16e843
NC
657 if (letter_signed (*args))
658 {
659 type |= OPTYPE_SIG;
660 type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
661 }
662
663 /* Split argument to sequences of consecutive ones. */
664 while (arg)
665 {
666 int shr = 0;
667 unsigned long tmp = arg, mask = 0;
668
669 while ((tmp & 1) == 0)
670 {
671 shr++;
672 tmp >>= 1;
673 }
674 while (tmp & 1)
675 {
676 mask++;
677 tmp >>= 1;
678 }
679 cur->type = type | shr;
680 cur->data = mask;
681 arg &= ~(((1 << mask) - 1) << shr);
0fd3a477 682 debug (6, "|%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
683 cur++;
684 }
685 args++;
686 }
687 else if (*args == '(')
688 {
47b0e7ad
NC
689 /* Next param is displacement.
690 Later we will treat them as one operand. */
3b16e843
NC
691 cur--;
692 cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
0fd3a477 693 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
694 cur++;
695 type = 0;
696 i++;
697 args++;
698 }
699 else if (*args == OPERAND_DELIM)
700 {
701 cur--;
702 cur->type = type | cur->type | OPTYPE_OP;
0fd3a477 703 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
704 cur++;
705 type = 0;
706 i++;
707 args++;
708 }
709 else if (*args == '0')
710 {
711 cur->type = type;
712 cur->data = 0;
0fd3a477 713 debug (9, ">%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
714 cur++;
715 type = 0;
716 i++;
717 args++;
718 }
719 else if (*args == ')')
720 args++;
721 else
722 {
723 fprintf (stderr, "%s : parse error in args.\n", opcode->name);
724 exit (1);
725 }
726 }
727
728 cur--;
729 cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
0fd3a477 730 debug (9, "#%08lX %08lX\n", cur->type, cur->data);
3b16e843
NC
731 cur++;
732
733 return cur;
734}
735
736/* Constructs new automata based on or32_opcodes array. */
737
738void
47b0e7ad 739build_automata (void)
3b16e843 740{
5e37cc46 741 unsigned int i;
3b16e843
NC
742 unsigned long *end;
743 struct insn_op_struct *cur;
744
47b0e7ad
NC
745 automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
746 ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes);
3b16e843
NC
747
748 nuncovered = or32_num_opcodes;
749 printf ("Building automata... ");
750 /* Build temporary information about instructions. */
751 for (i = 0; i < or32_num_opcodes; i++)
752 {
753 unsigned long ones, zeros;
754 char *encoding = or32_opcodes[i].encoding;
755
756 ones = insn_extract('1', encoding);
757 zeros = insn_extract('0', encoding);
758
759 ti[i].insn_mask = ones | zeros;
760 ti[i].insn = ones;
761 ti[i].in_pass = curpass = 0;
762
763 /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
764 or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
765 }
766
767 /* Until all are covered search for best criteria to separate them. */
768 end = cover_insn (automata, curpass, 0xFFFFFFFF);
769
770 if (end - automata > MAX_AUTOMATA_SIZE)
771 {
772 fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
773 exit (1);
774 }
775
776 printf ("done, num uncovered: %i/%i.\n", nuncovered, or32_num_opcodes);
777 printf ("Parsing operands data... ");
778
47b0e7ad
NC
779 op_data = malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct));
780 op_start = malloc (or32_num_opcodes * sizeof (struct insn_op_struct *));
3b16e843
NC
781 cur = op_data;
782
783 for (i = 0; i < or32_num_opcodes; i++)
784 {
785 op_start[i] = cur;
786 cur = parse_params (&or32_opcodes[i], cur);
787
788 if (cur - op_data > MAX_OP_TABLE_SIZE)
789 {
790 fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
791 exit (1);
792 }
793 }
794 printf ("done.\n");
795}
796
797void
47b0e7ad 798destruct_automata (void)
3b16e843
NC
799{
800 free (ti);
801 free (automata);
802 free (op_data);
803 free (op_start);
804}
805
806/* Decodes instruction and returns instruction index. */
807
808int
47b0e7ad 809insn_decode (unsigned int insn)
3b16e843
NC
810{
811 unsigned long *a = automata;
812 int i;
813
814 while (!(*a & LEAF_FLAG))
815 {
816 unsigned int first = *a;
817
0fd3a477 818 debug (9, "%li ", (long)(a - automata));
3b16e843
NC
819
820 a++;
821 i = (insn >> first) & *a;
822 a++;
823 if (!*(a + i))
824 {
825 /* Invalid instruction found? */
0fd3a477 826 debug (9, "XXX\n");
3b16e843
NC
827 return -1;
828 }
829 a = automata + *(a + i);
830 }
831
832 i = *a & ~LEAF_FLAG;
833
834 debug (9, "%i\n", i);
835
836 /* Final check - do we have direct match?
837 (based on or32_opcodes this should be the only possibility,
838 but in case of invalid/missing instruction we must perform a check) */
839 if ((ti[i].insn_mask & insn) == ti[i].insn)
840 return i;
841 else
842 return -1;
843}
844
845static char disassembled_str[50];
846char *disassembled = &disassembled_str[0];
847
848/* Automagically does zero- or sign- extension and also finds correct
849 sign bit position if sign extension is correct extension. Which extension
850 is proper is figured out from letter description. */
851
852static unsigned long
47b0e7ad 853extend_imm (unsigned long imm, char l)
3b16e843
NC
854{
855 unsigned long mask;
856 int letter_bits;
857
858 /* First truncate all bits above valid range for this letter
859 in case it is zero extend. */
860 letter_bits = letter_range (l);
861 mask = (1 << letter_bits) - 1;
862 imm &= mask;
863
864 /* Do sign extend if this is the right one. */
865 if (letter_signed(l) && (imm >> (letter_bits - 1)))
866 imm |= (~mask);
867
868 return imm;
869}
870
871static unsigned long
47b0e7ad 872or32_extract (char param_ch, char *enc_initial, unsigned long insn)
3b16e843
NC
873{
874 char *enc;
875 unsigned long ret = 0;
876 int opc_pos = 0;
877 int param_pos = 0;
878
879 for (enc = enc_initial; *enc != '\0'; enc++)
880 if (*enc == param_ch)
881 {
882 if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
883 continue;
884 else
885 param_pos++;
886 }
887
888#if DEBUG
889 printf ("or32_extract: %x ", param_pos);
890#endif
891 opc_pos = 32;
892
893 for (enc = enc_initial; *enc != '\0'; )
894 if ((*enc == '0') && (*(enc + 1) == 'x'))
895 {
896 opc_pos -= 4;
897 if ((param_ch == '0') || (param_ch == '1'))
898 {
899 unsigned long tmp = strtol (enc, NULL, 16);
900#if DEBUG
901 printf (" enc=%s, tmp=%x ", enc, tmp);
902#endif
903 if (param_ch == '0')
904 tmp = 15 - tmp;
905 ret |= tmp << opc_pos;
906 }
907 enc += 3;
908 }
909 else if ((*enc == '0') || (*enc == '1'))
910 {
911 opc_pos--;
912 if (param_ch == *enc)
913 ret |= 1 << opc_pos;
914 enc++;
915 }
916 else if (*enc == param_ch)
917 {
918 opc_pos--;
919 param_pos--;
920#if DEBUG
921 printf ("\n ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
922#endif
923 if (ISLOWER (param_ch))
924 ret -= ((insn >> opc_pos) & 0x1) << param_pos;
925 else
926 ret += ((insn >> opc_pos) & 0x1) << param_pos;
927 enc++;
928 }
929 else if (ISALPHA (*enc))
930 {
931 opc_pos--;
932 enc++;
933 }
934 else if (*enc == '-')
935 {
936 opc_pos--;
937 enc++;
938 }
939 else
940 enc++;
941
942#if DEBUG
943 printf ("ret=%x\n", ret);
944#endif
945 return ret;
946}
947
948/* Print register. Used only by print_insn. */
949
950static void
47b0e7ad 951or32_print_register (char param_ch, char *encoding, unsigned long insn)
3b16e843
NC
952{
953 int regnum = or32_extract(param_ch, encoding, insn);
4ef2cf8b
NC
954 char s_regnum[20];
955
956 sprintf (s_regnum, "r%d", regnum);
957 strcat (disassembled, s_regnum);
3b16e843
NC
958}
959
960/* Print immediate. Used only by print_insn. */
961
962static void
47b0e7ad 963or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
3b16e843
NC
964{
965 int imm = or32_extract (param_ch, encoding, insn);
4ef2cf8b 966 char s_imm[20];
3b16e843
NC
967
968 imm = extend_imm (imm, param_ch);
4ef2cf8b 969
3b16e843
NC
970 if (letter_signed (param_ch))
971 {
972 if (imm < 0)
4ef2cf8b 973 sprintf (s_imm, "%d", imm);
3b16e843 974 else
4ef2cf8b 975 sprintf (s_imm, "0x%x", imm);
3b16e843
NC
976 }
977 else
4ef2cf8b
NC
978 sprintf (s_imm, "%#x", imm);
979 strcat (disassembled, s_imm);
3b16e843
NC
980}
981
982/* Disassemble one instruction from insn to disassemble.
983 Return the size of the instruction. */
984
985int
47b0e7ad 986disassemble_insn (unsigned long insn)
3b16e843
NC
987{
988 int index;
989 index = insn_decode (insn);
990
991 if (index >= 0)
992 {
993 struct or32_opcode const *opcode = &or32_opcodes[index];
994 char *s;
995
996 sprintf (disassembled, "%s ", opcode->name);
997 for (s = opcode->args; *s != '\0'; ++s)
998 {
999 switch (*s)
1000 {
1001 case '\0':
1002 return 4;
1003
1004 case 'r':
1005 or32_print_register (*++s, opcode->encoding, insn);
1006 break;
1007
1008 default:
1009 if (strchr (opcode->encoding, *s))
1010 or32_print_immediate (*s, opcode->encoding, insn);
1011 else
4ef2cf8b
NC
1012 {
1013 char s_encoding[2] = { *s, '\0' };
1014
1015 strcat (disassembled, s_encoding);
1016 }
1017
3b16e843
NC
1018 }
1019 }
1020 }
1021 else
1022 {
4ef2cf8b
NC
1023 char s_insn[20];
1024
3b16e843 1025 /* This used to be %8x for binutils. */
4ef2cf8b
NC
1026 sprintf (s_insn, ".word 0x%08lx", insn);
1027 strcat (disassembled, s_insn);
3b16e843
NC
1028 }
1029
1030 return insn_len (insn);
1031}
This page took 0.36019 seconds and 4 git commands to generate.