Fix compile time warnings from a GCC 4.0 compiler
[external/binutils.git] / opcodes / or32-opc.c
1 /* Table of opcodes for the OpenRISC 1000 ISA.
2    Copyright 2002, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Damjan Lampret (lampret@opencores.org).
4    
5    This file is part of gen_or1k_isa, or1k, GDB and GAS.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
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
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
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
34 const struct or32_letter or32_letters[] =
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 };
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
70 const struct or32_opcode or32_opcodes[] =
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 },
263     
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.  */
306 #ifdef HAS_CUST
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 },
310
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 },
314
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 },
318
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 },
322 #endif
323
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 }
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
337 static void
338 debug (int level ATTRIBUTE_UNUSED, const char *format ATTRIBUTE_UNUSED, ...)
339 {
340 }
341 #endif
342
343 const 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
347 int
348 insn_len (int insn_index ATTRIBUTE_UNUSED)
349 {
350   return 4;
351 }
352
353 /* Is individual insn's operand signed or unsigned?  */
354
355 int
356 letter_signed (char l)
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
370 int
371 letter_range (char l)
372 {
373   const struct or32_opcode *pinsn;
374   char *enc;
375   int range = 0;
376   
377   for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn ++)
378     {
379       if (strchr (pinsn->encoding,l))
380         {
381           for (enc = pinsn->encoding; *enc != '\0'; enc ++)
382             if ((*enc == '0') && (*(enc + 1) == 'x'))
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
396 int
397 insn_index (char *insn)
398 {
399   unsigned int i;
400   int found = -1;
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
411 const char *
412 insn_name (int index)
413 {
414   if (index >= 0 && index < (int) or32_num_opcodes)
415     return or32_opcodes[index].name;
416   else
417     return "???";
418 }
419
420 void
421 l_none (void)
422 {
423 }
424
425 /* Finite automata for instruction decoding building code.  */
426
427 /* Find simbols in encoding.  */
428
429 static unsigned long
430 insn_extract (char param_ch, char *enc_initial)
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
463 #define MAX_AUTOMATA_SIZE  1200
464 #define MAX_OP_TABLE_SIZE  1200
465 #define LEAF_FLAG          0x80000000
466 #define MAX_LEN            8
467
468 #ifndef MIN
469 #define MIN(x, y)          ((x) < (y) ? (x) : (y))
470 #endif
471
472 unsigned long *automata;
473 int nuncovered;
474 int curpass = 0;
475
476 /* MM: Struct that hold runtime build information about instructions.  */
477 struct temp_insn_struct
478 {
479   unsigned long insn;
480   unsigned long insn_mask;
481   int in_pass;
482 } *ti;
483
484 struct insn_op_struct *op_data, **op_start;
485
486 /* Recursive utility function used to find best match and to build automata.  */
487
488 static unsigned long *
489 cover_insn (unsigned long * cur, int pass, unsigned int mask)
490 {
491   int best_first = 0, last_match = -1, ninstr = 0;
492   unsigned int best_len = 0;
493   unsigned int i;
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   
505   debug (8, "%08X %08X\n", mask, cur_mask);
506
507   if (ninstr == 0)
508     return 0;
509
510   if (ninstr == 1)
511     {
512       /* Leaf holds instruction index.  */
513       debug (8, "%i>I%i %s\n",
514              cur - automata, last_match, or32_opcodes[last_match].name);
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         {
525           unsigned int len;
526
527           for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
528             {
529               unsigned long m = (1UL << ((unsigned long) len)) - 1;
530
531               debug (9, " (%i(%08X & %08X>>%i = %08X, %08X)",
532                      len,m, cur_mask, i, (cur_mask >> (unsigned)i),
533                      (cur_mask >> (unsigned) i) & m);
534
535               if ((m & (cur_mask >> (unsigned) i)) == m)
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
560       debug (8, "%i> #### %i << %i (%i) ####\n",
561              cur - automata, best_len, best_first, ninstr);
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;
571       cur_mask = (1 << (unsigned long) best_len) - 1;
572       
573       for (i = 0; i < ((unsigned) 1 << best_len); i++)
574         {
575           unsigned int j;
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
585           debug (9, "%08X %08X %i\n", mask, cur_mask, best_first);
586           c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
587           if (c)
588             {
589               debug (8, "%i> #%X -> %u\n", next - automata, i, cur - automata);
590               *next = cur - automata;
591               cur = c;   
592             }
593           else 
594             {
595               debug (8, "%i> N/A\n", next - automata);
596               *next = 0;
597             }
598           next++;
599         }
600     }
601   return cur;
602 }
603
604 /* Returns number of nonzero bits.  */
605
606 static int
607 num_ones (unsigned long value)
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
620 /* Utility function, which converts parameters from or32_opcode
621    format to more binary form.  Parameters are stored in ti struct.  */
622
623 static struct insn_op_struct *
624 parse_params (const struct or32_opcode * opcode,
625               struct insn_op_struct * cur)
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;
638       debug (9, "#%08X %08X\n", cur->type, cur->data);
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);
655           debug (9, "%s : %08X ------\n", opcode->name, arg);
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);
681               debug (6, "|%08X %08X\n", cur->type, cur->data);
682               cur++;
683             }
684           args++;
685         }
686       else if (*args == '(')
687         {
688           /* Next param is displacement.
689              Later we will treat them as one operand.  */
690           cur--;
691           cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
692           debug (9, ">%08X %08X\n", cur->type, cur->data);
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;
702           debug (9, ">%08X %08X\n", cur->type, cur->data);
703           cur++;
704           type = 0;
705           i++;
706           args++;
707         }
708       else if (*args == '0')
709         {
710           cur->type = type;
711           cur->data = 0;
712           debug (9, ">%08X %08X\n", cur->type, cur->data);
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;
729   debug (9, "#%08X %08X\n", cur->type, cur->data);
730   cur++;
731
732   return cur;
733 }
734
735 /* Constructs new automata based on or32_opcodes array.  */
736
737 void
738 build_automata (void)
739 {
740   unsigned int i;
741   unsigned long *end;
742   struct insn_op_struct *cur;
743   
744   automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
745   ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes);
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
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 *));
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
796 void
797 destruct_automata (void)
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
807 int
808 insn_decode (unsigned int insn)
809 {
810   unsigned long *a = automata;
811   int i;
812
813   while (!(*a & LEAF_FLAG))
814     {
815       unsigned int first = *a;
816
817       debug (9, "%i ", a - automata);
818
819       a++;
820       i = (insn >> first) & *a;
821       a++;
822       if (!*(a + i))
823         {
824           /* Invalid instruction found?  */
825           debug (9, "XXX\n", i);
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
844 static char disassembled_str[50];
845 char *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    
851 static unsigned long
852 extend_imm (unsigned long imm, char l)
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
870 static unsigned long
871 or32_extract (char param_ch, char *enc_initial, unsigned long insn)
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
949 static void
950 or32_print_register (char param_ch, char *encoding, unsigned long insn)
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
959 static void
960 or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
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
980 int
981 disassemble_insn (unsigned long insn)
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 }