Back to index

cell-binutils  2.17cvs20070401
or32-opc.c
Go to the documentation of this file.
00001 /* Table of opcodes for the OpenRISC 1000 ISA.
00002    Copyright 2002, 2004, 2005 Free Software Foundation, Inc.
00003    Contributed by Damjan Lampret (lampret@opencores.org).
00004    
00005    This file is part of gen_or1k_isa, or1k, GDB and GAS.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00020    MA 02110-1301, USA.  */
00021 
00022 /* We treat all letters the same in encode/decode routines so
00023    we need to assign some characteristics to them like signess etc.  */
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include "safe-ctype.h"
00028 #include "ansidecl.h"
00029 #ifdef HAVE_CONFIG_H
00030 # include "config.h"
00031 #endif
00032 #include "opcode/or32.h"
00033 
00034 const struct or32_letter or32_letters[] =
00035 {
00036   { 'A', NUM_UNSIGNED },
00037   { 'B', NUM_UNSIGNED },
00038   { 'D', NUM_UNSIGNED },
00039   { 'I', NUM_SIGNED },
00040   { 'K', NUM_UNSIGNED },
00041   { 'L', NUM_UNSIGNED },
00042   { 'N', NUM_SIGNED },
00043   { '0', NUM_UNSIGNED },
00044   { '\0', 0 }     /* Dummy entry.  */
00045 };
00046 
00047 /* Opcode encoding:
00048    machine[31:30]: first two bits of opcode
00049                  00 - neither of source operands is GPR
00050                  01 - second source operand is GPR (rB)
00051                  10 - first source operand is GPR (rA)
00052                  11 - both source operands are GPRs (rA and rB)
00053    machine[29:26]: next four bits of opcode
00054    machine[25:00]: instruction operands (specific to individual instruction)
00055 
00056   Recommendation: irrelevant instruction bits should be set with a value of
00057   bits in same positions of instruction preceding current instruction in the
00058   code (when assembling).  */
00059 
00060 #define EFN &l_none
00061 
00062 #ifdef HAS_EXECUTION
00063 #define EF(func) &(func)
00064 #define EFI &l_invalid
00065 #else  /* HAS_EXECUTION */
00066 #define EF(func) EFN
00067 #define EFI EFN
00068 #endif /* HAS_EXECUTION */
00069 
00070 const struct or32_opcode or32_opcodes[] =
00071 {
00072   { "l.j",       "N",            "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY },
00073   { "l.jal",     "N",            "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY },
00074   { "l.bnf",     "N",            "00 0x3  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG},
00075   { "l.bf",      "N",            "00 0x4  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG },
00076   { "l.nop",     "K",            "00 0x5  01--- ----- KKKK KKKK KKKK KKKK", EF(l_nop), 0 },
00077   { "l.movhi",   "rD,K",         "00 0x6  DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/
00078   { "l.macrc",   "rD",           "00 0x6  DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/
00079 
00080   { "l.sys",     "K",            "00 0x8  00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 },
00081   { "l.trap",    "K",            "00 0x8  01000 00000 KKKK KKKK KKKK KKKK", EF(l_trap), 0 }, /* CZ 21/06/01 */
00082   { "l.msync",   "",             "00 0x8  10000 00000 0000 0000 0000 0000", EFN, 0 },
00083   { "l.psync",   "",             "00 0x8  10100 00000 0000 0000 0000 0000", EFN, 0 },
00084   { "l.csync",   "",             "00 0x8  11000 00000 0000 0000 0000 0000", EFN, 0 },
00085   { "l.rfe",     "",             "00 0x9  ----- ----- ---- ---- ---- ----", EF(l_rfe), OR32_IF_DELAY },
00086 
00087   { "lv.all_eq.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
00088   { "lv.all_eq.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
00089   { "lv.all_ge.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
00090   { "lv.all_ge.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
00091   { "lv.all_gt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
00092   { "lv.all_gt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
00093   { "lv.all_le.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
00094   { "lv.all_le.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
00095   { "lv.all_lt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
00096   { "lv.all_lt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
00097   { "lv.all_ne.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
00098   { "lv.all_ne.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
00099   { "lv.any_eq.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x0", EFI, 0 },
00100   { "lv.any_eq.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x1", EFI, 0 },
00101   { "lv.any_ge.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x2", EFI, 0 },
00102   { "lv.any_ge.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x3", EFI, 0 },
00103   { "lv.any_gt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x4", EFI, 0 },
00104   { "lv.any_gt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x5", EFI, 0 },
00105   { "lv.any_le.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x6", EFI, 0 },
00106   { "lv.any_le.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x7", EFI, 0 },
00107   { "lv.any_lt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x8", EFI, 0 },
00108   { "lv.any_lt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0x9", EFI, 0 },
00109   { "lv.any_ne.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0xA", EFI, 0 },
00110   { "lv.any_ne.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x2 0xB", EFI, 0 },
00111   { "lv.add.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x0", EFI, 0 },
00112   { "lv.add.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x1", EFI, 0 },
00113   { "lv.adds.b", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x2", EFI, 0 },
00114   { "lv.adds.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x3", EFI, 0 },
00115   { "lv.addu.b", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x4", EFI, 0 },
00116   { "lv.addu.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x5", EFI, 0 },
00117   { "lv.addus.b","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x6", EFI, 0 },
00118   { "lv.addus.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x7", EFI, 0 },
00119   { "lv.and",    "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x8", EFI, 0 },
00120   { "lv.avg.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0x9", EFI, 0 },
00121   { "lv.avg.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x3 0xA", EFI, 0 },
00122   { "lv.cmp_eq.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x0", EFI, 0 },
00123   { "lv.cmp_eq.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x1", EFI, 0 },
00124   { "lv.cmp_ge.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x2", EFI, 0 },
00125   { "lv.cmp_ge.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x3", EFI, 0 },
00126   { "lv.cmp_gt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x4", EFI, 0 },
00127   { "lv.cmp_gt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x5", EFI, 0 },
00128   { "lv.cmp_le.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x6", EFI, 0 },
00129   { "lv.cmp_le.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x7", EFI, 0 },
00130   { "lv.cmp_lt.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x8", EFI, 0 },
00131   { "lv.cmp_lt.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0x9", EFI, 0 },
00132   { "lv.cmp_ne.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0xA", EFI, 0 },
00133   { "lv.cmp_ne.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x4 0xB", EFI, 0 },
00134   { "lv.madds.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x4", EFI, 0 },
00135   { "lv.max.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x5", EFI, 0 },
00136   { "lv.max.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x6", EFI, 0 },
00137   { "lv.merge.b","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x7", EFI, 0 },
00138   { "lv.merge.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x8", EFI, 0 },
00139   { "lv.min.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0x9", EFI, 0 },
00140   { "lv.min.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xA", EFI, 0 },
00141   { "lv.msubs.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xB", EFI, 0 },
00142   { "lv.muls.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xC", EFI, 0 },
00143   { "lv.nand",   "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xD", EFI, 0 },
00144   { "lv.nor",    "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xE", EFI, 0 },
00145   { "lv.or",     "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x5 0xF", EFI, 0 },
00146   { "lv.pack.b", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x0", EFI, 0 },
00147   { "lv.pack.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x1", EFI, 0 },
00148   { "lv.packs.b","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x2", EFI, 0 },
00149   { "lv.packs.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x3", EFI, 0 },
00150   { "lv.packus.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x4", EFI, 0 },
00151   { "lv.packus.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x5", EFI, 0 },
00152   { "lv.perm.n", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x6", EFI, 0 },
00153   { "lv.rl.b",   "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x7", EFI, 0 },
00154   { "lv.rl.h",   "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x8", EFI, 0 },
00155   { "lv.sll.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0x9", EFI, 0 },
00156   { "lv.sll.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xA", EFI, 0 },
00157   { "lv.sll",    "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xB", EFI, 0 },
00158   { "lv.srl.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xC", EFI, 0 },
00159   { "lv.srl.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xD", EFI, 0 },
00160   { "lv.sra.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xE", EFI, 0 },
00161   { "lv.sra.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x6 0xF", EFI, 0 },
00162   { "lv.srl",    "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x0", EFI, 0 },
00163   { "lv.sub.b",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x1", EFI, 0 },
00164   { "lv.sub.h",  "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x2", EFI, 0 },
00165   { "lv.subs.b", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x3", EFI, 0 },
00166   { "lv.subs.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x4", EFI, 0 },
00167   { "lv.subu.b", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x5", EFI, 0 },
00168   { "lv.subu.h", "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x6", EFI, 0 },
00169   { "lv.subus.b","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x7", EFI, 0 },
00170   { "lv.subus.h","rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x8", EFI, 0 },
00171   { "lv.unpack.b","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0x9", EFI, 0 },
00172   { "lv.unpack.h","rD,rA,rB",    "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0xA", EFI, 0 },
00173   { "lv.xor",    "rD,rA,rB",     "00 0xA  DDDDD AAAAA BBBB B--- 0x7 0xB", EFI, 0 },
00174   { "lv.cust1",  "",        "00 0xA  ----- ----- ---- ---- 0xC ----", EFI, 0 },
00175   { "lv.cust2",  "",        "00 0xA  ----- ----- ---- ---- 0xD ----", EFI, 0 },
00176   { "lv.cust3",  "",        "00 0xA  ----- ----- ---- ---- 0xE ----", EFI, 0 },
00177   { "lv.cust4",  "",        "00 0xA  ----- ----- ---- ---- 0xF ----", EFI, 0 },
00178   
00179   { "lf.add.s",   "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
00180   { "lf.sub.s",   "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
00181   { "lf.mul.s",   "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
00182   { "lf.div.s",   "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
00183   { "lf.itof.s",  "rD,rA",       "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
00184   { "lf.ftoi.s",  "rD,rA",       "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
00185   { "lf.rem.s",   "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
00186   { "lf.madd.s",  "rD,rA,rB",    "00 0xB  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
00187   { "lf.sfeq.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
00188   { "lf.sfne.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
00189   { "lf.sfgt.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
00190   { "lf.sfge.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
00191   { "lf.sflt.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
00192   { "lf.sfle.s",  "rA,rB",       "00 0xB  ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
00193   { "lf.cust1.s", "",              "00 0xB  ----- ----- ---- ---- 0xE ----", EFI, 0 },
00194 
00195   { "lf.add.d",   "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
00196   { "lf.sub.d",   "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
00197   { "lf.mul.d",   "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x2", EFI, 0 },
00198   { "lf.div.d",   "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x3", EFI, 0 },
00199   { "lf.itof.d",  "rD,rA",       "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x4", EFI, 0 },
00200   { "lf.ftoi.d",  "rD,rA",       "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x5", EFI, 0 },
00201   { "lf.rem.d",   "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x6", EFI, 0 },
00202   { "lf.madd.d",  "rD,rA,rB",    "00 0xC  DDDDD AAAAA BBBB B--- 0x1 0x7", EFI, 0 },
00203   { "lf.sfeq.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0x8", EFI, 0 },
00204   { "lf.sfne.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0x9", EFI, 0 },
00205   { "lf.sfgt.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0xA", EFI, 0 },
00206   { "lf.sfge.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0xB", EFI, 0 },
00207   { "lf.sflt.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0xC", EFI, 0 },
00208   { "lf.sfle.d",  "rA,rB",       "00 0xC  ----- AAAAA BBBB B--- 0x1 0xD", EFI, 0 },
00209   { "lf.cust1.d", "",              "00 0xC  ----- ----- ---- ---- 0xE ----", EFI, 0 },
00210 
00211   { "lvf.ld",     "rD,0(rA)",    "00 0xD  DDDDD AAAAA ---- ---- 0x0 0x0", EFI, 0 },
00212   { "lvf.lw",     "rD,0(rA)",    "00 0xD  DDDDD AAAAA ---- ---- 0x0 0x1", EFI, 0 },
00213   { "lvf.sd",     "0(rA),rB",    "00 0xD  ----- AAAAA BBBB B--- 0x1 0x0", EFI, 0 },
00214   { "lvf.sw",     "0(rA),rB",    "00 0xD  ----- AAAAA BBBB B--- 0x1 0x1", EFI, 0 },
00215 
00216   { "l.jr",      "rB",           "01 0x1  ----- ----- BBBB B--- ---- ----", EF(l_jr), OR32_IF_DELAY },
00217   { "l.jalr",    "rB",           "01 0x2  ----- ----- BBBB B--- ---- ----", EF(l_jalr), OR32_IF_DELAY },
00218   { "l.maci",    "rB,I",         "01 0x3  IIIII ----- BBBB BIII IIII IIII", EF(l_mac), 0 },
00219   { "l.cust1",   "",        "01 0xC  ----- ----- ---- ---- ---- ----", EF(l_cust1), 0 },
00220   { "l.cust2",   "",        "01 0xD  ----- ----- ---- ---- ---- ----", EF(l_cust2), 0 },
00221   { "l.cust3",   "",        "01 0xE  ----- ----- ---- ---- ---- ----", EF(l_cust3), 0 },
00222   { "l.cust4",   "",        "01 0xF  ----- ----- ---- ---- ---- ----", EF(l_cust4), 0 },
00223 
00224   { "l.ld",      "rD,I(rA)",     "10 0x0  DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
00225   { "l.lwz",     "rD,I(rA)",     "10 0x1  DDDDD AAAAA IIII IIII IIII IIII", EF(l_lwz), 0 },
00226   { "l.lws",     "rD,I(rA)",     "10 0x2  DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
00227   { "l.lbz",     "rD,I(rA)",     "10 0x3  DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbz), 0 },
00228   { "l.lbs",     "rD,I(rA)",     "10 0x4  DDDDD AAAAA IIII IIII IIII IIII", EF(l_lbs), 0 },
00229   { "l.lhz",     "rD,I(rA)",     "10 0x5  DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhz), 0 },
00230   { "l.lhs",     "rD,I(rA)",     "10 0x6  DDDDD AAAAA IIII IIII IIII IIII", EF(l_lhs), 0 },
00231 
00232   { "l.addi",    "rD,rA,I",      "10 0x7  DDDDD AAAAA IIII IIII IIII IIII", EF(l_add), 0 },
00233   { "l.addic",   "rD,rA,I",      "10 0x8  DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
00234   { "l.andi",    "rD,rA,K",      "10 0x9  DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_and), 0 },
00235   { "l.ori",     "rD,rA,K",      "10 0xA  DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_or), 0  },
00236   { "l.xori",    "rD,rA,I",      "10 0xB  DDDDD AAAAA IIII IIII IIII IIII", EF(l_xor), 0 },
00237   { "l.muli",    "rD,rA,I",      "10 0xC  DDDDD AAAAA IIII IIII IIII IIII", EFI, 0 },
00238   { "l.mfspr",   "rD,rA,K",      "10 0xD  DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 },
00239   { "l.slli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 },
00240   { "l.srli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 },
00241   { "l.srai",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 },
00242   { "l.rori",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 },
00243 
00244   { "l.sfeqi",   "rA,I",         "10 0xF  00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), OR32_W_FLAG },
00245   { "l.sfnei",   "rA,I",         "10 0xF  00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), OR32_W_FLAG },
00246   { "l.sfgtui",  "rA,I",         "10 0xF  00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), OR32_W_FLAG },
00247   { "l.sfgeui",  "rA,I",         "10 0xF  00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), OR32_W_FLAG },
00248   { "l.sfltui",  "rA,I",         "10 0xF  00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), OR32_W_FLAG },
00249   { "l.sfleui",  "rA,I",         "10 0xF  00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), OR32_W_FLAG },
00250   { "l.sfgtsi",  "rA,I",         "10 0xF  01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), OR32_W_FLAG },
00251   { "l.sfgesi",  "rA,I",         "10 0xF  01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), OR32_W_FLAG },
00252   { "l.sfltsi",  "rA,I",         "10 0xF  01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), OR32_W_FLAG },
00253   { "l.sflesi",  "rA,I",         "10 0xF  01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), OR32_W_FLAG },
00254 
00255   { "l.mtspr",   "rA,rB,K",      "11 0x0  KKKKK AAAAA BBBB BKKK KKKK KKKK", EF(l_mtspr), 0 },
00256   { "l.mac",     "rA,rB",        "11 0x1  ----- AAAAA BBBB B--- ---- 0x1", EF(l_mac), 0 }, /*MM*/
00257   { "l.msb",     "rA,rB",        "11 0x1  ----- AAAAA BBBB B--- ---- 0x2", EF(l_msb), 0 }, /*MM*/
00258 
00259   { "l.sd",      "I(rA),rB",     "11 0x4  IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 },
00260   { "l.sw",      "I(rA),rB",     "11 0x5  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 },
00261   { "l.sb",      "I(rA),rB",     "11 0x6  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 },
00262   { "l.sh",      "I(rA),rB",     "11 0x7  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
00263     
00264   { "l.add",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x0", EF(l_add), 0 },
00265   { "l.addc",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x1", EFI, 0 },
00266   { "l.sub",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x2", EF(l_sub), 0 },
00267   { "l.and",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x3", EF(l_and), 0 },
00268   { "l.or",      "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x4", EF(l_or), 0 },
00269   { "l.xor",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x5", EF(l_xor), 0 },
00270   { "l.mul",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0x6", EF(l_mul), 0 },
00271 
00272   { "l.sll",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0x8", EF(l_sll), 0 },
00273   { "l.srl",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0x8", EF(l_srl), 0 },
00274   { "l.sra",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
00275   { "l.ror",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 },
00276   { "l.div",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 },
00277   { "l.divu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 },
00278   { "l.mulu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 },
00279   { "l.exths",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0xC", EFI, 0 },
00280   { "l.extbs",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0xC", EFI, 0 },
00281   { "l.exthz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0xC", EFI, 0 },
00282   { "l.extbz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0xC", EFI, 0 },
00283   { "l.extws",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0xD", EFI, 0 },
00284   { "l.extwz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0xD", EFI, 0 },
00285   { "l.cmov",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 },
00286   { "l.ff1",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 },
00287 
00288   { "l.sfeq",    "rA,rB",        "11 0x9  00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), OR32_W_FLAG },
00289   { "l.sfne",    "rA,rB",        "11 0x9  00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), OR32_W_FLAG },
00290   { "l.sfgtu",   "rA,rB",        "11 0x9  00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), OR32_W_FLAG },
00291   { "l.sfgeu",   "rA,rB",        "11 0x9  00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), OR32_W_FLAG },
00292   { "l.sfltu",   "rA,rB",        "11 0x9  00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), OR32_W_FLAG },
00293   { "l.sfleu",   "rA,rB",        "11 0x9  00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), OR32_W_FLAG },
00294   { "l.sfgts",   "rA,rB",        "11 0x9  01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), OR32_W_FLAG },
00295   { "l.sfges",   "rA,rB",        "11 0x9  01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), OR32_W_FLAG },
00296   { "l.sflts",   "rA,rB",        "11 0x9  01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), OR32_W_FLAG },
00297   { "l.sfles",   "rA,rB",        "11 0x9  01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), OR32_W_FLAG },
00298 
00299   { "l.cust5",   "",        "11 0xC  ----- ----- ---- ---- ---- ----", EFI, 0 },
00300   { "l.cust6",   "",        "11 0xD  ----- ----- ---- ---- ---- ----", EFI, 0 },
00301   { "l.cust7",   "",        "11 0xE  ----- ----- ---- ---- ---- ----", EFI, 0 },
00302   { "l.cust8",   "",        "11 0xF  ----- ----- ---- ---- ---- ----", EFI, 0 },
00303 
00304   /* This section should not be defined in or1ksim, since it contains duplicates,
00305      which would cause machine builder to complain.  */
00306 #ifdef HAS_CUST
00307   { "l.cust5_1",   "rD",           "11 0xC  DDDDD ----- ---- ---- ---- ----", EFI, 0 },
00308   { "l.cust5_2",   "rD,rA"   ,   "11 0xC  DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
00309   { "l.cust5_3",   "rD,rA,rB",   "11 0xC  DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
00310 
00311   { "l.cust6_1",   "rD",           "11 0xD  DDDDD ----- ---- ---- ---- ----", EFI, 0 },
00312   { "l.cust6_2",   "rD,rA"   ,   "11 0xD  DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
00313   { "l.cust6_3",   "rD,rA,rB",   "11 0xD  DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
00314 
00315   { "l.cust7_1",   "rD",           "11 0xE  DDDDD ----- ---- ---- ---- ----", EFI, 0 },
00316   { "l.cust7_2",   "rD,rA"   ,   "11 0xE  DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
00317   { "l.cust7_3",   "rD,rA,rB",   "11 0xE  DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
00318 
00319   { "l.cust8_1",   "rD",           "11 0xF  DDDDD ----- ---- ---- ---- ----", EFI, 0 },
00320   { "l.cust8_2",   "rD,rA"   ,   "11 0xF  DDDDD AAAAA ---- ---- ---- ----", EFI, 0 },
00321   { "l.cust8_3",   "rD,rA,rB",   "11 0xF  DDDDD AAAAA BBBB B--- ---- ----", EFI, 0 },
00322 #endif
00323 
00324   /* Dummy entry, not included in num_opcodes.  This
00325      lets code examine entry i+1 without checking
00326      if we've run off the end of the table.  */
00327   { "", "", "", EFI, 0 }
00328 };
00329 
00330 #undef EFI
00331 #undef EFN
00332 #undef EF 
00333 
00334 /* Define dummy, if debug is not defined.  */
00335 
00336 #if !defined HAS_DEBUG
00337 static void ATTRIBUTE_PRINTF_2
00338 debug (int level ATTRIBUTE_UNUSED, const char *format ATTRIBUTE_UNUSED, ...)
00339 {
00340 }
00341 #endif
00342 
00343 const unsigned int or32_num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
00344 
00345 /* Calculates instruction length in bytes. Always 4 for OR32.  */
00346 
00347 int
00348 insn_len (int insn_index ATTRIBUTE_UNUSED)
00349 {
00350   return 4;
00351 }
00352 
00353 /* Is individual insn's operand signed or unsigned?  */
00354 
00355 int
00356 letter_signed (char l)
00357 {
00358   const struct or32_letter *pletter;
00359   
00360   for (pletter = or32_letters; pletter->letter != '\0'; pletter++)
00361     if (pletter->letter == l)
00362       return pletter->sign;
00363   
00364   printf ("letter_signed(%c): Unknown letter.\n", l);
00365   return 0;
00366 }
00367 
00368 /* Number of letters in the individual lettered operand.  */
00369 
00370 int
00371 letter_range (char l)
00372 {
00373   const struct or32_opcode *pinsn;
00374   char *enc;
00375   int range = 0;
00376   
00377   for (pinsn = or32_opcodes; strlen (pinsn->name); pinsn ++)
00378     {
00379       if (strchr (pinsn->encoding,l))
00380        {
00381          for (enc = pinsn->encoding; *enc != '\0'; enc ++)
00382            if ((*enc == '0') && (*(enc + 1) == 'x'))
00383              enc += 2;
00384            else if (*enc == l)
00385              range++;
00386          return range;
00387        }
00388     }
00389 
00390   printf ("\nABORT: letter_range(%c): Never used letter.\n", l);
00391   exit (1);
00392 }
00393 
00394 /* MM: Returns index of given instruction name.  */
00395 
00396 int
00397 insn_index (char *insn)
00398 {
00399   unsigned int i;
00400   int found = -1;
00401 
00402   for (i = 0; i < or32_num_opcodes; i++)
00403     if (!strcmp (or32_opcodes[i].name, insn))
00404       {
00405        found = i;
00406        break;
00407       }
00408   return found;
00409 }
00410 
00411 const char *
00412 insn_name (int index)
00413 {
00414   if (index >= 0 && index < (int) or32_num_opcodes)
00415     return or32_opcodes[index].name;
00416   else
00417     return "???";
00418 }
00419 
00420 void
00421 l_none (void)
00422 {
00423 }
00424 
00425 /* Finite automata for instruction decoding building code.  */
00426 
00427 /* Find simbols in encoding.  */
00428 
00429 static unsigned long
00430 insn_extract (char param_ch, char *enc_initial)
00431 {
00432   char *enc;
00433   unsigned long ret = 0;
00434   unsigned opc_pos = 32;
00435 
00436   for (enc = enc_initial; *enc != '\0'; )
00437     if ((*enc == '0') && (*(enc + 1) == 'x')) 
00438       {
00439        unsigned long tmp = strtol (enc+2, NULL, 16);
00440 
00441         opc_pos -= 4;
00442        if (param_ch == '0' || param_ch == '1')
00443          {
00444            if (param_ch == '0')
00445              tmp = 15 - tmp;
00446            ret |= tmp << opc_pos;
00447          }
00448         enc += 3;
00449       }
00450     else
00451       {
00452        if (*enc == '0' || *enc == '1' || *enc == '-' || ISALPHA (*enc))
00453          {
00454            opc_pos--;
00455            if (param_ch == *enc)
00456              ret |= 1 << opc_pos;
00457          }
00458        enc++;
00459       }
00460   return ret;
00461 }
00462 
00463 #define MAX_AUTOMATA_SIZE  1200
00464 #define MAX_OP_TABLE_SIZE  1200
00465 #define LEAF_FLAG          0x80000000
00466 #define MAX_LEN            8
00467 
00468 #ifndef MIN
00469 #define MIN(x, y)          ((x) < (y) ? (x) : (y))
00470 #endif
00471 
00472 unsigned long *automata;
00473 int nuncovered;
00474 int curpass = 0;
00475 
00476 /* MM: Struct that hold runtime build information about instructions.  */
00477 struct temp_insn_struct
00478 {
00479   unsigned long insn;
00480   unsigned long insn_mask;
00481   int in_pass;
00482 } *ti;
00483 
00484 struct insn_op_struct *op_data, **op_start;
00485 
00486 /* Recursive utility function used to find best match and to build automata.  */
00487 
00488 static unsigned long *
00489 cover_insn (unsigned long * cur, int pass, unsigned int mask)
00490 {
00491   int best_first = 0, last_match = -1, ninstr = 0;
00492   unsigned int best_len = 0;
00493   unsigned int i;
00494   unsigned long cur_mask = mask;
00495   unsigned long *next;
00496 
00497   for (i = 0; i < or32_num_opcodes; i++)
00498     if (ti[i].in_pass == pass)
00499       {
00500        cur_mask &= ti[i].insn_mask;
00501        ninstr++;
00502        last_match = i;
00503       }
00504   
00505   debug (8, "%08X %08lX\n", mask, cur_mask);
00506 
00507   if (ninstr == 0)
00508     return 0;
00509 
00510   if (ninstr == 1)
00511     {
00512       /* Leaf holds instruction index.  */
00513       debug (8, "%li>I%i %s\n",
00514             (long)(cur - automata), last_match, or32_opcodes[last_match].name);
00515 
00516       *cur = LEAF_FLAG | last_match;
00517       cur++;
00518       nuncovered--;
00519     }
00520   else
00521     {
00522       /* Find longest match.  */
00523       for (i = 0; i < 32; i++)
00524        {
00525          unsigned int len;
00526 
00527          for (len = best_len + 1; len < MIN (MAX_LEN, 33 - i); len++)
00528            {
00529              unsigned long m = (1UL << ((unsigned long) len)) - 1;
00530 
00531              debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)",
00532                    len,m, cur_mask, i, (cur_mask >> (unsigned)i),
00533                    (cur_mask >> (unsigned) i) & m);
00534 
00535              if ((m & (cur_mask >> (unsigned) i)) == m)
00536               {
00537                 best_len = len;
00538                 best_first = i;
00539                 debug (9, "!");
00540               }
00541              else
00542               break;
00543            }
00544        }
00545 
00546       debug (9, "\n");
00547 
00548       if (!best_len)
00549        {
00550          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask);
00551 
00552          for (i = 0; i < or32_num_opcodes; i++)
00553            if (ti[i].in_pass == pass)
00554              fprintf (stderr, "%s ", or32_opcodes[i].name);
00555          
00556          fprintf (stderr, "\n");
00557          exit (1);
00558        }
00559 
00560       debug (8, "%li> #### %i << %i (%i) ####\n",
00561             (long)(cur - automata), best_len, best_first, ninstr);
00562 
00563       *cur = best_first;
00564       cur++;
00565       *cur = (1 << best_len) - 1;
00566       cur++;
00567       next = cur;    
00568 
00569       /* Allocate space for pointers.  */
00570       cur += 1 << best_len;
00571       cur_mask = (1 << (unsigned long) best_len) - 1;
00572       
00573       for (i = 0; i < ((unsigned) 1 << best_len); i++)
00574        {
00575          unsigned int j;
00576          unsigned long *c;
00577 
00578          curpass++;
00579          for (j = 0; j < or32_num_opcodes; j++)
00580            if (ti[j].in_pass == pass
00581               && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i
00582               && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
00583              ti[j].in_pass = curpass;
00584 
00585          debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
00586          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
00587          if (c)
00588            {
00589              debug (8, "%li> #%X -> %lu\n", (long)(next - automata), i, (long)(cur - automata));
00590              *next = cur - automata;
00591              cur = c;        
00592            }
00593          else 
00594            {
00595              debug (8, "%li> N/A\n", (long)(next - automata));
00596              *next = 0;
00597            }
00598          next++;
00599        }
00600     }
00601   return cur;
00602 }
00603 
00604 /* Returns number of nonzero bits.  */
00605 
00606 static int
00607 num_ones (unsigned long value)
00608 {
00609   int c = 0;
00610 
00611   while (value)
00612     {
00613       if (value & 1)
00614        c++;
00615       value >>= 1;
00616     }
00617   return c;
00618 }
00619 
00620 /* Utility function, which converts parameters from or32_opcode
00621    format to more binary form.  Parameters are stored in ti struct.  */
00622 
00623 static struct insn_op_struct *
00624 parse_params (const struct or32_opcode * opcode,
00625              struct insn_op_struct * cur)
00626 {
00627   char *args = opcode->args;
00628   int i, type;
00629   
00630   i = 0;
00631   type = 0;
00632   /* In case we don't have any parameters, we add dummy read from r0.  */
00633 
00634   if (!(*args))
00635     {
00636       cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
00637       cur->data = 0;
00638       debug (9, "#%08lX %08lX\n", cur->type, cur->data);
00639       cur++;
00640       return cur;
00641   }
00642   
00643   while (*args != '\0')
00644     {     
00645       if (*args == 'r')
00646        {
00647          args++;
00648          type |= OPTYPE_REG;
00649        }
00650       else if (ISALPHA (*args))
00651        {
00652          unsigned long arg;
00653 
00654          arg = insn_extract (*args, opcode->encoding);
00655          debug (9, "%s : %08lX ------\n", opcode->name, arg);
00656          if (letter_signed (*args))
00657            {
00658              type |= OPTYPE_SIG;
00659              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
00660            }
00661 
00662          /* Split argument to sequences of consecutive ones.  */
00663          while (arg)
00664            {
00665              int shr = 0;
00666              unsigned long tmp = arg, mask = 0;
00667 
00668              while ((tmp & 1) == 0)
00669               {
00670                 shr++;
00671                 tmp >>= 1;
00672               }
00673              while (tmp & 1)
00674               {
00675                 mask++;
00676                 tmp >>= 1;
00677               }
00678              cur->type = type | shr;
00679              cur->data = mask;
00680              arg &= ~(((1 << mask) - 1) << shr);
00681              debug (6, "|%08lX %08lX\n", cur->type, cur->data);
00682              cur++;
00683            }
00684          args++;
00685        }
00686       else if (*args == '(')
00687        {
00688          /* Next param is displacement.
00689             Later we will treat them as one operand.  */
00690          cur--;
00691          cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
00692          debug (9, ">%08lX %08lX\n", cur->type, cur->data);
00693          cur++;
00694          type = 0;
00695          i++;
00696          args++;
00697        }
00698       else if (*args == OPERAND_DELIM)
00699        {
00700          cur--;
00701          cur->type = type | cur->type | OPTYPE_OP;
00702          debug (9, ">%08lX %08lX\n", cur->type, cur->data);
00703          cur++;
00704          type = 0;
00705          i++;
00706          args++;
00707        }
00708       else if (*args == '0')
00709        {
00710          cur->type = type;
00711          cur->data = 0;
00712          debug (9, ">%08lX %08lX\n", cur->type, cur->data);
00713          cur++;
00714          type = 0;
00715          i++;
00716          args++;
00717        }
00718       else if (*args == ')')
00719        args++;
00720       else
00721        {
00722          fprintf (stderr, "%s : parse error in args.\n", opcode->name);
00723          exit (1);
00724        }
00725     }
00726 
00727   cur--;
00728   cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
00729   debug (9, "#%08lX %08lX\n", cur->type, cur->data);
00730   cur++;
00731 
00732   return cur;
00733 }
00734 
00735 /* Constructs new automata based on or32_opcodes array.  */
00736 
00737 void
00738 build_automata (void)
00739 {
00740   unsigned int i;
00741   unsigned long *end;
00742   struct insn_op_struct *cur;
00743   
00744   automata = malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
00745   ti = malloc (sizeof (struct temp_insn_struct) * or32_num_opcodes);
00746 
00747   nuncovered = or32_num_opcodes;
00748   printf ("Building automata... ");
00749   /* Build temporary information about instructions.  */
00750   for (i = 0; i < or32_num_opcodes; i++)
00751     {
00752       unsigned long ones, zeros;
00753       char *encoding = or32_opcodes[i].encoding;
00754 
00755       ones  = insn_extract('1', encoding);
00756       zeros = insn_extract('0', encoding);
00757 
00758       ti[i].insn_mask = ones | zeros;
00759       ti[i].insn = ones;
00760       ti[i].in_pass = curpass = 0;
00761 
00762       /*debug(9, "%s: %s %08X %08X\n", or32_opcodes[i].name,
00763        or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
00764     }
00765   
00766   /* Until all are covered search for best criteria to separate them.  */
00767   end = cover_insn (automata, curpass, 0xFFFFFFFF);
00768 
00769   if (end - automata > MAX_AUTOMATA_SIZE)
00770     {
00771       fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
00772       exit (1);
00773     }
00774 
00775   printf ("done, num uncovered: %i/%i.\n", nuncovered, or32_num_opcodes);
00776   printf ("Parsing operands data... ");
00777 
00778   op_data = malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct));
00779   op_start = malloc (or32_num_opcodes * sizeof (struct insn_op_struct *));
00780   cur = op_data;
00781 
00782   for (i = 0; i < or32_num_opcodes; i++)
00783     {
00784       op_start[i] = cur;
00785       cur = parse_params (&or32_opcodes[i], cur);
00786 
00787       if (cur - op_data > MAX_OP_TABLE_SIZE)
00788        {
00789          fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
00790          exit (1);
00791        }
00792     }
00793   printf ("done.\n");
00794 }
00795 
00796 void
00797 destruct_automata (void)
00798 {
00799   free (ti);
00800   free (automata);
00801   free (op_data);
00802   free (op_start);
00803 }
00804 
00805 /* Decodes instruction and returns instruction index.  */
00806 
00807 int
00808 insn_decode (unsigned int insn)
00809 {
00810   unsigned long *a = automata;
00811   int i;
00812 
00813   while (!(*a & LEAF_FLAG))
00814     {
00815       unsigned int first = *a;
00816 
00817       debug (9, "%li ", (long)(a - automata));
00818 
00819       a++;
00820       i = (insn >> first) & *a;
00821       a++;
00822       if (!*(a + i))
00823        {
00824          /* Invalid instruction found?  */
00825          debug (9, "XXX\n");
00826          return -1;
00827        }
00828       a = automata + *(a + i);
00829     }
00830 
00831   i = *a & ~LEAF_FLAG;
00832 
00833   debug (9, "%i\n", i);
00834 
00835   /* Final check - do we have direct match?
00836      (based on or32_opcodes this should be the only possibility,
00837      but in case of invalid/missing instruction we must perform a check)  */
00838   if ((ti[i].insn_mask & insn) == ti[i].insn) 
00839     return i;
00840   else
00841     return -1;
00842 }
00843 
00844 static char disassembled_str[50];
00845 char *disassembled = &disassembled_str[0];
00846 
00847 /* Automagically does zero- or sign- extension and also finds correct
00848    sign bit position if sign extension is correct extension. Which extension
00849    is proper is figured out from letter description.  */
00850    
00851 static unsigned long
00852 extend_imm (unsigned long imm, char l)
00853 {
00854   unsigned long mask;
00855   int letter_bits;
00856   
00857   /* First truncate all bits above valid range for this letter
00858      in case it is zero extend.  */
00859   letter_bits = letter_range (l);
00860   mask = (1 << letter_bits) - 1;
00861   imm &= mask;
00862   
00863   /* Do sign extend if this is the right one.  */
00864   if (letter_signed(l) && (imm >> (letter_bits - 1)))
00865     imm |= (~mask);
00866 
00867   return imm;
00868 }
00869 
00870 static unsigned long
00871 or32_extract (char param_ch, char *enc_initial, unsigned long insn)
00872 {
00873   char *enc;
00874   unsigned long ret = 0;
00875   int opc_pos = 0;
00876   int param_pos = 0;
00877 
00878   for (enc = enc_initial; *enc != '\0'; enc++)
00879     if (*enc == param_ch)
00880       {
00881         if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
00882          continue;
00883         else
00884           param_pos++;
00885       }
00886 
00887 #if DEBUG
00888   printf ("or32_extract: %x ", param_pos);
00889 #endif
00890   opc_pos = 32;
00891 
00892   for (enc = enc_initial; *enc != '\0'; )
00893     if ((*enc == '0') && (*(enc + 1) == 'x')) 
00894       {
00895         opc_pos -= 4;
00896         if ((param_ch == '0') || (param_ch == '1')) 
00897           {
00898             unsigned long tmp = strtol (enc, NULL, 16);
00899 #if DEBUG
00900             printf (" enc=%s, tmp=%x ", enc, tmp);
00901 #endif
00902             if (param_ch == '0')
00903               tmp = 15 - tmp;
00904             ret |= tmp << opc_pos;
00905           }
00906         enc += 3;
00907       }
00908     else if ((*enc == '0') || (*enc == '1')) 
00909       {
00910         opc_pos--;
00911         if (param_ch == *enc)
00912           ret |= 1 << opc_pos;
00913         enc++;
00914       }
00915     else if (*enc == param_ch) 
00916       {
00917         opc_pos--;
00918         param_pos--;
00919 #if DEBUG
00920         printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
00921 #endif  
00922         if (ISLOWER (param_ch))
00923           ret -= ((insn >> opc_pos) & 0x1) << param_pos;
00924         else
00925           ret += ((insn >> opc_pos) & 0x1) << param_pos;
00926         enc++;
00927       }
00928     else if (ISALPHA (*enc)) 
00929       {
00930         opc_pos--;
00931         enc++;
00932       }
00933     else if (*enc == '-') 
00934       {
00935         opc_pos--;
00936         enc++;
00937       }
00938     else
00939       enc++;
00940 
00941 #if DEBUG
00942   printf ("ret=%x\n", ret);
00943 #endif
00944   return ret;
00945 }
00946 
00947 /* Print register. Used only by print_insn.  */
00948 
00949 static void
00950 or32_print_register (char param_ch, char *encoding, unsigned long insn)
00951 {
00952   int regnum = or32_extract(param_ch, encoding, insn);
00953   
00954   sprintf (disassembled, "%sr%d", disassembled, regnum);
00955 }
00956 
00957 /* Print immediate. Used only by print_insn.  */
00958 
00959 static void
00960 or32_print_immediate (char param_ch, char *encoding, unsigned long insn)
00961 {
00962   int imm = or32_extract (param_ch, encoding, insn);
00963 
00964   imm = extend_imm (imm, param_ch);
00965   
00966   if (letter_signed (param_ch))
00967     {
00968       if (imm < 0)
00969         sprintf (disassembled, "%s%d", disassembled, imm);
00970       else
00971         sprintf (disassembled, "%s0x%x", disassembled, imm);
00972     }
00973   else
00974     sprintf (disassembled, "%s%#x", disassembled, imm);
00975 }
00976 
00977 /* Disassemble one instruction from insn to disassemble.
00978    Return the size of the instruction.  */
00979 
00980 int
00981 disassemble_insn (unsigned long insn)
00982 {
00983   int index;
00984   index = insn_decode (insn);
00985 
00986   if (index >= 0)
00987     {
00988       struct or32_opcode const *opcode = &or32_opcodes[index];
00989       char *s;
00990 
00991       sprintf (disassembled, "%s ", opcode->name);
00992       for (s = opcode->args; *s != '\0'; ++s)
00993         {
00994           switch (*s)
00995             {
00996             case '\0':
00997               return 4;
00998   
00999             case 'r':
01000               or32_print_register (*++s, opcode->encoding, insn);
01001               break;
01002   
01003             default:
01004               if (strchr (opcode->encoding, *s))
01005                 or32_print_immediate (*s, opcode->encoding, insn);
01006               else
01007                 sprintf (disassembled, "%s%c", disassembled, *s);
01008             }
01009         }
01010     }
01011   else
01012     {
01013       /* This used to be %8x for binutils.  */
01014       sprintf (disassembled, "%s.word 0x%08lx", disassembled, insn);
01015     }
01016 
01017   return insn_len (insn);
01018 }