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
00028
00029
00030
00031
00032
00033
00034
00035 #include "global.h"
00036 #include "decoder.h"
00037 #include "hppa-names.h"
00038 #include "rtl.h"
00039
00040 void c_null(ADDRESS hostpc, char **garble);
00041 unsigned long c_wcr(ADDRESS hostpc, char **garble);
00042 bool c_c_n(ADDRESS hostpc);
00043 void addr(ADDRESS hostpc);
00044
00045
00046 void not_used(int unwanted)
00047 {
00048 unwanted = 0;
00049 }
00050
00051 DWord getDword (unsigned lc)
00052
00053
00054 {
00055 return
00056 (DWord)
00057 ((((((
00058 *(Byte *)lc << 8
00059 ) + *(Byte *)(lc+1)) << 8
00060 ) + *(Byte *)(lc+2)) << 8
00061 ) + *(Byte *)(lc+3));
00062 }
00063
00064 bool c_c_n(ADDRESS hostpc)
00065 {
00066 bool result = true;
00067 match hostpc to
00068 | c_c_nonneg() => { result = true; }
00069 | c_c_neg() => { result = false; }
00070 endmatch
00071 return result;
00072 }
00073
00074 SemStr* NJMCDecoder::c_c(ADDRESS hostpc, int &cond)
00075 {
00076 static const char *c_c_names = {
00077 "c_c_no", "c_c_eq", "c_c_l", "c_c_le", "c_c_ul", "c_c_ule", "c_c_sv",
00078 "c_c_od", "c_c_yes", "c_c_ne", "c_c_ge", "c_c_g", "c_c_uge", "c_c_ug",
00079 "c_c_nsv", "c_c_ev"
00080 };
00081 static const int cmpib_codes = { 4, 1, 2, 3, 12, 9, 10, 11 };
00082 static const int sep_codes = { 0, 1, 2, 7, 8, 9, 10, 15 };
00083 match hostpc to
00084 | c_arith_w(c3,cmplt) => {
00085 cond = c3 + (c_c_n(cmplt)?0:8);
00086 }
00087 | c_arith_dw(c3,cmplt) => {
00088 cond = c3 + (c_c_n(cmplt)?0:8);
00089 }
00090 | c_arith_none() => {
00091 cond = 0;
00092 }
00093 | c_sep(c3_16) => {
00094 cond = sep_codes;
00095 }
00096 | c_cmpb_w(c3,cmplt) => {
00097 cond = c3 + (c_c_n(cmplt)?0:8);
00098 }
00099 | c_cmpb_dw(c3,cmplt) => {
00100 cond = c3 + (c_c_n(cmplt)?0:8);
00101 }
00102 | c_cmpib_dw(c3) => {
00103 cond = cmpib_codes;
00104 }
00105 | c_bbs_w(c) => {
00106 cond = 1 + (c?0:8);
00107 }
00108 | c_bbs_dw(c) => {
00109 cond = 1 + (c?0:8);
00110 }
00111 else {
00112 cond = 0;
00113 }
00114 endmatch
00115 return instantiateNamedParam(c_c_names[cond]);
00116 }
00117
00118 unsigned long c_wcr(ADDRESS hostpc, char **garble)
00119 {
00120 #if 0
00121 unsigned long regl;
00122 match hostpc to
00123 | c_mfctl(r_06) => {
00124 regl = r_06;
00125 }
00126 | c_mfctl_w() => {
00127 *garble += sprintf(*garble,".w");
00128 regl = 11;
00129 }
00130 else {
00131 regl = 0;
00132
00133 }
00134 endmatch
00135 return regl;
00136 #else
00137 return 0;
00138 #endif
00139 }
00140
00141 void c_null(ADDRESS hostpc, char **garble)
00142 {
00143 #if 0
00144 match hostpc to
00145 | c_br_nnull() => {
00146 }
00147 | c_br_null() => {
00148 *garble += sprintf(*garble, ".n");
00149 }
00150 else {
00151
00152 }
00153 endmatch
00154 #endif
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 list<RT*>* NJMCDecoder::decodeLowLevelInstruction (ADDRESS hostPC, ADDRESS pc,
00171 DecodeResult& result)
00172 {
00173 ADDRESS nextPC;
00174
00175 list<RT*>* RTs = NULL;
00176 int condvalue;
00177 match hostPC to
00178 | arith(cmplt,r_11,r_06,t_27) => {
00179
00180 RTs = instantiate(pc, name, dis_Reg(r_11), dis_Reg(r_06),
00181 dis_Reg(t_27),c_c(cmplt, condvalue));
00182 }
00183 | arith_imm(cmplt, imm11, r_06, t_11) => {
00184
00185 RTs = instantiate(pc, name, dis_Num(imm11), dis_Reg(r_06),
00186 dis_Reg(t_11), c_c(cmplt, condvalue));
00187 }
00188 | ADDIL(imm21, r_06) => {
00189 RTs = instantiate(pc, name, dis_Num(imm21), dis_Reg(r_06));
00190 }
00191 | LDIL(imm21, t_06) => {
00192 RTs = instantiate(pc, name, dis_Num(imm21), dis_Reg(t_06));
00193 }
00194 | iloads(c_addr, xd, s, b,t_27) => {
00195 RTs = instantiate(pc, name, dis_c_addr(c_addr),
00196 dis_xd(xd), dis_Sreg(s),
00197 dis_Reg(b), dis_Reg(t_27));
00198 }
00199 | istores(c_addr,r_11, xd, s, b) => {
00200 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_Reg(r_11),
00201 dis_xd(xd), dis_Sreg(s), dis_Reg(b));
00202 }
00203 | fwloads(c_addr, xd, s, b, t_27) => {
00204 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_xd(xd),
00205 dis_Sreg(s), dis_Reg(b), dis_Freg(t_27, 0));
00206 }
00207 | fwstores(c_addr, r_27, xd, s, b) => {
00208 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_Freg(r_27, 0),
00209 dis_xd(xd), dis_Sreg(s), dis_Reg(b));
00210 }
00211 | fdloads(c_addr, xd, s, b, t_27) => {
00212 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_xd(xd),
00213 dis_Sreg(s), dis_Reg(b), dis_Freg(t_27, 1));
00214 }
00215 | fdstores(c_addr, r_27, xd, s, b) => {
00216 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_Freg(r_27, 1),
00217 dis_xd(xd), dis_Sreg(s), dis_Reg(b));
00218 }
00219 | iloads_ldisp(c_addr, xd, s, b, r_11) => {
00220 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_xd(xd),
00221 dis_Sreg(s), dis_Reg(b), dis_Reg(r_11));
00222 }
00223 | istores_ldisp(c_addr, r_11, xd, s, b) => {
00224 RTs = instantiate(pc, name, dis_c_addr(c_addr), dis_Reg(r_11),
00225 dis_xd(xd), dis_Sreg(s), dis_Reg(b));
00226 }
00227 | LDO(ldisp, b, t) => {
00228 RTs = instantiate(pc, name, dis_Num(ldisp), dis_Reg(b), dis_Reg(t));
00229 }
00230 | VSHD(r1, r2, t, c) => {
00231 RTs = instantiate(pc, name, dis_Reg(r1), dis_Reg(r2), dis_Reg(t),
00232 c_c(c, condvalue));
00233 }
00234 | SHD(r1, r2, p, t, c) => {
00235 RTs = instantiate(pc, name, dis_Reg(r1), dis_Reg(r2), dis_Num(p),
00236 dis_Reg(t), c_c(c, condvalue));
00237 }
00238 | ext_var(r, len, t, c) => {
00239 RTs = instantiate(pc, name, dis_Reg(r), dis_Num(len), dis_Reg(t),
00240 c_c(c, condvalue));
00241 }
00242 | ext_fix(r, p, len, t, c) => {
00243 RTs = instantiate(pc, name, dis_Reg(r), dis_Num(p), dis_Num(len),
00244 dis_Reg(t), c_c(c, condvalue));
00245 }
00246 | dep_var(r, len, t, c) => {
00247 RTs = instantiate(pc, name, dis_Reg(r), dis_Num(len), dis_Reg(t),
00248 c_c(c, condvalue));
00249 }
00250 | dep_fix(r, p, len, t, c) => {
00251 RTs = instantiate(pc, name, dis_Reg(r), dis_Num(p), dis_Num(len),
00252 dis_Reg(t), c_c(c, condvalue));
00253 }
00254 | dep_ivar(i, len, t, c) => {
00255 RTs = instantiate(pc, name, dis_Num(i), dis_Num(len), dis_Reg(t),
00256 c_c(c, condvalue));
00257 }
00258 | dep_ifix(i, p, len, t, c) => {
00259 RTs = instantiate(pc, name, dis_Num(i), dis_Num(p), dis_Num(len),
00260 dis_Reg(t), c_c(c, condvalue));
00261 }
00262 | ubranch(nulli,ubr_target,t_06) => {
00263
00264 RTs = instantiate(pc, name, dis_Num(ubr_target), dis_Reg(t_06));
00265 not_used(nulli);
00266 }
00267 | BL.LONG(nulli,ubr_target) => {
00268
00269 RTs = instantiate(pc, name, dis_Num(ubr_target));
00270 not_used(nulli);
00271 }
00272 | BLR(nulli,x_11,t_06) => {
00273
00274 RTs = instantiate(pc, name, dis_Reg(x_11), dis_Reg(t_06));
00275 not_used(nulli);
00276 }
00277 | BV(nulli,x_11,b_06) => {
00278
00279 RTs = instantiate(pc, name, dis_Reg(x_11), dis_Reg(b_06));
00280 not_used(nulli);
00281 }
00282 | bve(p_31,nulli,b_06) => {
00283
00284 RTs = instantiate(pc, name, p_31, dis_Reg(b_06));
00285 not_used(nulli);
00286 }
00287 | BREAK(im5_27,im13_06) => {
00288 RTs = instantiate(pc, name, dis_Num(im5_27), dis_Num(im13_06));
00289 }
00290 | sysop_i_t(im10_06,t_27) => {
00291 RTs = instantiate(pc, name, dis_Num(im10_06), dis_Reg(t_27));
00292 }
00293 | sysop_simple => {
00294 RTs = instantiate(pc, name);
00295 }
00296 | sysop_r(r_11) => {
00297 RTs = instantiate(pc, name, dis_Reg(r_11));
00298 }
00299 | sysop_cr_t(cmplt, t_27) => {
00300 RTs = instantiate(pc, name, dis_c_wcr(cmplt), dis_Reg(t_27));
00301 }
00302 | MTCTL(r_11, ct_06) => {
00303 RTs = instantiate(pc, name, dis_Reg(r_11), dis_ct(ct_06));
00304 }
00305 | MFIA(t_27) => {
00306 RTs = instantiate(pc, name, dis_Reg(t_27));
00307 }
00308
00309
00310 | flt_c0_all(fmt, rf, tf) => {
00311 RTs = instantiate(pc, name, dis_Num(fmt), dis_Freg(rf, fmt),
00312 dis_Freg(tf, fmt));
00313 }
00314 | flt_c1_all(sf, df, rf, tf) => {
00315 RTs = instantiate(pc, name, dis_Num(sf), dis_Num(df),
00316 dis_Freg(rf, sf), dis_Freg(tf, df));
00317 }
00318 | flt_c2_all(sf, df, rf, tf) => {
00319 RTs = instantiate(pc, name, dis_Num(sf), dis_Num(df),
00320 dis_Freg(rf, sf), dis_Freg(tf, df));
00321 }
00322 | flt_c3_all(fmt, fr1, fr2, frt) => {
00323 RTs = instantiate(pc, name, dis_Num(fmt), dis_Freg(fr1, fmt),
00324 dis_Freg(fr2, fmt), dis_Freg(frt, fmt));
00325 }
00326 | XMPYU(fr1, fr2, frt) => {
00327
00328 RTs = instantiate(pc, "XMPYU", dis_Freg(fr1, 0), dis_Freg(fr2, 0),
00329 dis_Freg(frt, 1));
00330 }
00331
00332
00333
00334
00335
00336
00337 else {
00338
00339 result.valid = false;
00340 cout << "Undecoded instruction " << hex << *(int*)hostPC << " at " << pc << " (opcode " << ((*(unsigned*)hostPC) >> 26) << ")\n";
00341 }
00342 endmatch
00343
00344 result.numBytes = (nextPC - hostPC);
00345 return RTs;
00346
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356