TO DO:
- FIX CIELOS - FIX HUGE STACKS BYE
This commit is contained in:
parent
ca67378173
commit
2ea7bf65ea
|
@ -24,7 +24,7 @@
|
|||
#include "../ta-log.h"
|
||||
|
||||
bool DivCSChannelState::doCall(unsigned int addr) {
|
||||
if (callStackPos>=16) {
|
||||
if (callStackPos>=DIV_MAX_CSSTACK) {
|
||||
readPos=0;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "safeReader.h"
|
||||
|
||||
#define DIV_MAX_CSTRACE 64
|
||||
#define DIV_MAX_CSSTACK 128
|
||||
|
||||
class DivEngine;
|
||||
|
||||
|
@ -39,7 +40,7 @@ struct DivCSChannelState {
|
|||
int portaTarget, portaSpeed;
|
||||
unsigned char arp, arpStage, arpTicks, loopCount;
|
||||
|
||||
unsigned int callStack[16];
|
||||
unsigned int callStack[DIV_MAX_CSSTACK];
|
||||
unsigned char callStackPos;
|
||||
|
||||
unsigned int trace[DIV_MAX_CSTRACE];
|
||||
|
|
|
@ -662,6 +662,7 @@ SafeWriter* stripNops(SafeWriter* s) {
|
|||
case 0xf5: // calli
|
||||
case 0xfa: { // jmp
|
||||
unsigned int addr=buf[i+1]|(buf[i+2]<<8)|(buf[i+3]<<16)|(buf[i+4]<<24);
|
||||
assert(!(addr&7));
|
||||
try {
|
||||
addr=addrTable[addr];
|
||||
buf[i+1]=addr&0xff;
|
||||
|
@ -780,14 +781,11 @@ struct BlockMatch {
|
|||
|
||||
// TODO:
|
||||
// - see if we can optimize even more
|
||||
SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlocks, unsigned char* speedDial) {
|
||||
SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlocks, unsigned char* speedDial, DivCSProgress* progress) {
|
||||
unsigned char* buf=stream->getFinalBuf();
|
||||
size_t matchSize=MIN_MATCH_SIZE;
|
||||
std::vector<BlockMatch> matches;
|
||||
|
||||
// repeat until we run out of matches
|
||||
while (true) {
|
||||
matchSize=MIN_MATCH_SIZE;
|
||||
matches.clear();
|
||||
|
||||
// fast match algorithm
|
||||
|
@ -842,6 +840,7 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
|||
// set done to false unless:
|
||||
// - this match overlaps with itself
|
||||
// - this block only consists of calls
|
||||
// - this block contains a ret or jmp
|
||||
size_t nonOverlapCount=0;
|
||||
for (BlockMatch& i: matches) {
|
||||
i.done=false;
|
||||
|
@ -851,11 +850,20 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
|||
} else {
|
||||
bool onlyCalls=true;
|
||||
for (size_t j=i.orig; j<i.orig+i.len; j+=8) {
|
||||
if (buf[j]!=0xf4) {
|
||||
if (buf[j]!=0xf4 && buf[j]!=0xf5) {
|
||||
onlyCalls=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!onlyCalls) {
|
||||
// check whether there's call or ret
|
||||
for (size_t j=i.orig; j<i.orig+i.len; j+=8) {
|
||||
if (buf[j]==0xf9 || buf[j]==0xfa) {
|
||||
onlyCalls=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (onlyCalls) {
|
||||
i.done=true;
|
||||
} else {
|
||||
|
@ -866,10 +874,14 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
|||
|
||||
logD("%d good candidates",(int)nonOverlapCount);
|
||||
|
||||
if (progress!=NULL) {
|
||||
progress->count=nonOverlapCount;
|
||||
}
|
||||
|
||||
// NEW STUFF
|
||||
// find and sort matches by benefit
|
||||
size_t bestBenefitIndex=0;
|
||||
int bestBenefit=-1000000;
|
||||
int bestBenefit=-1;
|
||||
size_t lastOrig=SIZE_MAX;
|
||||
size_t lastLen=SIZE_MAX;
|
||||
size_t lastOrigOff=0;
|
||||
|
@ -885,9 +897,11 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
|||
if (lastOrig!=SIZE_MAX) {
|
||||
// commit previous block and start new one
|
||||
//logV("%x gains: %d",(int)lastOrig,gains);
|
||||
if (gains>bestBenefit) {
|
||||
int finalBenefit=gains*2+lastLen*3;
|
||||
if (gains<1) finalBenefit=-1;
|
||||
if (finalBenefit>bestBenefit) {
|
||||
bestBenefitIndex=lastOrigOff;
|
||||
bestBenefit=gains;
|
||||
bestBenefit=finalBenefit;
|
||||
}
|
||||
if (gains<=0) {
|
||||
// don't make a sub-block for these matches since we only have loss
|
||||
|
@ -1020,15 +1034,12 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
|||
logV("done!");
|
||||
|
||||
// get out if we haven't made any blocks
|
||||
if (!newBlocks) break;
|
||||
if (!newBlocks) return stream;
|
||||
|
||||
// remove nop's
|
||||
stream=stripNops(stream);
|
||||
buf=stream->getFinalBuf();
|
||||
|
||||
logV("doing it again...");
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
@ -1059,19 +1070,20 @@ SafeWriter* packStream(SafeWriter* s, unsigned char* speedDial) {
|
|||
try {
|
||||
addr=addrTable[addr];
|
||||
// check whether we have sufficient room to turn this into a 16-bit call
|
||||
/*
|
||||
if (addr<0xff00) {
|
||||
buf[i]=0xf8;
|
||||
buf[i+1]=addr&0xff;
|
||||
buf[i+2]=(addr>>8)&0xff;
|
||||
buf[i+3]=0xf1;
|
||||
buf[i+4]=0xf1;
|
||||
} else {
|
||||
} else {*/
|
||||
buf[i]=0xf5;
|
||||
buf[i+1]=addr&0xff;
|
||||
buf[i+2]=(addr>>8)&0xff;
|
||||
buf[i+3]=(addr>>16)&0xff;
|
||||
buf[i+4]=(addr>>24)&0xff;
|
||||
}
|
||||
//}
|
||||
} catch (std::out_of_range& e) {
|
||||
logW("address %x is not mappable!",addr);
|
||||
}
|
||||
|
@ -1458,21 +1470,15 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
|
||||
// 6 is the minimum size that can be reliably optimized
|
||||
logI("finding sub-blocks");
|
||||
globalStream=findSubBlocks(globalStream,subBlocks,sortedCmd);
|
||||
// find sub-blocks within sub-blocks
|
||||
size_t subBlocksLast=0;
|
||||
size_t subBlocksLen=subBlocks.size();
|
||||
logI("finding sub-blocks within sub-blocks");
|
||||
while (subBlocksLast!=subBlocksLen) {
|
||||
logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast);
|
||||
for (size_t i=subBlocksLast; i<subBlocksLen; i++) {
|
||||
SafeWriter* newBlock=findSubBlocks(subBlocks[i],subBlocks,sortedCmd);
|
||||
subBlocks[i]=newBlock;
|
||||
}
|
||||
subBlocksLast=subBlocksLen;
|
||||
subBlocksLen=subBlocks.size();
|
||||
}
|
||||
|
||||
bool haveBlocks=false;
|
||||
subBlocks.clear();
|
||||
// repeat until no more sub-blocks are produced
|
||||
do {
|
||||
logD("iteration...");
|
||||
globalStream=findSubBlocks(globalStream,subBlocks,sortedCmd,progress);
|
||||
|
||||
haveBlocks=!subBlocks.empty();
|
||||
// insert sub-blocks and resolve symbols
|
||||
logI("%d sub-blocks total",(int)subBlocks.size());
|
||||
std::vector<size_t> blockOff;
|
||||
|
@ -1528,6 +1534,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
}
|
||||
}
|
||||
}
|
||||
} while (haveBlocks);
|
||||
|
||||
size_t afterSize=globalStream->size();
|
||||
logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize);
|
||||
|
|
|
@ -6064,7 +6064,7 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
} else {
|
||||
WAKE_UP;
|
||||
ImGui::Text("Exporting...");
|
||||
ImGui::Text("Exporting... %d",csProgress.count);
|
||||
|
||||
// check whether we're done
|
||||
if (csExportDone) {
|
||||
|
|
Loading…
Reference in a new issue