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 #include "global.h"
00034 #include "decoder.h"
00035 #include "prog.h"
00036 #include "ss.h"
00037 #include "rtl.h"
00038 #include "proc.h"
00039 #include "csr.h"
00040 #include "mc68k.pat.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 DecodeResult& NJMCDecoder::decodeInstruction (ADDRESS pc, int delta,
00067 UserProc* proc = NULL)
00068 {
00069 static DecodeResult result;
00070 ADDRESS hostPC = pc + delta;
00071
00072
00073 result.reset();
00074
00075
00076 list<RT*>* RTs = NULL;
00077
00078
00079 int addr, locals, stackSize, d16, d32, reg;
00080 ADDRESS saveHostPC = hostPC;
00081 Logue* logue;
00082 if ((logue = InstructionPatterns::std_call(csr, hostPC, addr)) != NULL) {
00083
00084
00085
00086 HLCall* newCall = new HLCall(pc, 0, RTs);
00087 result.rtl = newCall;
00088 result.numBytes = hostPC - saveHostPC;
00089
00090
00091 newCall->setDest(addr - delta);
00092 newCall->setPrologue(logue);
00093
00094
00095
00096 SHOW_ASM("std_call "<<addr)
00097 }
00098
00099 else if ((logue = InstructionPatterns::near_call(csr, hostPC, addr))
00100 != NULL) {
00101
00102
00103
00104 HLCall* newCall = new HLCall(pc, 0, RTs);
00105 result.rtl = newCall;
00106 result.numBytes = hostPC - saveHostPC;
00107
00108
00109 newCall->setDest(addr - delta);
00110 newCall->setPrologue(logue);
00111
00112
00113
00114 SHOW_ASM("near_call " << addr)
00115 }
00116
00117 else if ((logue = InstructionPatterns::pea_pea_add_rts(csr, hostPC, d32))
00118 != NULL) {
00119
00120
00121
00122
00123 HLCall* newCall = new HLCall(pc, 0, RTs);
00124 result.rtl = newCall;
00125 result.numBytes = hostPC - saveHostPC;
00126
00127
00128
00129 newCall->setDest(pc + 10 + d32);
00130 newCall->setPrologue(logue);
00131
00132
00133
00134 SHOW_ASM("pea/pea/add/rts " << pc+10+d32)
00135 }
00136
00137 else if ((logue = InstructionPatterns::pea_add_rts(csr, hostPC, d32))
00138 != NULL) {
00139
00140
00141
00142
00143 HLCall* newCall = new HLCall(pc, 0, RTs);
00144 result.rtl = newCall;
00145 result.numBytes = hostPC - saveHostPC;
00146
00147
00148
00149 newCall->setDest(pc + 6 + d32);
00150 newCall->setPrologue(logue);
00151
00152
00153 newCall->setReturnAfterCall(true);
00154
00155
00156
00157 SHOW_ASM("pea/add/rts " << pc+6+d32)
00158 }
00159
00160 else if ((logue = InstructionPatterns::trap_syscall(csr, hostPC, d16))
00161 != NULL) {
00162
00163
00164
00165
00166 HLCall* newCall = new HLCall(pc, 0, RTs);
00167 result.rtl = newCall;
00168 result.numBytes = hostPC - saveHostPC;
00169
00170
00171 newCall->setDest(0xAAAAA000 + d16);
00172 newCall->setPrologue(logue);
00173
00174 SHOW_ASM("trap/syscall " << hex << 0xA000 + d16)
00175 }
00176
00177
00178
00179
00180 else if ((logue = InstructionPatterns::link_save(csr, hostPC,
00181 locals, d16)) != NULL)
00182 {
00183
00184
00185
00186 if (proc != NULL) {
00187
00188
00189 assert(logue->getType() == Logue::CALLEE_PROLOGUE);
00190 proc->setPrologue((CalleePrologue*)logue);
00191 }
00192 result.rtl = new RTL(pc, RTs);
00193 result.numBytes = hostPC - saveHostPC;
00194 SHOW_ASM("link_save " << locals)
00195 }
00196
00197 else if ((logue = InstructionPatterns::link_save1(csr, hostPC,
00198 locals, reg)) != NULL)
00199 {
00200
00201
00202
00203 if (proc != NULL) {
00204
00205
00206 assert(logue->getType() == Logue::CALLEE_PROLOGUE);
00207 proc->setPrologue((CalleePrologue*)logue);
00208 }
00209 result.rtl = new RTL(pc, RTs);
00210 result.numBytes = hostPC - saveHostPC;
00211 SHOW_ASM("link_save1 " << locals)
00212 }
00213
00214 else if ((logue = InstructionPatterns::push_lea(csr, hostPC,
00215 locals, reg)) != NULL)
00216 {
00217
00218
00219
00220
00221
00222 if (proc != NULL) {
00223
00224
00225 assert(logue->getType() == Logue::CALLEE_PROLOGUE);
00226 proc->setPrologue((CalleePrologue*)logue);
00227 }
00228 result.rtl = new RTL(pc, RTs);
00229 result.numBytes = hostPC - saveHostPC;
00230 SHOW_ASM("push_lea " << locals)
00231 }
00232
00233 else if ((logue = InstructionPatterns::std_link(csr, hostPC,
00234 locals)) != NULL)
00235 {
00236
00237
00238
00239 if (proc != NULL) {
00240
00241
00242 assert(logue->getType() == Logue::CALLEE_PROLOGUE);
00243 proc->setPrologue((CalleePrologue*)logue);
00244 }
00245 result.rtl = new RTL(pc, RTs);
00246 result.numBytes = hostPC - saveHostPC;
00247 SHOW_ASM("std_link "<< locals)
00248 }
00249
00250 else if ((logue = InstructionPatterns::bare_ret(csr, hostPC))
00251 != NULL)
00252 {
00253
00254
00255
00256 if (proc != NULL) {
00257
00258
00259 assert(logue->getType() == Logue::CALLEE_PROLOGUE);
00260 proc->setPrologue((CalleePrologue*)logue);
00261 proc->setEpilogue(new CalleeEpilogue("__dummy",list<string>()));
00262 }
00263 result.rtl = new HLReturn(pc, RTs);
00264 result.numBytes = hostPC - saveHostPC;
00265 SHOW_ASM("bare_ret")
00266 }
00267
00268 else if ((logue = InstructionPatterns::std_ret(csr, hostPC)) != NULL) {
00269
00270
00271
00272 if (proc!= NULL) {
00273
00274
00275 assert(logue->getType() == Logue::CALLEE_EPILOGUE);
00276 proc->setEpilogue((CalleeEpilogue*)logue);
00277 }
00278
00279 result.rtl = new HLReturn(pc, RTs);
00280 result.numBytes = hostPC - saveHostPC;
00281 SHOW_ASM("std_ret")
00282 }
00283
00284 else if ((logue = InstructionPatterns::rest_ret(csr, hostPC, d16)) != NULL)
00285 {
00286
00287
00288
00289 if (proc!= NULL) {
00290
00291
00292 assert(logue->getType() == Logue::CALLEE_EPILOGUE);
00293 proc->setEpilogue((CalleeEpilogue*)logue);
00294 }
00295
00296 result.rtl = new HLReturn(pc, RTs);
00297 result.numBytes = hostPC - saveHostPC;
00298 SHOW_ASM("rest_ret")
00299 }
00300
00301 else if ((logue = InstructionPatterns::rest1_ret(csr, hostPC, reg)) != NULL)
00302 {
00303
00304
00305
00306 if (proc!= NULL) {
00307
00308
00309 assert(logue->getType() == Logue::CALLEE_EPILOGUE);
00310 proc->setEpilogue((CalleeEpilogue*)logue);
00311 }
00312
00313 result.rtl = new HLReturn(pc, RTs);
00314 result.numBytes = hostPC - saveHostPC;
00315 SHOW_ASM("rest1_ret")
00316 }
00317
00318 else if ((logue = InstructionPatterns::pop_ret(csr, hostPC, reg)) != NULL)
00319 {
00320
00321
00322
00323 if (proc!= NULL) {
00324
00325
00326 assert(logue->getType() == Logue::CALLEE_EPILOGUE);
00327 proc->setEpilogue((CalleeEpilogue*)logue);
00328 }
00329
00330 result.rtl = new HLReturn(pc, RTs);
00331 result.numBytes = hostPC - saveHostPC;
00332 SHOW_ASM("pop_ret")
00333 }
00334
00335 else if ((logue = InstructionPatterns::clear_stack(csr, hostPC, stackSize))
00336 != NULL)
00337 {
00338
00339
00340
00341 RTs = instantiate(pc, "clear_stack", dis_Num(stackSize));
00342
00343 result.rtl = new RTL(pc, RTs);
00344 result.numBytes = hostPC - saveHostPC;
00345 }
00346
00347 else {
00348
00349 ADDRESS nextPC;
00350 int bump = 0, bumpr;
00351 SemStr* ss;
00352
00353 match hostPC to
00354
00355 | regCall(ea) =>
00356
00357
00358
00359
00360 HLCall* newCall = new HLCall(pc, 0, RTs);
00361
00362 newCall->setIsComputed();
00363
00364 newCall->setDest(cEA(ea, pc, 32));
00365 result.rtl = newCall;
00366
00367 result.numBytes = nextPC - hostPC;
00368
00369 | regJmp(ea) =>
00370
00371
00372
00373 HLNwayJump* newJump = new HLNwayJump(pc, RTs);
00374
00375 newJump->setIsComputed();
00376
00377 newJump->setDest(cEA(ea, pc, 32));
00378 result.rtl = newJump;
00379
00380 result.numBytes = nextPC - hostPC;
00381
00382
00383
00384
00385 | bra(d) =>
00386 ss = BTA(d, result, pc);
00387 UNCOND_JUMP(name, nextPC - hostPC, ss);
00388
00389
00390
00391
00392 | bgt(d) =>
00393 ss = BTA(d, result, pc);
00394 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JSG)
00395 | ble(d) =>
00396 ss = BTA(d, result, pc);
00397 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JSLE)
00398 | bge(d) =>
00399 ss = BTA(d, result, pc);
00400 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JSGE)
00401 | blt(d) =>
00402 ss = BTA(d, result, pc);
00403 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JSL)
00404 | bpl(d) =>
00405 ss = BTA(d, result, pc);
00406 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JPOS)
00407 | bmi(d) =>
00408 ss = BTA(d, result, pc);
00409 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JMI)
00410 | bhi(d) =>
00411 ss = BTA(d, result, pc);
00412 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JUG)
00413 | bls(d) =>
00414 ss = BTA(d, result, pc);
00415 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JULE)
00416 | bne(d) =>
00417 ss = BTA(d, result, pc);
00418 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JNE)
00419 | beq(d) =>
00420 ss = BTA(d, result, pc);
00421 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JE)
00422 | bcc(d) =>
00423 ss = BTA(d, result, pc);
00424 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JUGE)
00425 | bcs(d) =>
00426 ss = BTA(d, result, pc);
00427 COND_JUMP(name, nextPC - hostPC, ss, HLJCOND_JUL)
00428 | bvc(d) =>
00429 ss = BTA(d, result, pc);
00430 COND_JUMP(name, nextPC - hostPC, ss, (JCOND_TYPE)0)
00431 | bvs(d) =>
00432 ss = BTA(d, result, pc);
00433 COND_JUMP(name, nextPC - hostPC, ss, (JCOND_TYPE)0)
00434
00435
00436
00437
00438
00439
00440 | shi(ea) =>
00441 ss = daEA(ea, pc, bump, bumpr, 1);
00442 RTs = instantiate(pc, name, ss);
00443 SETS(name, ss, HLJCOND_JSG)
00444 | sls(ea) =>
00445 ss = daEA(ea, pc, bump, bumpr, 1);
00446 RTs = instantiate(pc, name, ss);
00447 SETS(name, ss, HLJCOND_JULE)
00448 | scc(ea) =>
00449 ss = daEA(ea, pc, bump, bumpr, 1);
00450 RTs = instantiate(pc, name, ss);
00451 SETS(name, ss, HLJCOND_JUGE)
00452 | scs(ea) =>
00453 ss = daEA(ea, pc, bump, bumpr, 1);
00454 RTs = instantiate(pc, name, ss);
00455 SETS(name, ss, HLJCOND_JUL)
00456 | sne(ea) =>
00457 ss = daEA(ea, pc, bump, bumpr, 1);
00458 RTs = instantiate(pc, name, ss);
00459 SETS(name, ss, HLJCOND_JNE)
00460 | seq(ea) =>
00461 ss = daEA(ea, pc, bump, bumpr, 1);
00462 RTs = instantiate(pc, name, ss);
00463 SETS(name, ss, HLJCOND_JE)
00464
00465
00466
00467
00468
00469
00470
00471
00472 | spl(ea) =>
00473 ss = daEA(ea, pc, bump, bumpr, 1);
00474 RTs = instantiate(pc, name, ss);
00475 SETS(name, ss, HLJCOND_JPOS)
00476 | smi(ea) =>
00477 ss = daEA(ea, pc, bump, bumpr, 1);
00478 RTs = instantiate(pc, name, ss);
00479 SETS(name, ss, HLJCOND_JMI)
00480 | sge(ea) =>
00481 ss = daEA(ea, pc, bump, bumpr, 1);
00482 RTs = instantiate(pc, name, ss);
00483 SETS(name, ss, HLJCOND_JSGE)
00484 | slt(ea) =>
00485 ss = daEA(ea, pc, bump, bumpr, 1);
00486 RTs = instantiate(pc, name, ss);
00487 SETS(name, ss, HLJCOND_JSL)
00488 | sgt(ea) =>
00489 ss = daEA(ea, pc, bump, bumpr, 1);
00490 RTs = instantiate(pc, name, ss);
00491 SETS(name, ss, HLJCOND_JSG)
00492 | sle(ea) =>
00493 ss = daEA(ea, pc, bump, bumpr, 1);
00494 RTs = instantiate(pc, name, ss);
00495 SETS(name, ss, HLJCOND_JSLE)
00496
00497
00498 else
00499 result.rtl = new RTL(pc,
00500 decodeLowLevelInstruction(hostPC, pc, result));
00501 endmatch
00502 }
00503 return result;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 SemStr* NJMCDecoder::BTA(ADDRESS d, DecodeResult& result, ADDRESS pc)
00535 {
00536
00537 SemStr* ret = new SemStr(32);
00538 ret->push(idIntConst);
00539
00540 match d to
00541
00542 | wordOffset (dsp16) => {
00543 ret->push(pc+2 + dsp16);
00544 result.numBytes += 2;
00545 }
00546
00547 | byteOffset (dsp8) => {
00548
00549 ret->push(pc+2 + (int)(char)dsp8);
00550 }
00551 endmatch
00552
00553 return ret;
00554 }
00555
00556
00557 void NJMCDecoder::pIllegalMode(ADDRESS pc)
00558 {
00559 ostrstream ost;
00560 ost << "Illegal addressing mode at " << hex << pc;
00561 error(str(ost));
00562 }
00563
00564 SemStr* NJMCDecoder::pDDirect(int r2, int size)
00565 {
00566 SemStr* ret = new SemStr(size);
00567 ret->push(idRegOf);
00568 ret->push(idIntConst);
00569 ret->push(r2);
00570 return ret;
00571 }
00572
00573 SemStr* NJMCDecoder::pADirect(int r2, int size)
00574 {
00575 SemStr* ret = new SemStr(size);
00576 ret->push(idRegOf);
00577 ret->push(idIntConst);
00578 ret->push(r2 + 8);
00579 return ret;
00580 }
00581
00582 SemStr* NJMCDecoder::pIndirect(int r2, int size)
00583 {
00584 SemStr* ret = new SemStr(size);
00585 ret->push(idMemOf);
00586 ret->push(idRegOf);
00587 ret->push(idIntConst);
00588 ret->push(r2 + 8);
00589 return ret;
00590 }
00591
00592 SemStr* NJMCDecoder::pPostInc(int r2, int& bump, int& bumpr, int size)
00593 {
00594
00595
00596
00597 if ((r2 == 7) && (size == 8)) size = 16;
00598 SemStr* ret = new SemStr(size/8);
00599 ret->push(idMemOf);
00600 ret->push(idRegOf);
00601 ret->push(idIntConst);
00602 ret->push(r2 + 8);
00603 bump = size/8;
00604 bumpr = r2 + 8;
00605 return ret;
00606 }
00607
00608 SemStr* NJMCDecoder::pPreDec(int r2, int& bump, int& bumpr, int size)
00609 {
00610
00611
00612
00613 if ((r2 == 7) && (size == 8)) size = 16;
00614 SemStr* ret = new SemStr(size);
00615 ret->push(idMemOf); ret->push(idPlus);
00616 ret->push(idRegOf);
00617 ret->push(idIntConst);
00618 ret->push(r2 + 8);
00619 ret->push(idIntConst); ret->push(-size/8);
00620 bump = -size/8;
00621 bumpr = r2 + 8;
00622 return ret;
00623 }
00624
00625 SemStr* NJMCDecoder::alEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00626 int size)
00627 {
00628 SemStr* ret = new SemStr(size);
00629 match ea to
00630 | alDDirect (reg2) => ret = pDDirect(reg2, size);
00631 | alADirect (reg2) => ret = pADirect(reg2, size);
00632 | alIndirect (reg2) => ret = pIndirect(reg2, size);
00633 | alPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00634 | alPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00635 else pIllegalMode(pc);
00636 endmatch
00637 return ret;
00638 }
00639
00640 SemStr* NJMCDecoder::amEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00641 int size)
00642 {
00643 SemStr* ret = new SemStr(size);
00644 match ea to
00645 | amDDirect (reg2) => ret = pDDirect(reg2, size);
00646 | amADirect (reg2) => ret = pADirect(reg2, size);
00647 | amIndirect (reg2) => ret = pIndirect(reg2, size);
00648 | amPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00649 | amPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00650 else pIllegalMode(pc);
00651 endmatch
00652 return ret;
00653 }
00654
00655 SemStr* NJMCDecoder::awlEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00656 int size)
00657 {
00658 SemStr* ret = new SemStr(size);
00659 match ea to
00660 | awlDDirect (reg2) => ret = pDDirect(reg2, size);
00661 | awlADirect (reg2) => ret = pADirect(reg2, size);
00662 | awlIndirect (reg2) => ret = pIndirect(reg2, size);
00663 | awlPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00664 | awlPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00665 else pIllegalMode(pc);
00666 endmatch
00667 return ret;
00668 }
00669
00670 SemStr* NJMCDecoder::cEA(ADDRESS ea, ADDRESS pc, int size)
00671 {
00672 SemStr* ret = new SemStr(size);
00673 match ea to
00674 | cIndirect (reg2) => ret = pIndirect(reg2, size);
00675 else pIllegalMode(pc);
00676 endmatch
00677 return ret;
00678 }
00679
00680 SemStr* NJMCDecoder::dEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00681 int size)
00682 {
00683 SemStr* ret = new SemStr(size);
00684 match ea to
00685 | dDDirect (reg2) => ret = pDDirect(reg2, size);
00686 | dIndirect (reg2) => ret = pIndirect(reg2, size);
00687 | dPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00688 | dPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00689 else pIllegalMode(pc);
00690 endmatch
00691 return ret;
00692 }
00693
00694 SemStr* NJMCDecoder::daEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00695 int size)
00696 {
00697 SemStr* ret = new SemStr(size);
00698 match ea to
00699 | daDDirect (reg2) => ret = pDDirect(reg2, size);
00700 | daIndirect (reg2) => ret = pIndirect(reg2, size);
00701 | daPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00702 | daPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00703 else pIllegalMode(pc);
00704 endmatch
00705 return ret;
00706 }
00707
00708 SemStr* NJMCDecoder::dBEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00709 int size)
00710 {
00711 SemStr* ret = new SemStr(size);
00712 match ea to
00713 | dBDDirect (reg2) => ret = pDDirect(reg2, size);
00714 | dBIndirect (reg2) => ret = pIndirect(reg2, size);
00715 | dBPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00716 | dBPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00717 else pIllegalMode(pc);
00718 endmatch
00719 return ret;
00720 }
00721
00722 SemStr* NJMCDecoder::dWEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00723 int size)
00724 {
00725 SemStr* ret = new SemStr(size);
00726 match ea to
00727 | dWDDirect (reg2) => ret = pDDirect(reg2, size);
00728 | dWIndirect (reg2) => ret = pIndirect(reg2, size);
00729 | dWPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00730 | dWPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00731 else pIllegalMode(pc);
00732 endmatch
00733 return ret;
00734 }
00735
00736 SemStr* NJMCDecoder::maEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00737 int size)
00738 {
00739 SemStr* ret = new SemStr(size);
00740 match ea to
00741 | maIndirect (reg2) => ret = pIndirect(reg2, size);
00742 | maPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00743 | maPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00744 else pIllegalMode(pc);
00745 endmatch
00746 return ret;
00747 }
00748
00749 SemStr* NJMCDecoder::msEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00750 int size)
00751 {
00752 SemStr* ret = new SemStr(size);
00753 match ea to
00754 | msDDirect (reg2) => ret = pDDirect(reg2, size);
00755 | msADirect (reg2) => ret = pADirect(reg2, size);
00756 | msIndirect (reg2) => ret = pIndirect(reg2, size);
00757 | msPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00758 | msPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00759 else pIllegalMode(pc);
00760 endmatch
00761 return ret;
00762 }
00763
00764 SemStr* NJMCDecoder::mdEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00765 int size)
00766 {
00767 SemStr* ret = new SemStr(size);
00768 match ea to
00769 | mdDDirect (reg1) => ret = pDDirect(reg1, size);
00770 | mdADirect (reg1) => ret = pADirect(reg1, size);
00771 | mdIndirect (reg1) => ret = pIndirect(reg1, size);
00772 | mdPostInc (reg1) => ret = pPostInc(reg1, bump, bumpr, size);
00773 | mdPreDec (reg1) => ret = pPreDec(reg1, bump, bumpr, size);
00774 else pIllegalMode(pc);
00775 endmatch
00776 return ret;
00777 }
00778
00779 SemStr* NJMCDecoder::mrEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00780 int size)
00781 {
00782 SemStr* ret = new SemStr(size);
00783 match ea to
00784 | mrIndirect (reg2) => ret = pIndirect(reg2, size);
00785 | mrPostInc (reg2) => ret = pPostInc(reg2, bump, bumpr, size);
00786 else pIllegalMode(pc);
00787 endmatch
00788 return ret;
00789 }
00790
00791 SemStr* NJMCDecoder::rmEA(ADDRESS ea, ADDRESS pc, int& bump, int& bumpr,
00792 int size)
00793 {
00794 SemStr* ret = new SemStr(size);
00795 match ea to
00796 | rmIndirect (reg2) => ret = pIndirect(reg2, size);
00797 | rmPreDec (reg2) => ret = pPreDec(reg2, bump, bumpr, size);
00798 else pIllegalMode(pc);
00799 endmatch
00800 return ret;
00801 }
00802
00803
00804 SemStr* NJMCDecoder::pADisp(int d16, int r, int size)
00805 {
00806 SemStr* ret = new SemStr(size);
00807
00808 ret->push(idMemOf); ret->push(idPlus); ret->push(idRegOf);
00809 ret->push(idIntConst); ret->push(r+8);
00810 ret->push(idIntConst); ret->push(d16);
00811 return ret;
00812 }
00813
00814 SemStr* NJMCDecoder::pAIndex(int d8, int r, int iT, int iR, int iS, int size)
00815 {
00816 SemStr* ret = new SemStr(size);
00817
00818
00819 ret->push(idMemOf); ret->push(idPlus); ret->push(idPlus);
00820 ret->push(idRegOf); ret->push(idIntConst); ret->push(r+8);
00821 ret->push(idSignExt);
00822 ret->push(idSize); ret->push(iS == 0 ? 16 : 32);
00823 ret->push(idRegOf); ret->push(idIntConst); ret->push((iT<<3) + iR);
00824 ret->push(idIntConst); ret->push(d8);
00825 return ret;
00826 }
00827
00828 SemStr* NJMCDecoder::pPcDisp(ADDRESS label, int delta, int size)
00829 {
00830
00831 SemStr* ret = new SemStr(size);
00832
00833
00834
00835
00836 ret->push(idMemOf); ret->push(idCodeAddr);
00837 ret->push(label - delta);
00838 return ret;
00839 }
00840
00841 SemStr* NJMCDecoder::pPcIndex(int d8, int iT, int iR, int iS, ADDRESS nextPc, int size)
00842 {
00843
00844 SemStr* ret = new SemStr(size);
00845
00846
00847 ret->push(idMemOf); ret->push(idPlus);
00848 ret->push(idIntConst); ret->push(nextPc+d8);
00849 ret->push(idSignExt);
00850 ret->push(idSize); ret->push(iS == 0 ? 16 : 32);
00851 ret->push(idRegOf); ret->push(idIntConst); ret->push((iT<<3) + iR);
00852 return ret;
00853 }
00854
00855 SemStr* NJMCDecoder::pAbsW(int d16, int size)
00856 {
00857
00858
00859 SemStr* ret = new SemStr(size);
00860 ret->push(idSize); ret->push(size);
00861 ret->push(idMemOf); ret->push(idIntConst); ret->push(d16);
00862 return ret;
00863 }
00864
00865 SemStr* NJMCDecoder::pAbsL(int d32, int size)
00866 {
00867
00868 SemStr* ret = new SemStr(size);
00869 ret->push(idSize); ret->push(size);
00870 ret->push(idMemOf); ret->push(idIntConst); ret->push(d32);
00871 return ret;
00872 }
00873
00874 SemStr* NJMCDecoder::pImmB(int d8)
00875 {
00876
00877
00878 SemStr* ret = new SemStr(8);
00879 ret->push(idIntConst); ret->push(d8);
00880 return ret;
00881 }
00882
00883 SemStr* NJMCDecoder::pImmW(int d16)
00884 {
00885
00886
00887 SemStr* ret = new SemStr(16);
00888 ret->push(idIntConst); ret->push(d16);
00889 return ret;
00890 }
00891
00892 SemStr* NJMCDecoder::pImmL(int d32)
00893 {
00894 SemStr* ret = new SemStr(32);
00895 ret->push(idIntConst); ret->push(d32);
00896 return ret;
00897 }
00898
00899 void NJMCDecoder::pNonzeroByte(ADDRESS pc)
00900 {
00901 ostrstream ost;
00902 ost << "Non zero upper byte at " << hex << pc;
00903 error(str(ost));
00904 }
00905
00906
00907 SemStr* NJMCDecoder::alEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
00908 ADDRESS pc, int size)
00909 {
00910 SemStr* ret;
00911 int reg2, mode;
00912
00913 match eax to
00914 | alADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
00915 | alAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
00916 | alAbs.w () => { mode = 4; result.numBytes += 2;}
00917 | alAbs.l () => { mode = 5; result.numBytes += 4;}
00918 else pIllegalMode(pc);
00919 endmatch
00920
00921 switch (mode) {
00922 case 0 : {
00923 match x to
00924 | alADisp.x (d16) => ret = pADisp(d16, reg2, size);
00925 endmatch
00926 break;
00927 }
00928 case 1 : {
00929 match x to
00930 | alAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
00931 endmatch
00932 break;
00933 }
00934 case 4 : {
00935 match x to
00936 | alAbs.w.x (d16) => ret = pAbsW(d16, size);
00937 endmatch
00938 break;
00939 }
00940 case 5 : {
00941 match x to
00942 | alAbs.l.x (d32) => ret = pAbsL(d32, size);
00943 endmatch
00944 break;
00945 }
00946 default : pIllegalMode(pc); break;
00947 }
00948 return ret;
00949 }
00950
00951
00952 SemStr* NJMCDecoder::amEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
00953 ADDRESS pc, int delta, int size)
00954 {
00955 SemStr* ret;
00956 int reg2, mode;
00957
00958 match eax to
00959 | amADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
00960 | amAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
00961 | amPcDisp () => { mode = 2; result.numBytes += 2;}
00962 | amPcIndex () => { mode = 3; result.numBytes += 2;}
00963 | amAbs.w () => { mode = 4; result.numBytes += 2;}
00964 | amAbs.l () => { mode = 5; result.numBytes += 4;}
00965 | amImm.b () => { mode = 6; result.numBytes += 2;}
00966 | amImm.w () => { mode = 7; result.numBytes += 2;}
00967 | amImm.l () => { mode = 8; result.numBytes += 4;}
00968 else pIllegalMode(pc);
00969 endmatch
00970
00971 switch (mode) {
00972 case 0 : {
00973 match x to
00974 | amADisp.x (d16) => ret = pADisp(d16, reg2, size);
00975 endmatch
00976 break;
00977 }
00978 case 1 : {
00979 match x to
00980 | amAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
00981 endmatch
00982 break;
00983 }
00984 case 2 : {
00985 match x to
00986 | amPcDisp.x (d16) => ret = pPcDisp(d16, delta, size);
00987 endmatch
00988 break;
00989 }
00990 case 3 : {
00991 match x to
00992 | amPcIndex.x (iT, iR, iS, d8) =>
00993 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
00994 endmatch
00995 break;
00996 }
00997 case 4 : {
00998 match x to
00999 | amAbs.w.x (d16) => ret = pAbsW(d16, size);
01000 endmatch
01001 break;
01002 }
01003 case 5 : {
01004 match x to
01005 | amAbs.l.x (d32) => ret = pAbsL(d32, size);
01006 endmatch
01007 break;
01008 }
01009 case 6 : {
01010 match x to
01011 | amImm.b.x (d8) => ret = pImmB(d8);
01012 else pNonzeroByte(pc);
01013 endmatch
01014 break;
01015 }
01016 case 7 : {
01017 match x to
01018 | amImm.w.x (d16) => ret = pImmW(d16);
01019 endmatch
01020 break;
01021 }
01022 case 8 : {
01023 match x to
01024 | amImm.l.x (d32) => ret = pImmL(d32);
01025 endmatch
01026 break;
01027 }
01028 default : pIllegalMode(pc); break;
01029 }
01030 return ret;
01031 }
01032
01033
01034 SemStr* NJMCDecoder::awlEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01035 ADDRESS pc, int delta, int size)
01036 {
01037 SemStr* ret;
01038 int reg2, mode;
01039
01040 match eax to
01041 | awlADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01042 | awlAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01043 | awlPcDisp () => { mode = 2; result.numBytes += 2;}
01044 | awlPcIndex () => { mode = 3; result.numBytes += 2;}
01045 | awlAbs.w () => { mode = 4; result.numBytes += 2;}
01046 | awlAbs.l () => { mode = 5; result.numBytes += 4;}
01047 | awlImm.w () => { mode = 7; result.numBytes += 2;}
01048 | awlImm.l () => { mode = 8; result.numBytes += 4;}
01049 else pIllegalMode(pc);
01050 endmatch
01051
01052 switch (mode) {
01053 case 0 : {
01054 match x to
01055 | awlADisp.x (d16) => ret = pADisp(d16, reg2, size);
01056 endmatch
01057 break;
01058 }
01059 case 1 : {
01060 match x to
01061 | awlAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01062 endmatch
01063 break;
01064 }
01065 case 2 : {
01066 match x to
01067 | awlPcDisp.x (d16) => ret = pPcDisp(d16, delta, size);
01068 endmatch
01069 break;
01070 }
01071 case 3 : {
01072 match x to
01073 | awlPcIndex.x (iT, iR, iS, d8) =>
01074 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01075 endmatch
01076 break;
01077 }
01078 case 4 : {
01079 match x to
01080 | awlAbs.w.x (d16) => ret = pAbsW(d16, size);
01081 endmatch
01082 break;
01083 }
01084 case 5 : {
01085 match x to
01086 | awlAbs.l.x (d32) => ret = pAbsL(d32, size);
01087 endmatch
01088 break;
01089 }
01090 case 7 : {
01091 match x to
01092 | awlImm.w.x (d16) => ret = pImmW(d16);
01093 endmatch
01094 break;
01095 }
01096 case 8 : {
01097 match x to
01098 | awlImm.l.x (d32) => ret = pImmL(d32);
01099 endmatch
01100 break;
01101 }
01102 default : pIllegalMode(pc); break;
01103 }
01104 return ret;
01105 }
01106
01107
01108 SemStr* NJMCDecoder::cEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01109 ADDRESS pc, int delta, int size)
01110 {
01111 SemStr* ret;
01112 int reg2, mode;
01113
01114 match eax to
01115 | cADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01116 | cAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01117 | cPcDisp () => { mode = 2; result.numBytes += 2;}
01118 | cPcIndex () => { mode = 3; result.numBytes += 2;}
01119 | cAbs.w () => { mode = 4; result.numBytes += 2;}
01120 | cAbs.l () => { mode = 5; result.numBytes += 4;}
01121 else pIllegalMode(pc);
01122 endmatch
01123
01124 switch (mode) {
01125 case 0 : {
01126 match x to
01127 | cADisp.x (d16) => ret = pADisp(d16, reg2, size);
01128 endmatch
01129 break;
01130 }
01131 case 1 : {
01132 match x to
01133 | cAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01134 endmatch
01135 break;
01136 }
01137 case 2 : {
01138 match x to
01139 | cPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01140 endmatch
01141 break;
01142 }
01143 case 3 : {
01144 match x to
01145 | cPcIndex.x (iT, iR, iS, d8) => ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01146 endmatch
01147 break;
01148 }
01149 case 4 : {
01150 match x to
01151 | cAbs.w.x (d16) => ret = pAbsW(d16, size);
01152 endmatch
01153 break;
01154 }
01155 case 5 : {
01156 match x to
01157 | cAbs.l.x (d32) => ret = pAbsL(d32, size);
01158 endmatch
01159 break;
01160 }
01161 default : pIllegalMode(pc); break;
01162 }
01163 return ret;
01164 }
01165
01166
01167 SemStr* NJMCDecoder::dEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01168 ADDRESS pc, int delta, int size)
01169 {
01170 SemStr* ret;
01171 int reg2, mode;
01172
01173 match eax to
01174 | dADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01175 | dAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01176 | dPcDisp () => { mode = 2; result.numBytes += 2;}
01177 | dPcIndex () => { mode = 3; result.numBytes += 2;}
01178 | dAbs.w () => { mode = 4; result.numBytes += 2;}
01179 | dAbs.l () => { mode = 5; result.numBytes += 4;}
01180 | dImm.b () => { mode = 6; result.numBytes += 2;}
01181 | dImm.w () => { mode = 7; result.numBytes += 2;}
01182 | dImm.l () => { mode = 8; result.numBytes += 4;}
01183 else pIllegalMode(pc);
01184 endmatch
01185
01186 switch (mode) {
01187 case 0 : {
01188 match x to
01189 | dADisp.x (d16) => ret = pADisp(d16, reg2, size);
01190 endmatch
01191 break;
01192 }
01193 case 1 : {
01194 match x to
01195 | dAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01196 endmatch
01197 break;
01198 }
01199 case 2 : {
01200 match x to
01201 | dPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01202 endmatch
01203 break;
01204 }
01205 case 3 : {
01206 match x to
01207 | dPcIndex.x (iT, iR, iS, d8) => ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01208 endmatch
01209 break;
01210 }
01211 case 4 : {
01212 match x to
01213 | dAbs.w.x (d16) => ret = pAbsW(d16, size);
01214 endmatch
01215 break;
01216 }
01217 case 5 : {
01218 match x to
01219 | dAbs.l.x (d32) => ret = pAbsL(d32, size);
01220 endmatch
01221 break;
01222 }
01223 case 6 : {
01224 match x to
01225 | dImm.b.x (d8) => ret = pImmB(d8);
01226 else pNonzeroByte(pc);
01227 endmatch
01228 break;
01229 }
01230 case 7 : {
01231 match x to
01232 | dImm.w.x (d16) => ret = pImmW(d16);
01233 endmatch
01234 break;
01235 }
01236 case 8 : {
01237 match x to
01238 | dImm.l.x (d32) => ret = pImmL(d32);
01239 endmatch
01240 break;
01241 }
01242 default : pIllegalMode(pc); break;
01243 }
01244 return ret;
01245 }
01246
01247
01248 SemStr* NJMCDecoder::daEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01249 ADDRESS pc, int size)
01250 {
01251 SemStr* ret;
01252 int reg2, mode;
01253
01254 match eax to
01255 | daADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01256 | daAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01257 | daAbs.w () => { mode = 4; result.numBytes += 2;}
01258 | daAbs.l () => { mode = 5; result.numBytes += 4;}
01259 else pIllegalMode(pc);
01260 endmatch
01261
01262 switch (mode) {
01263 case 0 : {
01264 match x to
01265 | daADisp.x (d16) => ret = pADisp(d16, reg2, size);
01266 endmatch
01267 break;
01268 }
01269 case 1 : {
01270 match x to
01271 | daAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01272 endmatch
01273 break;
01274 }
01275 case 4 : {
01276 match x to
01277 | daAbs.w.x (d16) => ret = pAbsW(d16, size);
01278 endmatch
01279 break;
01280 }
01281 case 5 : {
01282 match x to
01283 | daAbs.l.x (d32) => ret = pAbsL(d32, size);
01284 endmatch
01285 break;
01286 }
01287 default : pIllegalMode(pc); break;
01288 }
01289 return ret;
01290 }
01291
01292
01293 SemStr* NJMCDecoder::dBEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01294 ADDRESS pc, int delta, int size)
01295 {
01296 SemStr* ret;
01297 int reg2, mode;
01298
01299 match eax to
01300 | dBADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01301 | dBAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01302 | dBPcDisp () => { mode = 2; result.numBytes += 2;}
01303 | dBPcIndex () => { mode = 3; result.numBytes += 2;}
01304 | dBAbs.w () => { mode = 4; result.numBytes += 2;}
01305 | dBAbs.l () => { mode = 5; result.numBytes += 4;}
01306 | dBImm.b () => { mode = 6; result.numBytes += 2;}
01307 else pIllegalMode(pc);
01308 endmatch
01309
01310 switch (mode) {
01311 case 0 : {
01312 match x to
01313 | dBADisp.x (d16) => ret = pADisp(d16, reg2, size);
01314 endmatch
01315 break;
01316 }
01317 case 1 : {
01318 match x to
01319 | dBAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01320 endmatch
01321 break;
01322 }
01323 case 2 : {
01324 match x to
01325 | dBPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01326 endmatch
01327 break;
01328 }
01329 case 3 : {
01330 match x to
01331 | dBPcIndex.x (iT, iR, iS, d8) =>
01332 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01333 endmatch
01334 break;
01335 }
01336 case 4 : {
01337 match x to
01338 | dBAbs.w.x (d16) => ret = pAbsW(d16, size);
01339 endmatch
01340 break;
01341 }
01342 case 5 : {
01343 match x to
01344 | dBAbs.l.x (d32) => ret = pAbsL(d32, size);
01345 endmatch
01346 break;
01347 }
01348 case 6 : {
01349 match x to
01350 | dImm.b.x (d8) => ret = pImmB(d8);
01351 else pNonzeroByte(pc);
01352 endmatch
01353 break;
01354 }
01355 default : pIllegalMode(pc); break;
01356 }
01357 return ret;
01358 }
01359
01360
01361 SemStr* NJMCDecoder::dWEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01362 ADDRESS pc, int delta, int size)
01363 {
01364 SemStr* ret;
01365 int reg2, mode;
01366
01367 match eax to
01368 | dWADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01369 | dWAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01370 | dWPcDisp () => { mode = 2; result.numBytes += 2;}
01371 | dWPcIndex () => { mode = 3; result.numBytes += 2;}
01372 | dWAbs.w () => { mode = 4; result.numBytes += 2;}
01373 | dWAbs.l () => { mode = 5; result.numBytes += 4;}
01374 | dWImm.w () => { mode = 7; result.numBytes += 2;}
01375 else pIllegalMode(pc);
01376 endmatch
01377
01378 switch (mode) {
01379 case 0 : {
01380 match x to
01381 | dWADisp.x (d16) => ret = pADisp(d16, reg2, size);
01382 endmatch
01383 break;
01384 }
01385 case 1 : {
01386 match x to
01387 | dWAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01388 endmatch
01389 break;
01390 }
01391 case 2 : {
01392 match x to
01393 | dWPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01394 endmatch
01395 break;
01396 }
01397 case 3 : {
01398 match x to
01399 | dWPcIndex.x (iT, iR, iS, d8) =>
01400 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01401 endmatch
01402 break;
01403 }
01404 case 4 : {
01405 match x to
01406 | dWAbs.w.x (d16) => ret = pAbsW(d16, size);
01407 endmatch
01408 break;
01409 }
01410 case 5 : {
01411 match x to
01412 | dWAbs.l.x (d32) => ret = pAbsL(d32, size);
01413 endmatch
01414 break;
01415 }
01416 case 7 : {
01417 match x to
01418 | dWImm.w.x (d16) => ret = pImmW(d16);
01419 endmatch
01420 break;
01421 }
01422 default : pIllegalMode(pc); break;
01423 }
01424 return ret;
01425 }
01426
01427
01428 SemStr* NJMCDecoder::maEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01429 ADDRESS pc, int size)
01430 {
01431 SemStr* ret;
01432 int reg2, mode;
01433
01434 match eax to
01435 | maADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01436 | maAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01437 | maAbs.w () => { mode = 4; result.numBytes += 2;}
01438 | maAbs.l () => { mode = 5; result.numBytes += 4;}
01439 else pIllegalMode(pc);
01440 endmatch
01441
01442 switch (mode) {
01443 case 0 : {
01444 match x to
01445 | maADisp.x (d16) => ret = pADisp(d16, reg2, size);
01446 endmatch
01447 break;
01448 }
01449 case 1 : {
01450 match x to
01451 | maAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01452 endmatch
01453 break;
01454 }
01455 case 4 : {
01456 match x to
01457 | maAbs.w.x (d16) => ret = pAbsW(d16, size);
01458 endmatch
01459 break;
01460 }
01461 case 5 : {
01462 match x to
01463 | maAbs.l.x (d32) => ret = pAbsL(d32, size);
01464 endmatch
01465 break;
01466 }
01467 default : pIllegalMode(pc); break;
01468 }
01469 return ret;
01470 }
01471
01472
01473 SemStr* NJMCDecoder::msEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01474 ADDRESS pc, int delta, int size)
01475 {
01476 SemStr* ret;
01477 int reg2, mode;
01478
01479 match eax to
01480 | msADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01481 | msAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01482 | msPcDisp () => { mode = 2; result.numBytes += 2;}
01483 | msPcIndex () => { mode = 3; result.numBytes += 2;}
01484 | msAbs.w () => { mode = 4; result.numBytes += 2;}
01485 | msImm.b () => { mode = 6; result.numBytes += 2;}
01486 | msImm.w () => { mode = 7; result.numBytes += 2;}
01487 else pIllegalMode(pc);
01488 endmatch
01489
01490 switch (mode) {
01491 case 0 : {
01492 match x to
01493 | msADisp.x (d16) => ret = pADisp(d16, reg2, size);
01494 endmatch
01495 break;
01496 }
01497 case 1 : {
01498 match x to
01499 | msAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01500 endmatch
01501 break;
01502 }
01503 case 2 : {
01504 match x to
01505 | msPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01506 endmatch
01507 break;
01508 }
01509 case 3 : {
01510 match x to
01511 | msPcIndex.x (iT, iR, iS, d8) =>
01512 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01513 endmatch
01514 break;
01515 }
01516 case 4 : {
01517 match x to
01518 | msAbs.w.x (d16) => ret = pAbsW(d16, size);
01519 endmatch
01520 break;
01521 }
01522 case 6 : {
01523 match x to
01524 | msImm.b.x (d8) => ret = pImmB(d8);
01525 else pNonzeroByte(pc);
01526 endmatch
01527 break;
01528 }
01529 case 7 : {
01530 match x to
01531 | msImm.w.x (d16) => ret = pImmW(d16);
01532 endmatch
01533 break;
01534 }
01535 default : pIllegalMode(pc); break;
01536 }
01537 return ret;
01538 }
01539
01540
01541 SemStr* NJMCDecoder::msEAXL(ADDRESS eaxl, int d32, DecodeResult& result,
01542 ADDRESS pc, int size)
01543 {
01544 SemStr* ret;
01545 int reg2, mode;
01546
01547 match eaxl to
01548 | msAbs.l () => { mode = 5; result.numBytes += 4;}
01549 | msImm.l () => { mode = 8; result.numBytes += 4;}
01550 else pIllegalMode(pc);
01551 endmatch
01552
01553 switch (mode) {
01554 case 5 : {
01555 ret = pAbsL(d32, size);
01556 break;
01557 }
01558 case 8 : {
01559 ret = pImmL(d32);
01560 break;
01561 }
01562 default : pIllegalMode(pc); break;
01563 }
01564 return ret;
01565 }
01566
01567
01568 SemStr* NJMCDecoder::mdEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01569 ADDRESS pc, int size)
01570 {
01571 SemStr* ret;
01572 int reg1, mode;
01573
01574 match eax to
01575 | mdADisp (r1) => { mode = 0; reg1 = r1; result.numBytes += 2;}
01576 | mdAIndex (r1) => { mode = 1; reg1 = r1; result.numBytes += 2;}
01577 | mdAbs.w () => { mode = 4; result.numBytes += 2;}
01578 | mdAbs.l () => { mode = 5; result.numBytes += 4;}
01579 else pIllegalMode(pc);
01580 endmatch
01581
01582 switch (mode) {
01583 case 0 : {
01584 match x to
01585 | mdADisp.x (d16) => ret = pADisp(d16, reg1, size);
01586 endmatch
01587 break;
01588 }
01589 case 1 : {
01590 match x to
01591 | mdAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg1, iT, iR, iS, size);
01592 endmatch
01593 break;
01594 }
01595 case 4 : {
01596 match x to
01597 | mdAbs.w.x (d16) => ret = pAbsW(d16, size);
01598 endmatch
01599 break;
01600 }
01601 case 5 : {
01602 match x to
01603 | mdAbs.l.x (d32) => ret = pAbsL(d32, size);
01604 endmatch
01605 break;
01606 }
01607 default : pIllegalMode(pc); break;
01608 }
01609 return ret;
01610 }
01611
01612
01613 SemStr* NJMCDecoder::mrEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01614 ADDRESS pc, int delta, int size)
01615 {
01616 SemStr* ret;
01617 int reg2, mode;
01618
01619 match eax to
01620 | mrADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01621 | mrAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01622 | mrPcDisp () => { mode = 2; result.numBytes += 2;}
01623 | mrPcIndex () => { mode = 3; result.numBytes += 2;}
01624 | mrAbs.w () => { mode = 4; result.numBytes += 2;}
01625 | mrAbs.l () => { mode = 5; result.numBytes += 4;}
01626 else pIllegalMode(pc);
01627 endmatch
01628
01629 switch (mode) {
01630 case 0 : {
01631 match x to
01632 | mrADisp.x (d16) => ret = pADisp(d16, reg2, size);
01633 endmatch
01634 break;
01635 }
01636 case 1 : {
01637 match x to
01638 | mrAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01639 endmatch
01640 break;
01641 }
01642 case 2 : {
01643 match x to
01644 | mrPcDisp.x (label) => ret = pPcDisp(label, delta, size);
01645 endmatch
01646 break;
01647 }
01648 case 3 : {
01649 match x to
01650 | mrPcIndex.x (iT, iR, iS, d8) =>
01651 ret = pPcIndex(d8, iT, iR, iS, pc+2, size);
01652 endmatch
01653 break;
01654 }
01655 case 4 : {
01656 match x to
01657 | mrAbs.w.x (d16) => ret = pAbsW(d16, size);
01658 endmatch
01659 break;
01660 }
01661 case 5 : {
01662 match x to
01663 | mrAbs.l.x (d32) => ret = pAbsL(d32, size);
01664 endmatch
01665 break;
01666 }
01667 default : pIllegalMode(pc); break;
01668 }
01669 return ret;
01670 }
01671
01672
01673 SemStr* NJMCDecoder::rmEAX(ADDRESS eax, ADDRESS x, DecodeResult& result,
01674 ADDRESS pc, int size)
01675 {
01676 SemStr* ret;
01677 int reg2, mode;
01678
01679 match eax to
01680 | rmADisp (r2) => { mode = 0; reg2 = r2; result.numBytes += 2;}
01681 | rmAIndex (r2) => { mode = 1; reg2 = r2; result.numBytes += 2;}
01682 | rmAbs.w () => { mode = 4; result.numBytes += 2;}
01683 | rmAbs.l () => { mode = 5; result.numBytes += 4;}
01684 else pIllegalMode(pc);
01685 endmatch
01686
01687 switch (mode) {
01688 case 0 : {
01689 match x to
01690 | rmADisp.x (d16) => ret = pADisp(d16, reg2, size);
01691 endmatch
01692 break;
01693 }
01694 case 1 : {
01695 match x to
01696 | rmAIndex.x (iT, iR, iS, d8) => ret = pAIndex(d8, reg2, iT, iR, iS, size);
01697 endmatch
01698 break;
01699 }
01700 case 4 : {
01701 match x to
01702 | rmAbs.w.x (d16) => ret = pAbsW(d16, size);
01703 endmatch
01704 break;
01705 }
01706 case 5 : {
01707 match x to
01708 | rmAbs.l.x (d32) => ret = pAbsL(d32, size);
01709 endmatch
01710 break;
01711 }
01712 default : pIllegalMode(pc); break;
01713 }
01714 return ret;
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 bool isFuncPrologue(ADDRESS hostPC)
01726 {
01727 int locals, reg, d16;
01728
01729 if ((InstructionPatterns::link_save(prog.csrSrc, hostPC, locals, d16))
01730 != NULL)
01731 return true;
01732 if ((InstructionPatterns::link_save1(prog.csrSrc, hostPC, locals, reg))
01733 != NULL)
01734 return true;
01735 if ((InstructionPatterns::push_lea(prog.csrSrc, hostPC, locals, reg))
01736 != NULL)
01737 return true;
01738 if ((InstructionPatterns::std_link(prog.csrSrc, hostPC, locals)) != NULL)
01739 return true;
01740
01741 return false;
01742 }
01743