📄 optim.c
字号:
return 1;
}
static int isByteValue(char *v)
{
int result=0;
// Ignore first dollar
if (*v == '$')
v++;
// first digit
if (*v >= '0' && *v <= '9')
result += *v - '0';
else return 0;
v++;
if (*v == 0) return 1;
result *= 10;
// second digit
if (*v >= '0' && *v <= '9')
result += *v - '0';
else return 0;
v++;
if (*v == 0) return 1;
result *= 10;
// third digit
if (*v >= '0' && *v <= '9')
result += *v - '0';
else return 0;
v++;
if (*v != 0) return 0;
if (result < 255) return 1;
return 0;
}
static int inlinestrlen(void)
{
Instruction *i1,*ip,*in;
int condition;
ip = NULL;
/* i1 is the previous instruction. Should be a push of the
argument of strlen */
i1 = &InstructionTable[idxInstruction-1];
if (i1->Flags & (CHANGED|DELETED)) return 0;
/* in is the next instruction after the call. Should be an addl */
in = &InstructionTable[idxInstruction+1];
if (idxInstruction > 1)
ip = &InstructionTable[idxInstruction-2];
if (i1->Name[0] == 'p'
&& in->Name[0] == 'a') {
if (State[EDI] == NULL)
condition = 0;
else
condition = IsAliveValue(bb,idxInstruction+2,EDI);
if (!ediIsSaved) condition = 1;
insDst = GetNextChangedInstruction(i1,bb);
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i1->src);
if (condition) {
strcpy(insDst->dst,"%edx\n");
if (strcmp(i1->src,"%edi")) {
strcat(insDst->dst,"\txchg\t%edx,%edi");
}
State[EDX] = Nullst;
}
else {
strcpy(insDst->dst,"%edi");
State[EDI] = Nullst;
}
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\txor\t%eax");
strcpy(changedInstruction->src,",%eax\n\tstc\n\tsbb\t%ecx,%ecx\n\trepne\n\t");
strcpy(changedInstruction->dst,"scasb\n\tneg\t%ecx\n\tleal\t-2(%ecx),%eax\n");
/* This overflows by 1 byte. Since the next field of the
instruction is the 'Start' field and it is unused, we can
do that... */
if (condition)
strcat(changedInstruction->dst,"\tmovl\t%edx,%edi\n");
else State[EDI] = Nullst;
State[EAX] = Nullst;
State[ECX] = Nullst;
in->Flags |= DELETED;
ins->Flags |= DELETED;
FixCalls(ins,bb,idxInstruction);
deleted += 2;
return(2);
}
return 0;
}
static int call(void)
{
int i;
if (recursion == 0 && !strcmp(savesrc,"_strlen")) {
i = inlinestrlen();
if (i) return i;
}
else if (recursion == 0 && idxInstruction > 1 &&
InstructionTable[idxInstruction-1].Name[0] == 'f' &&
(!strcmp(savesrc,"_sqrt") || !strcmp(savesrc,"_sin") ||
!strcmp(savesrc,"_fabs") ||
!strcmp(savesrc,"_cos"))) {
Instruction *i1,*i2,*i3;
i1 = &InstructionTable[idxInstruction-1];
i2 = &InstructionTable[idxInstruction-2];
i3 = &InstructionTable[idxInstruction+1];
if (!strcmp(i1->Name,"fstpl") &&
!strcmp(i2->Name,"subl") &&
!strcmp(i3->Name,"addl")) {
i1->Flags |= DELETED;
deleted++;
i2->Flags |= DELETED;
deleted++;
if (!strcmp(savesrc,"_sqrt"))
insDst = ChangeInstruction(ins,bb,"fsqrt","","");
else
if (!strcmp(savesrc,"_sin"))
insDst = ChangeInstruction(ins,bb,"fsin","","");
else
if (!strcmp(savesrc,"_cos"))
insDst = ChangeInstruction(ins,bb,"fcos","","");
else
if (!strcmp(savesrc,"_fabs"))
insDst = ChangeInstruction(ins,bb,"fabs","","");
i3->Flags |= DELETED;
deleted++;
FixCalls(ins,bb,idxInstruction);
return(2);
}
}
#if 0
else
if (/*recursion == 0 && ediIsSaved && esiIsSaved &&*/ !strncmp(savesrc,"_strcpy",7)) {
unsigned char *strconstant;
Instruction *i1,*i2,*in;
int ix,len;
ix = idxInstruction-1;
i1 = &InstructionTable[ix--];
if (i1->Flags & (CHANGED|DELETED)) goto skip1;
i2 = &InstructionTable[ix--];
if (i2->Flags & (CHANGED|DELETED)) goto skip1;
if (i2->Name[0] == 'l' && !strcmp(i2->Name,"leal")) {
if ((InstructionTable[ix].Flags & CHANGED) == 0) {
i2 = &InstructionTable[ix--];
if (i2->Name[0] == 'i' && !strcmp(i2->Name,"imul")) {
i2 = &InstructionTable[ix--];
}
else if ((i2->Flags & ISMOVL) && (i2->Flags & CHANGED)==0)
i2 = &InstructionTable[ix--];
}
}
in = &InstructionTable[idxInstruction+1];
if (strcmp(in->src,"$8")) goto skip1;
if (!(i1->Name[0] == 'p' && i2->Name[0] == 'p'))
goto skip1;
if (!(i2->src[0] == '$' && i2->src[1] == '_' && i2->src[2] == '$'))
goto skip1;
strconstant = FindStringConstant(i2->src+3);
if (strconstant == NULL) goto skip1;
len = strlen(strconstant)+1;
ChangeInstruction(i2,bb,"movl",i2->src,"%edx");
insDst = ChangeInstruction(i1,bb,"movl",i1->src,"%eax");
if (len > 8) {
sprintf(tbuf,"$%d",len);
insDst = ChangeInstruction(ins,bb,"movl",tbuf,"%ecx");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\txchgl\t");
strcpy(changedInstruction->src,"%eax,%edi\n\txchgl\t%edx,%esi\n");
strcpy(changedInstruction->dst,"\trep\n");
strcat(changedInstruction->dst,"\tmovsb\n");
strcat(changedInstruction->dst,"\txchgl\t%eax,%edi\n");
insDst = ChangeInstruction(in,bb,"xchgl","%edx","%esi");
}
else {
switch (len) {
case 1:
ChangeInstruction(ins,bb,"movb","(%eax)","%al");
ChangeInstruction(in,bb,"movb","%al","(%edx)");
break;
case 2:
ChangeInstruction(ins,bb,"movw","(%eax)","%ax");
ChangeInstruction(in,bb,"movw","%ax","(%edx)");
break;
case 3:
ChangeInstruction(ins,bb,"movl","(%eax)","%eax");
insDst = ChangeInstruction(in,bb,"movw","%ax","(%edx)");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\tsar");
strcpy(changedInstruction->src,"\t$16,%eax\n");
strcpy(changedInstruction->dst,"\tmovb\t%al\t3(%edx)\n");
break;
case 4:
ChangeInstruction(ins,bb,"movl","(%eax)","%ecx");
ChangeInstruction(in,bb,"movl","%ecx","(%edx)");
break;
case 5:
ChangeInstruction(ins,bb,"movl","(%eax)","%ecx");
insDst = ChangeInstruction(in,bb,"movl","%ecx","(%edx)");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\tmovb\t");
strcpy(changedInstruction->src,"$0,");
strcpy(changedInstruction->dst,"4(%edx)\n");
break;
case 6:
ChangeInstruction(ins,bb,"movl","(%eax)","%ecx");
insDst = ChangeInstruction(in,bb,"movl","%ecx","(%edx)");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\tmovw\t");
strcpy(changedInstruction->src,"4(%eax),%cx\n\t");
strcpy(changedInstruction->dst,"movw\t%cx,4(%edx)\n");
break;
case 7:
ChangeInstruction(ins,bb,"movl","(%eax)","%ecx");
insDst = ChangeInstruction(in,bb,"movl","%ecx","(%edx)");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\tmovw\t");
strcpy(changedInstruction->src,"4(%eax),%cx\n\tmovw\t%cx,4(%edx)\n");
strcpy(changedInstruction->dst,"movb\t$0,6(%edx)\n");
break;
case 8:
ChangeInstruction(ins,bb,"movl","(%eax)","%ecx");
insDst = ChangeInstruction(in,bb,"movl","%ecx","(%edx)");
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
strcpy(changedInstruction->Name,"\tmovl\t");
strcpy(changedInstruction->src,"4(%eax),%ecx\n\tmovl");
strcpy(changedInstruction->dst,"\t%ecx,4(%edx)\n");
break;
}
}
FixCalls(ins,bb,idxInstruction);
printf("Optimization strcpy %s\n",strconstant);
return 2;
}
#endif
else
if (hasRegisterVariables == 0 &&
recursion == 0 && !strcmp(savesrc,"_memcpy")) {
Instruction *i1,*i2,*i3,*in,*ip;
int lab,saveEsi,saveEdi,ismovsw,ismovsd,isExactBytes;
ip = NULL;
i1 = &InstructionTable[idxInstruction-1];
if (i1->Flags & (CHANGED|DELETED)) goto skip1;
i2 = &InstructionTable[idxInstruction-2];
if (i2->Flags & (CHANGED|DELETED)) goto skip1;
i3 = &InstructionTable[idxInstruction-3];
if (i3->Flags & (CHANGED|DELETED)) goto skip1;
if (idxInstruction > 3)
ip = &InstructionTable[idxInstruction-4];
in = &InstructionTable[idxInstruction+1];
if (in->Flags & (CHANGED|DELETED)) goto skip1;
if (i1->Name[0] == 'p' &&
i2->Name[0] == 'p' &&
i3->Name[0] == 'p' &&
in->Name[0] == 'a' &&
(!strcmp(in->src,"$12")) &&
(i1->Flags & CHANGED) == 0 &&
(i2->Flags & CHANGED) == 0 &&
(i3->Flags & CHANGED) == 0) {
insDst = GetNextChangedInstruction(i3,bb);
lab = 0;
if (ip && (ip->Flags & CHANGED)== 0 && ip->Flags & ISMOVL &&
ip->dst[0] == '%' &&
(!strcmp(i3->src,ip->src)) &&
(ip->DstReg == ESI || ip->DstReg == EDI)) {
ip->Flags |= DELETED;
deleted++;
strcpy(insDst->Name,"movl");
strcpy(insDst->src,ip->src);
}
else {
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i3->src);
}
strcpy(insDst->dst,"%ecx");
State[ECX] = Nullst;
if (!ediIsSaved ) saveEdi = 1;
else if (hasRegisterVariables) saveEdi=1;
else saveEdi = IsAliveValue(bb,idxInstruction+2,EDI);
if (!esiIsSaved || hasRegisterVariables) saveEsi = 1;
else saveEsi = IsAliveValue(bb,idxInstruction+2,ESI);
ismovsd = ismovsw = isExactBytes = 0;
if (insDst->src[0] == '$' && insDst->src[1] >= '0' &&
insDst->src[1] <= '9') {
int t;
t = atoi(&insDst->src[1]);
if (t > 0) {
if (0 == (t % 4)) {
t /= 4;
ismovsd = 1;
}
else if (0 == (t%2)) {
t /= 2;
ismovsw = 1;
}
if (ismovsd || ismovsw) {
if (t == 1) {
i3->Flags |= DELETED;
i3->Flags &= ~CHANGED;
deleted++;
isExactBytes = 1;
}
else sprintf(insDst->src,"$%d",t);
}
}
}
if (i3->src[0] != '$') {
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags &= ~CHANGED;
insDst->Flags |= ADDED;
lab = genlabel(1);
sprintf(changedInstruction->Name,"\tjecxz");
sprintf(changedInstruction->src,"\t_$%d\n",lab);
}
insDst = GetNextChangedInstruction(i2,bb);
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i2->src);
if (saveEsi) {
strcpy(insDst->dst,"%edx\n\txchg\t%edx,%esi");
State[EDX] = Nullst;
}
else {
strcpy(insDst->dst,"%esi");
State[ESI] = Nullst;
}
insDst = GetNextChangedInstruction(i1,bb);
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i1->src);
if (saveEdi) {
strcpy(insDst->dst,"%eax\n\txchg\t%eax,%edi");
State[EAX] = Nullst;
}
else {
strcpy(insDst->dst,"%edi");
State[EDI] = Nullst;
}
if (!isExactBytes) {
insDst = GetNextChangedInstruction(ins,bb);
strcpy(insDst->Name,"rep");
insDst->src[0] = insDst->dst[0] = 0;
}
else {
ins->Flags |= DELETED;
deleted++;
}
FixCalls(ins,bb,idxInstruction);
insDst = GetNextChangedInstruction(in,bb);
if (ismovsw) {
strcpy(insDst->Name,"movsw");
}
else if (ismovsd) {
strcpy(insDst->Name,"movsl");
}
else strcpy(insDst->Name,"movsb");
if (saveEsi) {
strcat(insDst->Name,"\n");
strcpy(insDst->src,"mov\t%edx,%esi");
}
if (saveEdi) {
if (!saveEsi) {
strcat(insDst->Name,"\n");
strcpy(insDst->src,"movl\t%eax,%edi");
}
else strcat(insDst->src,"\n\tmov\t%eax,%edi");
}
if (lab) {
char tlabbuf[30];
sprintf(tlabbuf,"\n_$%d:",lab);
strcat(insDst->src,tlabbuf);
}
State[ESI] = Nullst;
return(2);
}
}
else if (!strcmp(savesrc,"_memset")) {
Instruction *i1,*i2,*i3,*in,*ip;
int ix,isword,isdword,AvoidClobberingEax;
ip = NULL;
isword = isdword = 0;
ix = idxInstruction-1;
i1 = &InstructionTable[ix--];
if (i1->Flags & (CHANGED|DELETED)) goto skip1;
i2 = &InstructionTable[ix--];
if (i2->Flags & (CHANGED|DELETED)) goto skip1;
if (i2->Name[0] == 'l' && !strcmp(i2->Name,"leal")) {
if ((InstructionTable[ix].Flags & CHANGED) == 0) {
i2 = &InstructionTable[ix--];
if (i2->Name[0] == 'i' && !strcmp(i2->Name,"imul")) {
i2 = &InstructionTable[ix--];
}
else if ((i2->Flags & ISMOVL) && (i2->Flags & CHANGED)==0)
i2 = &InstructionTable[ix--];
}
}
i3 = &InstructionTable[ix--];
if (i3->Flags & (CHANGED|DELETED)) goto skip1;
if (ix > 0)
ip = &InstructionTable[ix--];
in = &InstructionTable[idxInstruction+1];
if (!strcmp(i1->src,"%eax"))
AvoidClobberingEax = 1;
else
AvoidClobberingEax = 0;
if (i1->Name[0] == 'p' &&
i2->Name[0] == 'p' &&
i3->Name[0] == 'p' &&
in->Name[0] == 'a' &&
(i1->Flags & CHANGED) == 0 &&
(i2->Flags & CHANGED) == 0 &&
(i3->Flags & CHANGED) == 0 &&
(in->Flags & CHANGED) == 0 &&
!(AvoidClobberingEax && !ediIsSaved)) {
/*
This could be the last call in an optimized series. The stack
adjustment could be different than 12, in that case. (See
optimization of add $x,%esp below)
*/
if (strcmp(in->src,"$12")) {
goto skip1;
}
/*
First handle the quantity to put on ecx
*/
if (ip && (ip->Flags & ISMOVL) && !strcmp(ip->dst,i3->src)) {
insDst = GetNextChangedInstruction(ip,bb);
strcpy(insDst->Name,ip->Name);
strcpy(insDst->src,ip->src);
i3->Flags |= DELETED;
deleted++;
}
else {
insDst = GetNextChangedInstruction(i3,bb);
strcpy(insDst->Name,"movl");
if (i3->src[0] == '$' && !strcmp(i2->src,"$0")) {
int val = ReadValue(&i3->src[1]);
if (val) {
if (!(val%4)) {
val = val/4;
isdword = 1;
}
else if (!(val & 1)) {
val = val / 2;
isword = 1;
}
sprintf(insDst->src,"$%d",val);
}
/*
here we have memset(ptr,n,0); I do not know how to
nadle it so we call the ibrary function
*/
else goto skip1;
}
else {
strcpy(insDst->src,i3->src);
}
}
strcpy(insDst->dst,"%ecx");
State[ECX] = Nullst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -