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 #include "global.h"
00035 #include "decoder.h"
00036 #include "BinaryFile.h"
00037
00038 #include "hppa-names.h"
00039
00040
00041 extern char _assembly;
00042 char* astr;
00043 char *cmpltsep = ".";
00044
00045
00046 const char* GetSym(unsigned pc);
00047 const char* GetReloc(unsigned pc);
00048
00049
00050 DWord getDword (unsigned lc)
00051
00052
00053 {
00054 return
00055 (DWord)
00056 ((((((
00057 *(Byte *)lc << 8
00058 ) + *(Byte *)(lc+1)) << 8
00059 ) + *(Byte *)(lc+2)) << 8
00060 ) + *(Byte *)(lc+3));
00061 }
00062
00063 static char killBuffer;
00064
00065
00066 char* killDot(char* str)
00067 {
00068 strcpy(killBuffer, str);
00069 char* p = strchr(killBuffer, '.');
00070 if (p) *p = '\0';
00071 return killBuffer;
00072 }
00073
00074
00075 void NJMCDecoder::dis_c_c(ADDRESS hostpc)
00076 {
00077 static char *logw = {"",",=",",<",",OD"
00078 ,",TR",",!=",",>=",",EV"};
00079 static char *logdw = {"",",*=",",*<] ",",*OD"
00080 ,",*TR",",*!=",",*>=",",*EV"};
00081 static char *cmpsubw = {"",",=",",<",",<=",",<<",",<<=",
00082 ",SV",",OD",
00083 ",TR",",<>",",>=",",>",",>>=",
00084 ",>>",",NSV",",EV"};
00085 static char *cmpsubdw = {"",",*=",",*<",",*<=",",*<<",",*<<=",
00086 ",*SV",",*OD",
00087 ",*TR",",*<>",",*>=",",*>",",*>>=",
00088 ",*>>",",*NSV",",*EV"};
00089
00090
00091
00092 match hostpc to
00093 | c_arith_w(c3_16) => {
00094 astr += sprintf(astr, "%s", logw[c3_16]);
00095 strcat(constrName, "c_arith_w ");
00096 }
00097 | c_arith_dw(c3_16) => {
00098 astr += sprintf(astr, "%s", logdw[c3_16]);
00099 strcat(constrName, "c_arith_dw ");
00100 }
00101 | c_cmpb_w(c3_16) => {
00102 astr += sprintf(astr, "%s", cmpsubw[c3_16]);
00103 strcat(constrName, "c_cmpb_w ");
00104 }
00105 | c_cmpb_dw(c3_16) => {
00106 astr += sprintf(astr, "%s", cmpsubdw[c3_16]);
00107 strcat(constrName, "c_cmpb_dw ");
00108 }
00109 | c_bbs_w(c_16) => {
00110 astr += sprintf(astr, "[%d]",1-c_16);
00111 strcat(constrName, "c_bbs_w ");
00112 }
00113 | c_bbs_dw(c_16) => {
00114 astr += sprintf(astr, "[%d]",1-c_16);
00115 strcat(constrName, "c_bbs_dw ");
00116 }
00117 | c_arith_none() => {
00118 }
00119 else {
00120 astr += sprintf(astr, "#c_C%08X", getDword(hostpc));
00121 }
00122 endmatch
00123 }
00124
00125 void NJMCDecoder::dis_addr(ADDRESS hostpc)
00126 {
00127 match hostpc to
00128 | index_addr(x, ss, b, cmplt) => {
00129 astr += sprintf(astr, "%s(%s,%s)",b_06_names[x], s2_16_names[ss],
00130 b_06_names[b]);
00131 dis_c_addr(cmplt);
00132 strcat(constrName, "index_addr ");
00133 }
00134 | indexabs_addr(x, b, cmplt) => {
00135 astr += sprintf(astr, "%s(%s)",b_06_names[x], b_06_names[b]);
00136 dis_c_addr(cmplt);
00137 strcat(constrName, "indexabs_addr ");
00138 }
00139 | sdispl_addr(im5, ss, b, cmplt) => {
00140 astr += sprintf(astr, "%d(%s,%s)", im5, s2_16_names[ss],
00141 b_06_names[b]);
00142 dis_c_addr(cmplt);
00143 strcat(constrName, "sdispl_addr ");
00144 }
00145 | sdisplabs_addr(im5, b, cmplt) => {
00146 astr += sprintf(astr, "%d(%s)", im5, b_06_names[b]);
00147 dis_c_addr(cmplt);
00148 strcat(constrName, "sdisplabs_addr ");
00149 }
00150 | sdisps_addr(im5, ss, b, cmplt) => {
00151 astr += sprintf(astr, "%d(%s,%s)", im5, s2_16_names[ss],
00152 b_06_names[b]);
00153 dis_c_addr(cmplt);
00154 strcat(constrName, "sdisps_addr ");
00155 }
00156 | sdispsabs_addr(im5, b, cmplt) => {
00157 astr += sprintf(astr, "%d(%s)", im5, b_06_names[b]);
00158 dis_c_addr(cmplt);
00159 strcat(constrName, "sdispsabs_addr ");
00160 }
00161 | ldispa12_addr(ldisp, ss, b, cmplt) => {
00162 astr += sprintf(astr, "%d(%s,%s)", ldisp, s2_16_names[ss],
00163 b_06_names[b]);
00164 dis_c_addr(cmplt);
00165 strcat(constrName, "ldispa12_addr ");
00166 }
00167 | ldispa16_addr(ldisp, ss, b, cmplt) => {
00168 astr += sprintf(astr, "%d(%s,%s)", ldisp, s2_16_names[ss],
00169 b_06_names[b]);
00170 dis_c_addr(cmplt);
00171 strcat(constrName, "ldispa16_addr ");
00172 }
00173 | ldispa16ma_addr(ldisp, ss, b, cmplt) => {
00174 astr += sprintf(astr, "%d(%s,%s)", ldisp, s2_16_names[ss],
00175 b_06_names[b]);
00176 dis_c_addr(cmplt);
00177 strcat(constrName, "ldispa16ma_addr ");
00178 }
00179 | ldispa16mb_addr(ldisp, ss, b, cmplt) => {
00180 astr += sprintf(astr, "%d(%s,%s)", ldisp, s2_16_names[ss],
00181 b_06_names[b]);
00182 dis_c_addr(cmplt);
00183 strcat(constrName, "ldispa16mb_addr ");
00184 }
00185 | ldispa16abs_addr(ldisp, b, cmplt) => {
00186 astr += sprintf(astr, "%d(%s)", ldisp, b_06_names[b]);
00187 dis_c_addr(cmplt);
00188 strcat(constrName, "ldispa16abs_addr ");
00189 }
00190 | ldispa16a_addr(ldisp, ss, b, cmplt) => {
00191 astr += sprintf(astr, "%d(%s,%s)", ldisp, s2_16_names[ss],
00192 b_06_names[b]);
00193 dis_c_addr(cmplt);
00194 strcat(constrName, "ldispa16a_addr ");
00195 }
00196 | bea17_addr(offset, ss, b) => {
00197 astr += sprintf(astr, "%d(%s,%s)", offset, s3_16_names[ss],
00198 b_06_names[b]);
00199 strcat(constrName, "bea17_addr ");
00200 }
00201 else {
00202 astr += sprintf(astr, "#ADDR%08X",getDword(hostpc));
00203 }
00204 endmatch
00205 }
00206
00207 unsigned long NJMCDecoder::dis_c_wcr(ADDRESS hostpc)
00208 {
00209 unsigned long regl;
00210 match hostpc to
00211 | c_mfctl(r_06) => {
00212
00213 regl = r_06;
00214 strcat(constrName, "c_mfctl ");
00215 }
00216 | c_mfctl_w() => {
00217 astr += sprintf(astr, ".w");
00218 regl = 11;
00219 strcat(constrName, "c_mfctl_w ");
00220 }
00221 else {
00222 regl = 0;
00223 astr += sprintf(astr, "#c_WCR%08X#", getDword(hostpc));
00224 }
00225 endmatch
00226 return regl;
00227 }
00228
00229 void NJMCDecoder::dis_c_null(ADDRESS hostpc)
00230 {
00231 match hostpc to
00232 | c_br_nnull() => {
00233
00234 strcat(constrName, "c_br_nnull ");
00235 }
00236 | c_br_null() => {
00237 astr += sprintf(astr, ",n");
00238 strcat(constrName, "c_br_null ");
00239 }
00240 else
00241 astr += sprintf(astr, "#c_NULL%08X#", getDword(hostpc));
00242 endmatch
00243 }
00244
00245 void NJMCDecoder::dis_c_bit(ADDRESS hostpc)
00246 {
00247 match hostpc to
00248 | c_bitpos_w(p_06) => {
00249 astr += sprintf(astr, "@%d",p_06);
00250 strcat(constrName, "c_bitpos_w ");
00251 }
00252 | c_bitpos_dw(p_06) => {
00253 astr += sprintf(astr, "@%d",p_06 + 32);
00254 strcat(constrName, "c_bitpos_dw ");
00255 }
00256 | c_bitsar() => {
00257 astr += sprintf(astr, "%s", "%cr11");
00258 strcat(constrName, "c_bitsar ");
00259 }
00260 else
00261 astr += sprintf(astr, "#c_BIT%08X#", getDword(hostpc));
00262 endmatch
00263 }
00264
00265 void NJMCDecoder::dis_c_addr(ADDRESS hostpc)
00266 {
00267 match hostpc to
00268 | ins_b => {
00269 astr += sprintf(astr, "[b]");
00270 strcat(constrName, "ins_b ");
00271 }
00272 | ins_bm => {
00273 astr += sprintf(astr, "[bm]");
00274 strcat(constrName, "ins_bm ");
00275 }
00276 | ins_e => {
00277 astr += sprintf(astr, "[e]");
00278 strcat(constrName, "ins_e ");
00279 }
00280 | ins_em => {
00281 astr += sprintf(astr, "[em]");
00282 strcat(constrName, "ins_em ");
00283 }
00284 | ins_def_d => {
00285
00286 strcat(constrName, "ins_def_d ");
00287 }
00288 | ins_ma => {
00289 astr += sprintf(astr, "[ma]");
00290 strcat(constrName, "ins_ma ");
00291 }
00292 | ins_mb => {
00293 astr += sprintf(astr, "[mb]");
00294 strcat(constrName, "ins_mb ");
00295 }
00296 | ins_o => {
00297 astr += sprintf(astr, "[o]");
00298 strcat(constrName, "ins_o ");
00299 }
00300 | ins_def_il => {
00301
00302 strcat(constrName, "ins_def_il ");
00303 }
00304 | ins_s => {
00305 astr += sprintf(astr, "[s]");
00306 strcat(constrName, "ins_s ");
00307 }
00308 | ins_sm => {
00309 astr += sprintf(astr, "[sm]");
00310 strcat(constrName, "ins_sm ");
00311 }
00312 | ins_m => {
00313 astr += sprintf(astr, "[m]");
00314 strcat(constrName, "ins_m ");
00315 }
00316 else
00317 astr += sprintf(astr, "#c_addr%08X#", getDword(hostpc));
00318 endmatch
00319 }
00320
00321 void NJMCDecoder::dis_flt_fmt(int fmt)
00322 {
00323
00324 switch(fmt) {
00325 case 0: astr += sprintf(astr, ",sgl"); break;
00326 case 1: astr += sprintf(astr, ",dbl"); break;
00327 case 3: astr += sprintf(astr, ",quad"); break;
00328 default:astr += sprintf(astr, ",?"); break;
00329 }
00330 }
00331
00332 void NJMCDecoder::dis_faddr(ADDRESS faddr)
00333 {
00334 match faddr to
00335 | index_faddr (x, s, b) => {
00336 astr += sprintf(astr, " %s(%s,%s)", b_06_names[x], s2_16_names[s],
00337 b_06_names[b]);
00338 strcat(constrName, "index_faddr ");
00339 }
00340 | sdisps_faddr(d, s, b) => {
00341 astr += sprintf(astr, " %d(%s,%s)", d, s2_16_names[s],
00342 b_06_names[b]);
00343 strcat(constrName, "sdisps_faddr ");
00344 }
00345 endmatch
00346 }
00347
00348 void NJMCDecoder::dis_c_faddr(ADDRESS c_faddr)
00349 {
00350 match c_faddr to
00351 | ins_faddr_s => {
00352 astr += sprintf(astr, ",s");
00353 strcat(constrName, "ins_faddr_s ");
00354 }
00355 | ins_faddr_m => {
00356 astr += sprintf(astr, ",m");
00357 strcat(constrName, "ins_faddr_m ");
00358 }
00359 | ins_faddr_sm => {
00360 astr += sprintf(astr, ",sm");
00361 strcat(constrName, "ins_faddr_sm ");
00362 }
00363 | ins_faddr_x => {
00364 strcat(constrName, "ins_faddr_x ");
00365 }
00366 | ins_faddr_mb => {
00367 astr += sprintf(astr, ",mb");
00368 strcat(constrName, "ins_faddr_mb ");
00369 }
00370 | ins_faddr_ma => {
00371 astr += sprintf(astr, ",ma");
00372 strcat(constrName, "ins_faddr_ma ");
00373 }
00374 | ins_faddr_si => {
00375 strcat(constrName, "ins_faddr_si ");
00376 }
00377 endmatch
00378 }
00379
00380 int NJMCDecoder::decodeAssemblyInstruction (ADDRESS pc, int delta)
00381 {
00382 char sCmplt;
00383 unsigned long r1,r2;
00384 sCmplt='\0';
00385 ADDRESS hostPC = pc + delta;
00386
00387 astr = _assembly + sprintf(_assembly, "%x: %08x ", pc, *(unsigned*)hostPC);
00388
00389 match hostPC to
00390 | NOP => {
00391 astr += sprintf(astr, "NOP");
00392 }
00393 | COPY(r, t) => {
00394 astr += sprintf(astr, "COPY %s,%s", r_06_names[r], t_27_names[t]);
00395 }
00396 | arith(cmplt,r_11,r_06,t_27) => {
00397
00398 astr += sprintf(astr, "%s", name);
00399 dis_c_c(cmplt);
00400 astr += sprintf(astr, " %s,%s,%s",
00401 r_11_names[r_11], r_06_names[r_06], t_27_names[t_27]);
00402 strcat(constrName, "arith ");
00403 }
00404 | arith_imm(cmplt, im11_21, r_06, t_11) => {
00405
00406 astr += sprintf(astr, "%s", name);
00407 dis_c_c(cmplt);
00408 astr += sprintf(astr, " %d,%s,%s", im11_21, r_06_names[r_06],
00409 t_11_names[t_11]);
00410 strcat(constrName, "arith_imm ");
00411 }
00412 | ADDIL(imm21, r_06) => {
00413 astr += sprintf(astr, "%s", name);
00414
00415 astr += sprintf(astr, " %d,%s,%s", imm21, r_06_names[r_06],
00416 t_11_names[1]);
00417 strcat(constrName, "ADDIL ");
00418 }
00419 | LDIL(imm21, t_06) => {
00420 astr += sprintf(astr, "%s", name);
00421
00422 astr += sprintf(astr, " %d,%s", imm21, t_06_names[t_06]);
00423 strcat(constrName, "LDIL ");
00424 }
00425 | iloads(addr,t_27) => {
00426 astr += sprintf(astr, "%s ", name);
00427 dis_addr(addr);
00428 astr += sprintf(astr, ",%s",t_27_names[t_27]);
00429 strcat(constrName, "iloads ");
00430 }
00431 | istores(r_11,addr) => {
00432 astr += sprintf(astr, "%s", name);
00433 astr += sprintf(astr, " %s", r_11_names[r_11]);
00434 dis_addr(addr);
00435 strcat(constrName, "istores ");
00436 }
00437 | ubranch(nulli,ubr_target,t_06) => {
00438
00439 astr += sprintf(astr, "%s", name);
00440 dis_c_null(nulli);
00441
00442 ADDRESS dest = ubr_target + hostPC - delta;
00443
00444 const char* dsym = pBF->SymbolByAddress(dest);
00445 char hexsym;
00446 if (dsym == 0)
00447 sprintf(hexsym, "0x%x", dest);
00448 astr += sprintf(astr, " %s, %s", (dsym ? dsym : hexsym),
00449 t_06_names[t_06]);
00450 strcat(constrName, "ubranch ");
00451 }
00452 | BL.LONG(nulli,ubr_target) => {
00453
00454 astr += sprintf(astr, "%s", name);
00455 dis_c_null(nulli);
00456 astr += sprintf(astr, " %d %s", ubr_target, t_06_names[2]);
00457 strcat(constrName, "BL.LONG ");
00458 }
00459 | BLR(nulli,x_11,t_06) => {
00460
00461 astr += sprintf(astr, "%s", name);
00462 dis_c_null(nulli);
00463 astr += sprintf(astr, " %s,%s", x_11_names[x_11], t_06_names[t_06]);
00464 strcat(constrName, "BLR ");
00465 }
00466 | BV(nulli,x_11,b_06) => {
00467
00468 astr += sprintf(astr, "%s", name);
00469 dis_c_null(nulli);
00470 astr += sprintf(astr, " %s(%s)", x_11_names[x_11], b_06_names[b_06]);
00471 strcat(constrName, "BV ");
00472 }
00473 | bve(p_31,nulli,b_06) => {
00474
00475 astr += sprintf(astr, "%s", name);
00476 dis_c_null(nulli);
00477 astr += sprintf(astr, " (%s)", b_06_names[b_06]);
00478 strcat(constrName, "bve ");
00479 }
00480 | be_all(nulli,cmplt) => {
00481 astr += sprintf(astr, "%s", name);
00482 dis_c_null(nulli);
00483 astr += sprintf(astr, " ");
00484 dis_addr(cmplt);
00485 strcat(constrName, "be_all ");
00486 }
00487 | loads_l(cmplt,t_11) => {
00488 astr += sprintf(astr, "%s ", name);
00489 dis_addr(cmplt);
00490 astr += sprintf(astr, ",%s", t_11_names[t_11]);
00491 strcat(constrName, "loads_l ");
00492 }
00493 | stores_l(r_11,cmplt) => {
00494 astr += sprintf(astr, "%s %s,", name, r_11_names[r_11]);
00495 dis_addr(cmplt);
00496 strcat(constrName, "stores_l ");
00497 }
00498 | BREAK(im5_27,im13_06) => {
00499 astr += sprintf(astr, "%s %d,%d",name, im5_27,im13_06);
00500 strcat(constrName, "BREAK ");
00501 }
00502 | sysop_i_t(im10_06,t_27) => {
00503 astr += sprintf(astr, "%s %d,%s",name, im10_06,t_27_names[t_27]);
00504 strcat(constrName, "sysop_i_t ");
00505 }
00506 | sysop_simple => {
00507 astr += sprintf(astr, "%s", name);
00508 strcat(constrName, "sysop_simple ");
00509 }
00510 | sysop_r(r_11) => {
00511 astr += sprintf(astr, "%s %s", name, r_11_names[r_11]);
00512 strcat(constrName, "sysop_r ");
00513 }
00514 | sysop_cr_t(cmplt, t_27) => {
00515 astr += sprintf(astr, "%s", name);
00516 r1 = dis_c_wcr(cmplt);
00517 astr += sprintf(astr, " %s,%s", cr_06_names[r1], t_27_names[t_27]);
00518 strcat(constrName, "sysop_cr_t ");
00519 }
00520 | MTCTL(r_11, ct_06) => {
00521 astr += sprintf(astr, "%s %s", name, ct_06_names[ct_06]);
00522
00523 strcat(constrName, "MTCTL ");
00524 }
00525 | MFIA(t_27) => {
00526 astr += sprintf(astr, "%s %s", name, t_27_names[t_27]);
00527 strcat(constrName, "MFIA ");
00528 }
00529 | LDSID(s2_16,b_06,t_27) => {
00530 astr += sprintf(astr, "%s (%s,%s),%s", name, s2_16_names[s2_16],
00531 b_06_names[b_06], t_27_names[t_27]);
00532 strcat(constrName, "LDSID ");
00533 }
00534 | MTSP(r_11,sr) => {
00535 astr += sprintf(astr, "%s %s,%s", name, r_11_names[r_11],
00536 s3_16_names[sr]);
00537 strcat(constrName, "MTSP ");
00538 }
00539 | MFSP(sr,t_27) => {
00540 astr += sprintf(astr, "%s %s,%s", name, s3_16_names[sr],
00541 t_27_names[t_27]);
00542 strcat(constrName, "MFSP ");
00543 }
00544 | cmpb_all(c_cmplt, null_cmplt, r_11, r_06, target) => {
00545 astr += sprintf(astr, "%s", name);
00546 dis_c_c(c_cmplt);
00547 dis_c_null(null_cmplt);
00548 astr += sprintf(astr, " %s,%s,0x%x", r_11_names[r_11],
00549 r_06_names[r_06], target + pc + 8);
00550 strcat(constrName, "cmpb_all ");
00551 }
00552 | cmpib_all(c_cmplt, null_cmplt, im5_11, r_06, target) => {
00553 astr += sprintf(astr, "%s", name);
00554 dis_c_c(c_cmplt);
00555 dis_c_null(null_cmplt);
00556 astr += sprintf(astr, " %d,%s,0x%x", im5_11, r_06_names[r_06],
00557 target + pc + 8);
00558 strcat(constrName, "cmpib_all ");
00559 }
00560 | bb_all(c_cmplt, null_cmplt, r_11, bit_cmplt, target) => {
00561 astr += sprintf(astr, "%s", "BB");
00562 dis_c_c(c_cmplt);
00563 dis_c_null(null_cmplt);
00564 astr += sprintf(astr, " %s,", r_11_names[r_11]);
00565 dis_c_bit(bit_cmplt);
00566 sprint(astr, ",%x", target + pc + 8);
00567 strcat(constrName, "bb_all ");
00568 }
00569 | flt_c0_all(fmt, r, t) => {
00570 astr += sprintf(astr, "%s", killDot(name));
00571 dis_flt_fmt(fmt);
00572 astr += sprintf(astr, " fr%d, fr%d", r, t);
00573 strcat(constrName, "flt_c0_all ");
00574 }
00575 | flt_c1_all(sf, df, r, t) => {
00576 astr += sprintf(astr, "%s", killDot(name));
00577 dis_flt_fmt(sf);
00578 dis_flt_fmt(df);
00579 astr += sprintf(astr, " fr%d, fr%d", r, t);
00580 strcat(constrName, "flt_c1_all ");
00581 }
00582 | flt_c2_all(fmt, c, r1, r2) => {
00583 astr += sprintf(astr, "%s", killDot(name));
00584 dis_flt_fmt(fmt);
00585 astr += sprintf(astr, " fr%d, fr%d", r1, r2);
00586
00587 astr += sprintf(astr, "\t/* Completer c needs decoding */");
00588 strcat(constrName, "flt_c2_all ");
00589 }
00590 | flt_c3_all(fmt, r1, r2, t) => {
00591 astr += sprintf(astr, "%s", killDot(name));
00592 dis_flt_fmt(fmt);
00593 astr += sprintf(astr, " fr%d, fr%d, fr%d", r1, r2, t);
00594 strcat(constrName, "flt_c3_all ");
00595 }
00596
00597
00598 | floads(c_faddr, faddr, t_27) => {
00599 astr += sprintf(astr, "%s", killDot(name));
00600 dis_c_faddr(c_faddr);
00601 astr += sprintf(astr, " ");
00602 dis_faddr(faddr);
00603 astr += sprintf(astr, ",fr%d",t_27);
00604 strcat(constrName, "floads ");
00605 }
00606 | fstores(c_faddr, r, faddr) => {
00607 astr += sprintf(astr, "%s", killDot(name));
00608 dis_c_faddr(c_faddr);
00609 astr += sprintf(astr, " fr%d", r);
00610 dis_faddr(faddr);
00611 strcat(constrName, "fstores ");
00612 }
00613
00614 else
00615 astr += sprintf(astr, "unrecog. %02X %08X",
00616 (getDword(hostPC) >> 26) & 0x3F, getDword(hostPC) & 0x03FFFFFF);
00617 endmatch
00618
00619 return 4;
00620
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630