⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optim.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -