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