OSDN Git Service

* arm-dis.c (print_insn_arm): Revert previous, undocumented,
[pf3gnuchains/pf3gnuchains4x.git] / opcodes / or32-opc.c
1 /* Table of opcodes for the OpenRISC 1000 ISA.
2    Copyright 2002, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
3    Contributed by Damjan Lampret (lampret@opencores.org).
4    
5    This file is part of the GNU opcodes library.
6
7    This library 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 3, or (at your option)
10    any later version.
11
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.
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 ATTRIBUTE_PRINTF_2
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 i_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 op_index)
413 {
414   if (op_index >= 0 && op_index < (int) or32_num_opcodes)
415     return or32_opcodes[op_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 %08lX\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, "%li>I%i %s\n",
514              (long)(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(%08lX & %08lX>>%i = %08lX, %08lX)",
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, "%li> #### %i << %i (%i) ####\n",
561              (long)(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 %08lX %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, "%li> #%X -> %lu\n", (long)(next - automata), i,
590                      (unsigned long)(cur - automata));
591               *next = cur - automata;
592               cur = c;   
593             }
594           else 
595             {
596               debug (8, "%li> N/A\n", (long)(next - automata));
597               *next = 0;
598             }
599           next++;
600         }
601     }
602   return cur;
603 }
604
605 /* Returns number of nonzero bits.  */
606
607 static int
608 num_ones (unsigned long value)
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
621 /* Utility function, which converts parameters from or32_opcode
622    format to more binary form.  Parameters are stored in ti struct.  */
623
624 static struct insn_op_struct *
625 parse_params (const struct or32_opcode * opcode,
626               struct insn_op_struct * cur)
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;
639       debug (9, "#%08lX %08lX\n", cur->type, cur->data);
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);
656           debug (9, "%s : %08lX ------\n", opcode->name, arg);
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);
682               debug (6, "|%08lX %08lX\n", cur->type, cur->data);
683               cur++;
684             }
685           args++;
686         }
687       else if (*args == '(')
688         {
689           /* Next param is displacement.
690              Later we will treat them as one operand.  */
691           cur--;
692           cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
693           debug (9, ">%08lX %08lX\n", cur->type, cur->data);
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;
703           debug (9, ">%08lX %08lX\n", cur->type, cur->data);
704           cur++;
705           type = 0;
706           i++;
707           args++;
708         }
709       else if (*args == '0')
710         {
711           cur->type = type;
712           cur->data = 0;
713           debug (9, ">%08lX %08lX\n", cur->type, cur->data);
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;
730   debug (9, "#%08lX %08lX\n", cur->type, cur->data);
731   cur++;
732
733   return cur;
734 }
735
736 /* Constructs new automata based on or32_opcodes array.  */
737
738 void
739 build_automata (void)
740 {
741   unsigned int i;
742   unsigned long *end;
743   struct insn_op_struct *cur;
744   
745   automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
746   ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes);
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
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 *));
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
797 void
798 destruct_automata (void)
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
808 int
809 insn_decode (unsigned int insn)
810 {
811   unsigned long *a = automata;
812   int i;
813
814   while (!(*a & LEAF_FLAG))
815     {
816       unsigned int first = *a;
817
818       debug (9, "%li ", (long)(a - automata));
819
820       a++;
821       i = (insn >> first) & *a;
822       a++;
823       if (!*(a + i))
824         {
825           /* Invalid instruction found?  */
826           debug (9, "XXX\n");
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
845 static char disassembled_str[50];
846 char *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    
852 static unsigned long
853 extend_imm (unsigned long imm, char l)
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
871 static unsigned long
872 or32_extract (char param_ch, char *enc_initial, unsigned long insn)
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=%lx ", 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=%lx 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=%lx\n", ret);
944 #endif
945   return ret;
946 }
947
948 /* Print register. Used only by print_insn.  */
949
950 static void
951 or32_print_register (char param_ch, char *encoding, unsigned long insn)
952 {
953   int regnum = or32_extract(param_ch, encoding, insn);
954   char s_regnum[20];
955
956   sprintf (s_regnum, "r%d", regnum);
957   strcat (disassembled, s_regnum);
958 }
959
960 /* Print immediate. Used only by print_insn.  */
961
962 static void
963 or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
964 {
965   int imm = or32_extract (param_ch, encoding, insn);
966   char s_imm[20];
967
968   imm = extend_imm (imm, param_ch);
969
970   if (letter_signed (param_ch))
971     {
972       if (imm < 0)
973         sprintf (s_imm, "%d", imm);
974       else
975         sprintf (s_imm, "0x%x", imm);
976     }
977   else
978     sprintf (s_imm, "%#x", imm);
979   strcat (disassembled, s_imm);
980 }
981
982 /* Disassemble one instruction from insn to disassemble.
983    Return the size of the instruction.  */
984
985 int
986 disassemble_insn (unsigned long insn)
987 {
988   int op_index;
989   op_index = insn_decode (insn);
990
991   if (op_index >= 0)
992     {
993       struct or32_opcode const *opcode = &or32_opcodes[op_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
1012                 {
1013                   char s_encoding[2] = { *s, '\0' };
1014
1015                   strcat (disassembled, s_encoding);
1016                 }
1017
1018             }
1019         }
1020     }
1021   else
1022     {
1023       char s_insn[20];
1024
1025       /* This used to be %8x for binutils.  */
1026       sprintf (s_insn, ".word 0x%08lx", insn);
1027       strcat (disassembled, s_insn);
1028     }
1029
1030   return insn_len (insn);
1031 }