?? optim.c
字號:
else if (c == '%') {
int r;
r = GetRegNumber(bp);
if (regcount == 0) ins->SrcReg = r;
else ins->SrcReg |= (r << 8);
regcount++;
}
}
if (*bp == ')') ins->src[i++] = *bp++;
}
else if (c == '%') {
int r;
r = GetRegNumber(bp);
if (regcount == 0) ins->SrcReg = r;
else ins->SrcReg |= (r << 8);
regcount++;
}
else if (c == '_') {
while (*bp && ((*bp >= 'a' && *bp <= 'z') || (*bp >= 'A' && *bp <= 'Z'))) {
if (*bp == ',') break;
if (i < MAXIDSIZE) {
ins->src[i++] = *bp++;
}
else {
ins->Flags |= TRUNCATED;
bp++;
}
}
}
}
if (*bp == ',' || (*bp == ' ' || *bp == '\t')) bp++;
else if (*bp == '\n'){
if (firstCodeChar == 'c' && op[1] == 'a') {
ins->Flags |= ISCALL;
bb->Flags |= ISCALL;
if (bb->FirstCall == 0)
bb->FirstCall = (unsigned char)(InstructionIndex-1);
bb->LastCall = (unsigned char)(InstructionIndex-1);
}
bp++;
ins->End = bp;
return(bp);
}
while (*bp == ' ' || *bp == '\t') bp++;
if (*bp == '%') ins->Flags |= ISREGDST;
i = regcount = 0;
while (*bp && *bp != ' ' && *bp != '\n') {
int c = *bp++;
if (i < MAXIDSIZE)
ins->dst[i++] = (unsigned char)c;
else
ins->Flags |= TRUNCATED;
if (c == '(') {
ins->Flags |= DSTOFFSET;
while (*bp && *bp != ')') {
c = *bp++;
if (i < MAXIDSIZE)
ins->dst[i++] = (unsigned char)c;
else ins->Flags |= TRUNCATED;
if (c == ',') {
ins->Flags |= DSTDEREFERENCE;
}
else if (c == '%') {
int r;
r = GetRegNumber(bp);
if (regcount == 0) ins->DstReg = (unsigned char)r;
else ins->DstReg |= (r << 8);
regcount++;
}
}
if (*bp == ')' && i < MAXIDSIZE) ins->dst[i++] = *bp++;
else if (i >= MAXIDSIZE) ins->Flags |= TRUNCATED;
}
else if (c == '%') {
int r;
r = GetRegNumber(bp);
if (regcount == 0) ins->DstReg = r;
else ins->DstReg |= (r << 8);
regcount++;
}
else if (c == '_') {
while (*bp && ((*bp >= 'a' && *bp <= 'z') || (*bp >= 'A' && *bp <= 'Z'))) {
if (*bp == ',') break;
if (i < MAXIDSIZE) {
ins->dst[i++] = *bp++;
}
else {
ins->Flags |= TRUNCATED;
bp++;
}
}
}
}
while (*bp && *bp != '\n') bp++;
if (*bp == 0) {
ins->End = bp;
*pp = NULL;
return(NULL);
}
if (*bp == '\n') bp++;
ins->End = bp;
return(bp);
}
/* Adds instructions to the basic block until it finds a label
*/
static unsigned char *FindEndBlock(unsigned char *bp,BasicBlock *bb,unsigned char *stop)
{
unsigned char *r=bp,*result;
bb->NrOfInstructions = 0;
while ((r=AddNextInstruction(r,bb,&result))!=NULL) {
if (InstructionIndex > 0
&& InstructionTable[InstructionIndex-1].Flags & TRUNCATED) {
result = NULL;
bb->NrOfInstructions = 0;
fprintf(stderr,"Maximum identifier length exceeded.\n");
fprintf(stderr,"Quitting optimization\n");
return NULL;
}
if (r && r >= stop) break;
}
return(result);
}
#ifdef STANDALONE
static unsigned char *FindBasicBlock(unsigned char *bp,BasicBlock *block,unsigned char *stop)
{
unsigned char *bb,*be;
bb = FindBeginBlock(bp,block);
if (bb == NULL) return(NULL);
be = FindEndBlock(bb,block,stop);
return(be);
}
#endif
/* Invalidates the contents of the given register ('which') if
they are equal to the given character string.
*/
static void doclobber(unsigned char *p,int which)
{
if (p == Nullst) return;
if (p == NULL) return;
if (which != EAX && State[EAX] && !strcmp(State[EAX],p)) {
Printf1("eax = NULL\n");
State[EAX] = Nullst;
}
if (which != EBX && State[EBX] && !strcmp(State[EBX],p)) {
Printf1("ebx = NULL\n");
State[EBX] = Nullst;
}
if (which != ECX && State[ECX] && !strcmp(State[ECX],p)) {
Printf1("ecx = NULL\n");
State[ECX] = Nullst;
}
if (which != EDX && State[EDX] && !strcmp(State[EDX],p)) {
Printf1("edx = NULL\n");
State[EDX] = Nullst;
}
if (which != ESI && State[ESI] && !strcmp(State[ESI],p)) {
Printf1("esi = NULL\n");
State[ESI] = Nullst;
}
if (which != EDI && State[EDI] && !strcmp(State[EDI],p)) {
Printf1("edi = NULL\n");
State[EDI] = Nullst;
}
}
/* Replaces in the given buffer (str) the register named
'src' with the register named 'dst' and writes the
modified output into the 'out' buffer
*/
static int doreplace(unsigned char *str,unsigned char *src,unsigned char *dst,unsigned char *out)
{
unsigned char *p = str;
unsigned char *d = out;
int result = 0;
while (*p) {
if (*p == '%') {
*d++ = *p++;
if (p[0] == src[0] && p[1] == src[1] && p[2] == src[2]) {
*d++ = dst[0];
*d++ = dst[1];
*d++ = dst[2];
p += 3;
result++;
}
else if (p[0] != 'e') {
if (p[0] == src[1] && p[1] == src[2]) {
*d++ = dst[1];
*d++ = dst[2];
p += 2;
result++;
}
else if (p[0] == src[1] && p[1] == 'l' && src[2] == 'x') {
*d++ = dst[1];
*d++ = 'l';
p += 2;
}
}
}
else *d++ = *p++;
}
*d = 0;
return(result);
}
static int fixRegNr(int SrcReg,int reg,int oldreg)
{
int r1,r2;
if (SrcReg < ESP) return reg;
else if (SrcReg < SP) {
return reg + ESP;
}
else if (SrcReg & 0xFF00) {
r1 = SrcReg & 0xFF;
r2 = SrcReg >> 8;
if (oldreg == r1) {
return (reg | (r2 << 8));
}
else if (oldreg == r2) {
return ((reg << 8) | r1);
}
else
printf("internal compiler error 123 in optimizer\n");
}
return 0;
}
static int ReplaceRegister(unsigned char *regsrc,unsigned char *regdst,BasicBlock *bb,int first,int last,int reg)
{
Instruction *ins,*insDst;
unsigned char *src,*dst;
int dochanged,oldreg;
ins = &InstructionTable[first];
if (ins->Flags & CHANGED) {
insDst = &InstructionTable[ins->ChangedIdx];
dst = insDst->dst;
src = insDst->src;
}
else {
dst = ins->dst;
src = ins->src;
}
ins->Flags |= CHANGED;
ins->ChangedIdx = bb->ChangedCounter;
insDst = &InstructionTable[bb->ChangedCounter];
bb->ChangedCounter++;
oldreg = GetRegNumber(regsrc);
memset(insDst,0,sizeof(Instruction));
if (!doreplace(dst,regsrc,regdst,insDst->dst)) {
bb->ChangedCounter--;
return(0);
}
ins->DstReg = reg;
strcpy(insDst->src,src);
strcpy(insDst->Name,ins->Name);
first++;
ins++;
while (first <= last) {
dochanged = 0;
if (ins->Flags & CHANGED) {
insDst = &InstructionTable[ins->ChangedIdx];
src = insDst->src;
dst = insDst->dst;
}
else {
src = ins->src;
dst = ins->dst;
}
insDst = GetNextChangedInstruction(ins,bb);
strcpy(insDst->Name,ins->Name);
if (doreplace(src,regsrc,regdst,insDst->src)) {
ins->SrcReg = fixRegNr(ins->SrcReg,reg,oldreg);
dochanged++;
}
if (first != last) {
if (doreplace(dst,regsrc,regdst,insDst->dst)) {
ins->DstReg = fixRegNr(ins->DstReg,reg,oldreg);
dochanged++;
}
}
else strcpy(insDst->dst,dst);
if (dochanged) {
ins->Flags |= CHANGED;
}
else {
bb->ChangedCounter--;
ins->Flags &= ~ CHANGED;
}
first++;
ins++;
}
bb->Registers[reg] = 1;
return(1);
}
int testSafeReplacement(unsigned char *s)
{
if (*s++ != '(') return 0;
if (*s++ != '%') return 0;
if (*s++ != 'e') return 0;
s += 2;
if (*s++ != ',') return 0;
if (*s++ != '%') return 0;
if (*s++ != 'e') return 0;
s += 2;
if (*s != ')') return 0;
return 1;
}
static int AvoidClobber(unsigned char *reg,int idxInstruction,BasicBlock *bb)
{
int i,n,lastidx;
Instruction *ins;
if (SwappedRegs)
return 0;
if (State[ECX] != NULL && State[ECX] != Nullst) {
if (State[EDX] != NULL && State[EDX] != Nullst) {
return(0);
}
}
i = idxInstruction+1;
n = bb->NrOfInstructions;
if (i >= n) return(0);
ins = &InstructionTable[i];
lastidx = -1;
/* Find the first instruction that stores into that register */
while (i < n) {
if (ins->Flags & (CHANGED|ISCALL|TRUNCATED)) return(0);
if (ins->SrcReg > EBP || ins->DstReg > EBP) {
if (ins->SrcReg > EBP) {
if (!testSafeReplacement(ins->src)) return 0;
}
if (ins->DstReg > EBP) {
if (!testSafeReplacement(ins->dst)) return 0;
}
}
if (ins->Name[0] == 'f') return(0);
if (ins->Name[0] == 'i') {
if (!strncmp(ins->Name,"idiv",4)) return(0);
if (!strncmp(ins->Name,"imul",4)) return(0);
}
else if (!strncmp(ins->Name,"div",3)) return(0);
else if (!strncmp(ins->Name,"mul",3)) return(0);
if (ins->DstReg == ECX || ins->DstReg == EDX) return(0);
if (ins->SrcReg == EDX || ins->DstReg == ECX) return(0);
if (ins->dst[0] == '%') { /* if is a register store operation */
if (ins->Flags & ISGENERICMOVE)
if (ins->dst[1] == *reg && ins->dst[2] == reg[1] && ins->dst[3] == reg[2]) {
if (ins->SrcReg > EBP) return(0);
if (ins->dst[1] == ins->src[1] && ins->dst[2] == ins->src[2] &&
ins->dst[3] == ins->src[3] && ins->src[0] == ins->dst[0]) {
goto goon;
}
lastidx = i;
break;
}
}
goon:
i++;
ins++;
}
if (lastidx < 0) return(0);
if (State[ECX] == NULL || State[ECX] == Nullst) {
int r = ReplaceRegister(reg,"ecx",bb,idxInstruction,lastidx,ECX);
return (r)? ECX : 0;
}
if (State[EDX] == NULL || State[EDX] == Nullst) {
int r = ReplaceRegister(reg,"edx",bb,idxInstruction,lastidx,EDX);
return (r)? EDX : 0;
}
return(0);
}
static int TranslateWordRegister(int DstReg)
{
if (DstReg >= AX && DstReg <= DI) {
switch(DstReg) {
case AX:
return EAX;
case BX:
return EBX;
case CX:
return ECX;
case DX:
return EDX;
case SI:
return ESI;
case DI:
return EDI;
}
}
return DstReg;
}
int IsRegisterVariable(int regNum)
{
if (hasRegisterVariables) {
if (regNum == ESI && (hasRegisterVariables & (1 << 6))) return 1;
if (regNum == EBX && (hasRegisterVariables & (1 << 3))) return 1;
if (regNum == EDI && (hasRegisterVariables & (1 << 7))) return 1;
}
if (SwappedRegs) {
if (regNum == ECX || regNum == EDX)
return 1;
}
return 0;
}
static int IsAliveValue(BasicBlock *bb,int idx,int regNum)
{
int i = idx,flags,SrcReg,DstReg;
Instruction *ins = &InstructionTable[idx];
regNum = TranslateWordRegister(regNum);
if (IsRegisterVariable(regNum))
return 1;
while (i < bb->NrOfInstructions) {
SrcReg = TranslateWordRegister(ins->SrcReg);
DstReg = TranslateWordRegister(ins->DstReg);
if (SrcReg > ESP || DstReg >ESP) return 1;
if (SrcReg == regNum) {
if (ins->Name[0] == 'p' && ins->Name[1] == 'o' &&
ins->Name[2] == 'p' && ins->src[0] == '%')
return 0;
return(1);
}
flags = ins->Flags;
if ((flags & ISGENERICMOVE) == 0) {
if (DstReg == regNum) {
if (flags & ISLEAL) return(0);
return(1);
}
if (regNum == EAX || regNum == ECX) {
if (ins->Name[0] == 'i') {
if (!strncmp(ins->Name,"idiv",4)) return(1);
if (!strncmp(ins->Name,"imul",4)) return(1);
}
else if (!strncmp(ins->Name,"div",3)) return(1);
else if (!strncmp(ins->Name,"mul",3)) return(1);
}
if (flags & ISCALL) {
if (regNum == EAX || regNum == ECX || regNum == EDX)
return(0);
}
if (*(unsigned long *)(ins->Name) == REP_CODE) {
if (regNum == ECX || regNum == ESI || regNum == EDI)
return(1);
}
}
else {
if (ins->dst[0] == '%' && DstReg == regNum)
return(0);
else if (DstReg == regNum) return(1);
}
ins++;
i++;
}
return(0);
}
static int isUsedInBlock(int idxInstruction,unsigned char *old,BasicBlock *bb,int aReg)
{
int c = *old;
Instruction *ins;
int result = 0;
ins = &InstructionTable[idxInstruction];
while (idxInstruction < bb->NrOfInstructions) {
if (c == ins->src[0] && !strcmp(ins->src,old)) {
result++;
}
if (c == ins->dst[0] && !strcmp(ins->dst,old)) {
if (*(unsigned long *)(ins->Name) != CMPL_CODE)
return(result);
else result++;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -