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