Fix overflow handling of VLE_SDA21
[deliverable/binutils-gdb.git] / opcodes / or32-opc.c
CommitLineData
3b16e843 1/* Table of opcodes for the OpenRISC 1000 ISA.
4b95cf5c 2 Copyright (C) 2002-2014 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 21
df7b86aa 22#include "sysdep.h"
3b16e843
NC
23#include <string.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include "safe-ctype.h"
27#include "ansidecl.h"
3b16e843
NC
28#include "opcode/or32.h"
29
df7b86aa
NC
30/* We treat all letters the same in encode/decode routines so
31 we need to assign some characteristics to them like signess etc. */
32
3b16e843 33const struct or32_letter or32_letters[] =
47b0e7ad
NC
34{
35 { 'A', NUM_UNSIGNED },
36 { 'B', NUM_UNSIGNED },
37 { 'D', NUM_UNSIGNED },
38 { 'I', NUM_SIGNED },
39 { 'K', NUM_UNSIGNED },
40 { 'L', NUM_UNSIGNED },
41 { 'N', NUM_SIGNED },
42 { '0', NUM_UNSIGNED },
43 { '\0', 0 } /* Dummy entry. */
44};
3b16e843
NC
45
46/* Opcode encoding:
47 machine[31:30]: first two bits of opcode
48 00 - neither of source operands is GPR
49 01 - second source operand is GPR (rB)
50 10 - first source operand is GPR (rA)
51 11 - both source operands are GPRs (rA and rB)
52 machine[29:26]: next four bits of opcode
53 machine[25:00]: instruction operands (specific to individual instruction)
54
55 Recommendation: irrelevant instruction bits should be set with a value of
56 bits in same positions of instruction preceding current instruction in the
57 code (when assembling). */
58
59#define EFN &l_none
60
61#ifdef HAS_EXECUTION
62#define EF(func) &(func)
63#define EFI &l_invalid
64#else /* HAS_EXECUTION */
65#define EF(func) EFN
66#define EFI EFN
67#endif /* HAS_EXECUTION */
68
69const struct or32_opcode or32_opcodes[] =
47b0e7ad
NC
70{
71 { "l.j", "N", "00 0x0 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY },
72 { "l.jal", "N", "00 0x1 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY },
73 { "l.bnf", "N", "00 0x3 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG},
74 { "l.bf", "N", "00 0x4 NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG },
75 { "l.nop", "K", "00 0x5 01--- ----- KKKK KKKK KKKK KKKK", EF(l_nop), 0 },
76 { "l.movhi", "rD,K", "00 0x6 DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/
77 { "l.macrc", "rD", "00 0x6 DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/
78
79 { "l.sys", "K", "00 0x8 00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 },
80 { "l.trap", "K", "00 0x8 01000 00000 KKKK KKKK KKKK KKKK", EF(l_trap), 0 }, /* CZ 21/06/01 */
81 { "l.msync", "", "00 0x8 10000 00000 0000 0000 0000 0000", EFN, 0 },
82 { "l.psync", "", "00 0x8 10100 00000 0000 0000 0000 0000", EFN, 0 },
83 { "l.csync", "", "00 0x8 11000 00000 0000 0000 0000 0000", EFN, 0 },
84 { "l.rfe", "", "00 0x9 ----- ----- ---- ---- ---- ----", EF(l_rfe), OR32_IF_DELAY },
85
86 { "lv.all_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
87 { "lv.all_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
88 { "lv.all_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
89 { "lv.all_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
90 { "lv.all_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
91 { "lv.all_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
92 { "lv.all_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
93 { "lv.all_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
94 { "lv.all_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
95 { "lv.all_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
96 { "lv.all_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
97 { "lv.all_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
98 { "lv.any_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0 },
99 { "lv.any_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0 },
100 { "lv.any_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0 },
101 { "lv.any_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0 },
102 { "lv.any_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0 },
103 { "lv.any_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0 },
104 { "lv.any_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0 },
105 { "lv.any_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0 },
106 { "lv.any_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0 },
107 { "lv.any_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0 },
108 { "lv.any_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0 },
109 { "lv.any_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0 },
110 { "lv.add.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0 },
111 { "lv.add.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0 },
112 { "lv.adds.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0 },
113 { "lv.adds.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0 },
114 { "lv.addu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0 },
115 { "lv.addu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0 },
116 { "lv.addus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0 },
117 { "lv.addus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0 },
118 { "lv.and", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0 },
119 { "lv.avg.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0 },
120 { "lv.avg.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0 },
121 { "lv.cmp_eq.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0 },
122 { "lv.cmp_eq.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0 },
123 { "lv.cmp_ge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0 },
124 { "lv.cmp_ge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0 },
125 { "lv.cmp_gt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0 },
126 { "lv.cmp_gt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0 },
127 { "lv.cmp_le.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0 },
128 { "lv.cmp_le.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0 },
129 { "lv.cmp_lt.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0 },
130 { "lv.cmp_lt.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0 },
131 { "lv.cmp_ne.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0 },
132 { "lv.cmp_ne.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0 },
133 { "lv.madds.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0 },
134 { "lv.max.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0 },
135 { "lv.max.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0 },
136 { "lv.merge.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0 },
137 { "lv.merge.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0 },
138 { "lv.min.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0 },
139 { "lv.min.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0 },
140 { "lv.msubs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0 },
141 { "lv.muls.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0 },
142 { "lv.nand", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0 },
143 { "lv.nor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0 },
144 { "lv.or", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0 },
145 { "lv.pack.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0 },
146 { "lv.pack.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0 },
147 { "lv.packs.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0 },
148 { "lv.packs.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0 },
149 { "lv.packus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0 },
150 { "lv.packus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0 },
151 { "lv.perm.n", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0 },
152 { "lv.rl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0 },
153 { "lv.rl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0 },
154 { "lv.sll.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0 },
155 { "lv.sll.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0 },
156 { "lv.sll", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0 },
157 { "lv.srl.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0 },
158 { "lv.srl.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0 },
159 { "lv.sra.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0 },
160 { "lv.sra.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0 },
161 { "lv.srl", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0 },
162 { "lv.sub.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0 },
163 { "lv.sub.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0 },
164 { "lv.subs.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0 },
165 { "lv.subs.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0 },
166 { "lv.subu.b", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0 },
167 { "lv.subu.h", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0 },
168 { "lv.subus.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0 },
169 { "lv.subus.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0 },
170 { "lv.unpack.b","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0 },
171 { "lv.unpack.h","rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0 },
172 { "lv.xor", "rD,rA,rB", "00 0xA DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0 },
173 { "lv.cust1", "", "00 0xA ----- ----- ---- ---- 0xC ----", EFI, 0 },
174 { "lv.cust2", "", "00 0xA ----- ----- ---- ---- 0xD ----", EFI, 0 },
175 { "lv.cust3", "", "00 0xA ----- ----- ---- ---- 0xE ----", EFI, 0 },
176 { "lv.cust4", "", "00 0xA ----- ----- ---- ---- 0xF ----", EFI, 0 },
177
178 { "lf.add.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
179 { "lf.sub.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
180 { "lf.mul.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
181 { "lf.div.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
182 { "lf.itof.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
183 { "lf.ftoi.s", "rD,rA", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
184 { "lf.rem.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
185 { "lf.madd.s", "rD,rA,rB", "00 0xB DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
186 { "lf.sfeq.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
187 { "lf.sfne.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
188 { "lf.sfgt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
189 { "lf.sfge.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
190 { "lf.sflt.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
191 { "lf.sfle.s", "rA,rB", "00 0xB ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
192 { "lf.cust1.s", "", "00 0xB ----- ----- ---- ---- 0xE ----", EFI, 0 },
193
194 { "lf.add.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
195 { "lf.sub.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
196 { "lf.mul.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
197 { "lf.div.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
198 { "lf.itof.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
199 { "lf.ftoi.d", "rD,rA", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
200 { "lf.rem.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
201 { "lf.madd.d", "rD,rA,rB", "00 0xC DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
202 { "lf.sfeq.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
203 { "lf.sfne.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
204 { "lf.sfgt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
205 { "lf.sfge.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
206 { "lf.sflt.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
207 { "lf.sfle.d", "rA,rB", "00 0xC ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
208 { "lf.cust1.d", "", "00 0xC ----- ----- ---- ---- 0xE ----", EFI, 0 },
209
210 { "lvf.ld", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x0", EFI, 0 },
211 { "lvf.lw", "rD,0(rA)", "00 0xD DDDDD AAAAA ---- ---- 0x0 0x1", EFI, 0 },
212 { "lvf.sd", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
213 { "lvf.sw", "0(rA),rB", "00 0xD ----- AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
214
215 { "l.jr", "rB", "01 0x1 ----- ----- BBBB B--- ---- ----", EF(l_jr), OR32_IF_DELAY },
216 { "l.jalr", "rB", "01 0x2 ----- ----- BBBB B--- ---- ----", EF(l_jalr), OR32_IF_DELAY },
217 { "l.maci", "rB,I", "01 0x3 IIIII ----- BBBB BIII IIII IIII", EF(l_mac), 0 },
218 { "l.cust1", "", "01 0xC ----- ----- ---- ---- ---- ----", EF(l_cust1), 0 },
219 { "l.cust2", "", "01 0xD ----- ----- ---- ---- ---- ----", EF(l_cust2), 0 },
220 { "l.cust3", "", "01 0xE ----- ----- ---- ---- ---- ----", EF(l_cust3), 0 },
221 { "l.cust4", "", "01 0xF ----- ----- ---- ---- ---- ----", EF(l_cust4), 0 },
222
223 { "l.ld", "rD,I(rA)", "10 0x0 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
224 { "l.lwz", "rD,I(rA)", "10 0x1 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lwz), 0 },
225 { "l.lws", "rD,I(rA)", "10 0x2 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
226 { "l.lbz", "rD,I(rA)", "10 0x3 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbz), 0 },
227 { "l.lbs", "rD,I(rA)", "10 0x4 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbs), 0 },
228 { "l.lhz", "rD,I(rA)", "10 0x5 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhz), 0 },
229 { "l.lhs", "rD,I(rA)", "10 0x6 DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhs), 0 },
230
231 { "l.addi", "rD,rA,I", "10 0x7 DDDDD AAAAA IIII IIII IIII IIII", EF(l_add), 0 },
232 { "l.addic", "rD,rA,I", "10 0x8 DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
233 { "l.andi", "rD,rA,K", "10 0x9 DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_and), 0 },
234 { "l.ori", "rD,rA,K", "10 0xA DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_or), 0 },
235 { "l.xori", "rD,rA,I", "10 0xB DDDDD AAAAA IIII IIII IIII IIII", EF(l_xor), 0 },
236 { "l.muli", "rD,rA,I", "10 0xC DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
237 { "l.mfspr", "rD,rA,K", "10 0xD DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 },
238 { "l.slli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 },
239 { "l.srli", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 },
240 { "l.srai", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 },
241 { "l.rori", "rD,rA,L", "10 0xE DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 },
242
243 { "l.sfeqi", "rA,I", "10 0xF 00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), OR32_W_FLAG },
244 { "l.sfnei", "rA,I", "10 0xF 00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), OR32_W_FLAG },
245 { "l.sfgtui", "rA,I", "10 0xF 00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), OR32_W_FLAG },
246 { "l.sfgeui", "rA,I", "10 0xF 00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), OR32_W_FLAG },
247 { "l.sfltui", "rA,I", "10 0xF 00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), OR32_W_FLAG },
248 { "l.sfleui", "rA,I", "10 0xF 00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), OR32_W_FLAG },
249 { "l.sfgtsi", "rA,I", "10 0xF 01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), OR32_W_FLAG },
250 { "l.sfgesi", "rA,I", "10 0xF 01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), OR32_W_FLAG },
251 { "l.sfltsi", "rA,I", "10 0xF 01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), OR32_W_FLAG },
252 { "l.sflesi", "rA,I", "10 0xF 01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), OR32_W_FLAG },
253
254 { "l.mtspr", "rA,rB,K", "11 0x0 KKKKK AAAAA BBBB BKKK KKKK KKKK", EF(l_mtspr), 0 },
255 { "l.mac", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x1", EF(l_mac), 0 }, /*MM*/
256 { "l.msb", "rA,rB", "11 0x1 ----- AAAAA BBBB B--- ---- 0x2", EF(l_msb), 0 }, /*MM*/
257
258 { "l.sd", "I(rA),rB", "11 0x4 IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 },
259 { "l.sw", "I(rA),rB", "11 0x5 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 },
260 { "l.sb", "I(rA),rB", "11 0x6 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 },
261 { "l.sh", "I(rA),rB", "11 0x7 IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
3b16e843 262
47b0e7ad
NC
263 { "l.add", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x0", EF(l_add), 0 },
264 { "l.addc", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x1", EFI, 0 },
265 { "l.sub", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x2", EF(l_sub), 0 },
266 { "l.and", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x3", EF(l_and), 0 },
267 { "l.or", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
268 { "l.xor", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
269 { "l.mul", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
270
271 { "l.sll", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
272 { "l.srl", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
273 { "l.sra", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
274 { "l.ror", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 },
275 { "l.div", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 },
276 { "l.divu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 },
277 { "l.mulu", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 },
278 { "l.exths", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xC", EFI, 0 },
279 { "l.extbs", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xC", EFI, 0 },
280 { "l.exthz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 10-- 0xC", EFI, 0 },
281 { "l.extbz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 11-- 0xC", EFI, 0 },
282 { "l.extws", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 00-- 0xD", EFI, 0 },
283 { "l.extwz", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 01-- 0xD", EFI, 0 },
284 { "l.cmov", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 },
285 { "l.ff1", "rD,rA,rB", "11 0x8 DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 },
286
287 { "l.sfeq", "rA,rB", "11 0x9 00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), OR32_W_FLAG },
288 { "l.sfne", "rA,rB", "11 0x9 00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), OR32_W_FLAG },
289 { "l.sfgtu", "rA,rB", "11 0x9 00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), OR32_W_FLAG },
290 { "l.sfgeu", "rA,rB", "11 0x9 00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), OR32_W_FLAG },
291 { "l.sfltu", "rA,rB", "11 0x9 00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), OR32_W_FLAG },
292 { "l.sfleu", "rA,rB", "11 0x9 00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), OR32_W_FLAG },
293 { "l.sfgts", "rA,rB", "11 0x9 01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), OR32_W_FLAG },
294 { "l.sfges", "rA,rB", "11 0x9 01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), OR32_W_FLAG },
295 { "l.sflts", "rA,rB", "11 0x9 01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), OR32_W_FLAG },
296 { "l.sfles", "rA,rB", "11 0x9 01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), OR32_W_FLAG },
297
298 { "l.cust5", "", "11 0xC ----- ----- ---- ---- ---- ----", EFI, 0 },
299 { "l.cust6", "", "11 0xD ----- ----- ---- ---- ---- ----", EFI, 0 },
300 { "l.cust7", "", "11 0xE ----- ----- ---- ---- ---- ----", EFI, 0 },
301 { "l.cust8", "", "11 0xF ----- ----- ---- ---- ---- ----", EFI, 0 },
302
303 /* This section should not be defined in or1ksim, since it contains duplicates,
304 which would cause machine builder to complain. */
3b16e843 305#ifdef HAS_CUST
47b0e7ad
NC
306 { "l.cust5_1", "rD", "11 0xC DDDDD ----- ---- ---- ---- ----", EFI, 0 },
307 { "l.cust5_2", "rD,rA" , "11 0xC DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
308 { "l.cust5_3", "rD,rA,rB", "11 0xC DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 309
47b0e7ad
NC
310 { "l.cust6_1", "rD", "11 0xD DDDDD ----- ---- ---- ---- ----", EFI, 0 },
311 { "l.cust6_2", "rD,rA" , "11 0xD DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
312 { "l.cust6_3", "rD,rA,rB", "11 0xD DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 313
47b0e7ad
NC
314 { "l.cust7_1", "rD", "11 0xE DDDDD ----- ---- ---- ---- ----", EFI, 0 },
315 { "l.cust7_2", "rD,rA" , "11 0xE DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
316 { "l.cust7_3", "rD,rA,rB", "11 0xE DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843 317
47b0e7ad
NC
318 { "l.cust8_1", "rD", "11 0xF DDDDD ----- ---- ---- ---- ----", EFI, 0 },
319 { "l.cust8_2", "rD,rA" , "11 0xF DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
320 { "l.cust8_3", "rD,rA,rB", "11 0xF DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
3b16e843
NC
321#endif
322
47b0e7ad
NC
323 /* Dummy entry, not included in num_opcodes. This
324 lets code examine entry i+1 without checking
325 if we've run off the end of the table. */
326 { "", "", "", EFI, 0 }
3b16e843
NC
327};
328
329#undef EFI
330#undef EFN
331#undef EF
332
333/* Define dummy, if debug is not defined. */
334
335#if !defined HAS_DEBUG
0fd3a477 336static void ATTRIBUTE_PRINTF_2
5da8bf1b 337debug (int level ATTRIBUTE_UNUSED, const char *format ATTRIBUTE_UNUSED, ...)
3b16e843 338{
3b16e843
NC
339}
340#endif
341
342const unsigned int or32_num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
343
344/* Calculates instruction length in bytes. Always 4 for OR32. */
345
346int
91d6fa6a 347insn_len (int i_index ATTRIBUTE_UNUSED)
3b16e843
NC
348{
349 return 4;
350}
351
352/* Is individual insn's operand signed or unsigned? */
353
354int
47b0e7ad 355letter_signed (char l)
3b16e843
NC
356{
357 const struct or32_letter *pletter;
358
359 for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
360 if (pletter->letter == l)
361 return pletter->sign;
362
363 printf ("letter_signed(%c): Unknown letter.\n", l);
364 return 0;
365}
366
367/* Number of letters in the individual lettered operand. */
368
369int
47b0e7ad 370letter_range (char l)
3b16e843
NC
371{
372 const struct or32_opcode *pinsn;
373 char *enc;
374 int range = 0;
375
47b0e7ad 376 for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn ++)
3b16e843
NC
377 {
378 if (strchr (pinsn->encoding,l))
379 {
47b0e7ad
NC
380 for (enc = pinsn->encoding; *enc != '\0'; enc ++)
381 if ((*enc == '0') && (*(enc + 1) == 'x'))
3b16e843
NC
382 enc += 2;
383 else if (*enc == l)
384 range++;
385 return range;
386 }
387 }
388
389 printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
390 exit (1);
391}
392
393/* MM: Returns index of given instruction name. */
394
395int
396insn_index (char *insn)
397{
5e37cc46
NC
398 unsigned int i;
399 int found = -1;
3b16e843
NC
400
401 for (i = 0; i < or32_num_opcodes; i++)
402 if (!strcmp (or32_opcodes[i].name, insn))
403 {
404 found = i;
405 break;
406 }
407 return found;
408}
409
410const char *
91d6fa6a 411insn_name (int op_index)
3b16e843 412{
91d6fa6a
NC
413 if (op_index >= 0 && op_index < (int) or32_num_opcodes)
414 return or32_opcodes[op_index].name;
3b16e843
NC
415 else
416 return "???";
417}
418
419void
47b0e7ad 420l_none (void)
3b16e843
NC
421{
422}
423
424/* Finite automata for instruction decoding building code. */
425
426/* Find simbols in encoding. */
47b0e7ad 427
3b16e843 428static unsigned long
47b0e7ad 429insn_extract (char param_ch, char *enc_initial)
3b16e843
NC
430{
431 char *enc;
432 unsigned long ret = 0;
433 unsigned opc_pos = 32;
434
435 for (enc = enc_initial; *enc != '\0'; )
436 if ((*enc == '0') && (*(enc + 1) == 'x'))
437 {
438 unsigned long tmp = strtol (enc+2, NULL, 16);
439
440 opc_pos -= 4;
441 if (param_ch == '0' || param_ch == '1')
442 {
443 if (param_ch == '0')
444 tmp = 15 - tmp;
445 ret |= tmp << opc_pos;
446 }
447 enc += 3;
448 }
449 else
450 {
451 if (*enc == '0' || *enc == '1' || *enc == '-' || ISALPHA (*enc))
452 {
453 opc_pos--;
454 if (param_ch == *enc)
455 ret |= 1 << opc_pos;
456 }
457 enc++;
458 }
459 return ret;
460}
461
47b0e7ad
NC
462#define MAX_AUTOMATA_SIZE 1200
463#define MAX_OP_TABLE_SIZE 1200
464#define LEAF_FLAG 0x80000000
465#define MAX_LEN 8
3b16e843
NC
466
467#ifndef MIN
47b0e7ad 468#define MIN(x, y) ((x) < (y) ? (x) : (y))
3b16e843
NC
469#endif
470
471unsigned long *automata;
472int nuncovered;
473int curpass = 0;
474
475/* MM: Struct that hold runtime build information about instructions. */
476struct temp_insn_struct
477{
478 unsigned long insn;
479 unsigned long insn_mask;
480 int in_pass;
481} *ti;
482
483struct insn_op_struct *op_data, **op_start;
484
485/* Recursive utility function used to find best match and to build automata. */
486
487static unsigned long *
47b0e7ad 488cover_insn (unsigned long * cur, int pass, unsigned int mask)
3b16e843 489{
5e37cc46
NC
490 int best_first = 0, last_match = -1, ninstr = 0;
491 unsigned int best_len = 0;
492 unsigned int i;
3b16e843
NC
493 unsigned long cur_mask = mask;
494 unsigned long *next;
495
496 for (i = 0; i < or32_num_opcodes; i++)
497 if (ti[i].in_pass == pass)
498 {
499 cur_mask &= ti[i].insn_mask;
500 ninstr++;
501 last_match = i;
502 }
503
0fd3a477 504 debug (8, "%08X %08lX\n", mask, cur_mask);
3b16e843
NC
505
506 if (ninstr == 0)
507 return 0;
508
509 if (ninstr == 1)
510 {
511 /* Leaf holds instruction index. */
0fd3a477
JW
512 debug (8, "%li>I%i %s\n",
513 (long)(cur - automata), last_match, or32_opcodes[last_match].name);
3b16e843
NC
514
515 *cur = LEAF_FLAG | last_match;
516 cur++;
517 nuncovered--;
518 }
519 else
520 {
521 /* Find longest match. */
522 for (i = 0; i < 32; i++)
523 {
5e37cc46 524 unsigned int len;
3b16e843
NC
525
526 for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
527 {
47b0e7ad 528 unsigned long m = (1UL << ((unsigned long) len)) - 1;
3b16e843 529
0fd3a477 530 debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)",
3b16e843 531 len,m, cur_mask, i, (cur_mask >> (unsigned)i),
47b0e7ad 532 (cur_mask >> (unsigned) i) & m);
3b16e843 533
47b0e7ad 534 if ((m & (cur_mask >> (unsigned) i)) == m)
3b16e843
NC
535 {
536 best_len = len;
537 best_first = i;
538 debug (9, "!");
539 }
540 else
541 break;
542 }
543 }
544
545 debug (9, "\n");
546
547 if (!best_len)
548 {
549 fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask);
550
551 for (i = 0; i < or32_num_opcodes; i++)
552 if (ti[i].in_pass == pass)
553 fprintf (stderr, "%s ", or32_opcodes[i].name);
554
555 fprintf (stderr, "\n");
556 exit (1);
557 }
558
0fd3a477
JW
559 debug (8, "%li> #### %i << %i (%i) ####\n",
560 (long)(cur - automata), best_len, best_first, ninstr);
3b16e843
NC
561
562 *cur = best_first;
563 cur++;
564 *cur = (1 << best_len) - 1;
565 cur++;
566 next = cur;
567
568 /* Allocate space for pointers. */
569 cur += 1 << best_len;
47b0e7ad 570 cur_mask = (1 << (unsigned long) best_len) - 1;
3b16e843 571
5e37cc46 572 for (i = 0; i < ((unsigned) 1 << best_len); i++)
3b16e843 573 {
5e37cc46 574 unsigned int j;
3b16e843
NC
575 unsigned long *c;
576
577 curpass++;
578 for (j = 0; j < or32_num_opcodes; j++)
579 if (ti[j].in_pass == pass
580 && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i
581 && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
582 ti[j].in_pass = curpass;
583
0fd3a477 584 debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
3b16e843
NC
585 c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
586 if (c)
587 {
0af1713e
AM
588 debug (8, "%li> #%X -> %lu\n", (long)(next - automata), i,
589 (unsigned 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
9ccb8af9 900 printf (" enc=%s, tmp=%lx ", enc, tmp);
3b16e843
NC
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
9ccb8af9 920 printf ("\n ret=%lx opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
3b16e843
NC
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
9ccb8af9 942 printf ("ret=%lx\n", ret);
3b16e843
NC
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);
4ef2cf8b
NC
953 char s_regnum[20];
954
955 sprintf (s_regnum, "r%d", regnum);
956 strcat (disassembled, s_regnum);
3b16e843
NC
957}
958
959/* Print immediate. Used only by print_insn. */
960
961static void
47b0e7ad 962or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
3b16e843
NC
963{
964 int imm = or32_extract (param_ch, encoding, insn);
4ef2cf8b 965 char s_imm[20];
3b16e843
NC
966
967 imm = extend_imm (imm, param_ch);
4ef2cf8b 968
3b16e843
NC
969 if (letter_signed (param_ch))
970 {
971 if (imm < 0)
4ef2cf8b 972 sprintf (s_imm, "%d", imm);
3b16e843 973 else
4ef2cf8b 974 sprintf (s_imm, "0x%x", imm);
3b16e843
NC
975 }
976 else
4ef2cf8b
NC
977 sprintf (s_imm, "%#x", imm);
978 strcat (disassembled, s_imm);
3b16e843
NC
979}
980
981/* Disassemble one instruction from insn to disassemble.
982 Return the size of the instruction. */
983
984int
47b0e7ad 985disassemble_insn (unsigned long insn)
3b16e843 986{
91d6fa6a
NC
987 int op_index;
988 op_index = insn_decode (insn);
3b16e843 989
91d6fa6a 990 if (op_index >= 0)
3b16e843 991 {
91d6fa6a 992 struct or32_opcode const *opcode = &or32_opcodes[op_index];
3b16e843
NC
993 char *s;
994
995 sprintf (disassembled, "%s ", opcode->name);
996 for (s = opcode->args; *s != '\0'; ++s)
997 {
998 switch (*s)
999 {
1000 case '\0':
1001 return 4;
1002
1003 case 'r':
1004 or32_print_register (*++s, opcode->encoding, insn);
1005 break;
1006
1007 default:
1008 if (strchr (opcode->encoding, *s))
1009 or32_print_immediate (*s, opcode->encoding, insn);
1010 else
4ef2cf8b
NC
1011 {
1012 char s_encoding[2] = { *s, '\0' };
1013
1014 strcat (disassembled, s_encoding);
1015 }
1016
3b16e843
NC
1017 }
1018 }
1019 }
1020 else
1021 {
4ef2cf8b
NC
1022 char s_insn[20];
1023
3b16e843 1024 /* This used to be %8x for binutils. */
4ef2cf8b
NC
1025 sprintf (s_insn, ".word 0x%08lx", insn);
1026 strcat (disassembled, s_insn);
3b16e843
NC
1027 }
1028
1029 return insn_len (insn);
1030}
This page took 0.570928 seconds and 4 git commands to generate.