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

📄 optim.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 5 页
字号:
			insDst = GetNextChangedInstruction(i2,bb);
			if (ediIsSaved == 0 || hasRegisterVariables) {
				changedInstruction = GetNextChangedInstruction(insDst,bb);
				insDst->Flags |= ADDED;
				insDst->Flags &= ~ CHANGED;
				strcpy(changedInstruction->Name,"\tpushl");
				strcpy(changedInstruction->src,"\t%edi\n");
				changedInstruction->dst[0] = 0;
			}
			if ((!strcmp(i2->src,"$0")) || (!strcmp(i2->src,"$0x0"))) {
				strcpy(insDst->Name,"xor");
				if (AvoidClobberingEax) {
					strcpy(insDst->src,"%edi");
				}
				else {
					strcpy(insDst->src,"%eax");
				}
			}
			else if (i2->src[0] == '$') {
				/*
				Replicate in the eax register an 8 bit quantity
				*/
				int val = ReadValue(&i2->src[1]);
				strcpy(insDst->Name,"movl");
				sprintf(insDst->src,"$%d",(val << 24)|(val << 16)|(val << 8)|val);
			}
			else {
				strcpy(insDst->Name,"movl");
				strcpy(insDst->src,i2->src);
			}
			if (!AvoidClobberingEax) {
				strcpy(insDst->dst,"%eax");
			}
			else {
				strcpy(insDst->dst,"%edi");
			}
			State[EAX] = Nullst;

			insDst = GetNextChangedInstruction(i1,bb);
			if (strcmp(i1->src,"%edi")) {
				if (!AvoidClobberingEax) {
					strcpy(insDst->Name,"movl");
					strcpy(insDst->src,i1->src);
					strcpy(insDst->dst,"%edi");
				}
				else {
					strcpy(insDst->Name,"xchg");
					strcpy(insDst->src,"%eax");
					strcpy(insDst->dst,"%edi");
				}
			}
			else {
				i1->Flags |= DELETED;
				deleted++;
			}
			State[EDI] = Nullst;

			insDst = GetNextChangedInstruction(ins,bb);
			strcpy(insDst->Name,"rep");
			FixCalls(ins,bb,idxInstruction);

			insDst = GetNextChangedInstruction(in,bb);
			if (isdword)
				strcpy(insDst->Name,"stosl");
			else if (isword)
				strcpy(insDst->Name,"stosw");
			else strcpy(insDst->Name,"stosb");
			if (ediIsSaved == 0 || hasRegisterVariables) {
				changedInstruction = GetNextChangedInstruction(insDst,bb);
				insDst->Flags |= ADDED;
				insDst->Flags &= ~ CHANGED;
				strcpy(changedInstruction->Name,"\tpopl");
				strcpy(changedInstruction->src,"\t%edi\n");
				State[EDX] = Nullst;
			}
			Printf1("Optimization 22\n");
			return(2);
		}
	}
skip1:
	State[EAX] = State[ECX] = State[EDX] = Nullst;
	Printf1("eax = ecx = edx = NULL\n");
	if (State[ESI] && *State[ESI] == '_') State[ESI] = Nullst;
	if (State[EDI] && *State[EDI] == '_') State[EDI] = Nullst;
	if (State[EBX] && *State[EBX] == '_') State[EBX] = Nullst;
	return 0;
}

static int FindStateChanges(void)
{
	int result;

	opcode = ins->Name;
	savesrc = src = ins->src;
	dst = ins->dst;
	regdst = regsrc = isImmediate = aReg = 0;
	result = 1;
	assert((ins->Flags & TRUNCATED)==0);
	if (ins->Flags & DELETED) return result;
	if (ins->Flags & CHANGED) {
		src = InstructionTable[ins->ChangedIdx].src;
		dst = InstructionTable[ins->ChangedIdx].dst;
	}
	nextIns = &InstructionTable[idxInstruction+1];
	lastIns = &InstructionTable[idxInstruction-1];
	if (*dst == '%') {
		dst++;
		regdst = 1;
	}
	if (*src == '%') {
		src++;
		regsrc = 1;
	}
	else if (*src == '$')
		isImmediate = 1;
	isRedundant = 0;
	isMovl = (ins->Flags & ISMOVL)?1:0;
	if (dst[0] == '(') {
		/*
		replace
		mov	%esi	(,%edi)
		mov	(,%edi)	%esi
		*/
		if ( isMovl && nextIns->src[0] == '(' && !strcmp(src,nextIns->src)) {
			if (!strcmp(ins->src,nextIns->dst)) {
				nextIns->Flags |= DELETED;
				Printf1("Optimization 37\n");
				deleted++;
				result++;
			}
			else if (regsrc) {
				ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,nextIns->dst);
			}
		}
		return result;
	}
	/*
	replace
	mov %ecx;%esi
	mov %esi,%ecx
	*/
	if (isMovl && regsrc && regdst &&
		ins->SrcReg < EBP &&
		(nextIns->Flags &(CHANGED|DELETED)) == 0) {

		if ((nextIns->Flags & ISMOVL) &&
			nextIns->src[0] == '%' && nextIns->dst[0] == '%') {
			if (ins->DstReg == nextIns->SrcReg &&
				ins->SrcReg == nextIns->DstReg) {
				State[ins->DstReg] = Nullst;
				nextIns->Flags |= DELETED;
				deleted++;
				return 2;
			}
		}
	}
	if (regdst && isMovl) {
		if (ins->SrcReg == ins->DstReg) {
			if (regsrc && !strcmp(src,dst)) {
					ins->Flags |= DELETED;
					deleted++;
					return result;
			}
		}
		/*
		replace
		movl %edx,%esi
		movl (,%esi),%esi
		with
		movl (,%edx),%esi
		*/
		if (regsrc && nextIns->dst[0] == '%' &&
			!strcmp(ins->dst,nextIns->dst) &&
			*(unsigned long *)(nextIns->Name) == MOVL_CODE &&
			(nextIns->Flags &(CHANGED|DELETED)) == 0 &&
			ins->src[0] == '%' &&
			nextIns->SrcReg == ins->DstReg ) {

			doreplace(nextIns->src,ins->dst+1,ins->src+1,tbuf);
			ChangeInstruction(nextIns,bb,nextIns->Name,tbuf,nextIns->dst);
			ins->Flags |= DELETED;
			deleted++;
			State[ins->DstReg] = Nullst;
#if 0
			printf("move optimization %s %s,%s -> %s %s,%s = %s %s,%s\n",
				ins->Name,ins->src,ins->dst,
				nextIns->Name,nextIns->src,nextIns->dst,
				pins->Name,pins->src,pins->dst
				);
#endif
			return 2;
		}
		if (!regsrc && !isImmediate) {
			if (State[EAX] && !strcmp(src,State[EAX])) {
				Printf2("%s was in eax\n",State[EAX]);
				if (ins->DstReg == EAX) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = EAX;
				}
			}
			if (State[EBX] && !strcmp(src,State[EBX])) {
				Printf2("%s was in ebx\n",State[EBX]);
				if (ins->DstReg == EBX) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = EBX;
				}
			}
			if (State[ECX] && !strcmp(src,State[ECX])) {
				Printf2("%s was in ecx\n",State[ECX]);
				if (ins->DstReg == ECX) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = ECX;
				}
			}
			if (State[EDX] && !strcmp(src,State[EDX])) {
				Printf2("%s was in edx\n",State[EDX]);
				if (ins->DstReg == EDX) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = EDX;
				}
			}
			if (State[ESI] && !strcmp(src,State[ESI])) {
				Printf2("%s was in esi\n",State[ESI]);
				if (ins->DstReg == ESI) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = ESI;
				}
			}
			if (State[EDI] && !strcmp(src,State[EDI])) {
				Printf2("%s was in edi\n",State[EDI]);
				if (ins->DstReg == EDI) {
					ins->Flags |= DELETED;
					deleted++;
				}
				else {
					redundant++;
					isRedundant = EDI;
				}
			}
			if (isRedundant && 
				src[0] != '$' && (ins->Flags & (CHANGED|DELETED)) == 0) {
				ChangeRedundantLoad(ins,isRedundant,bb,idxInstruction);
			}
		}
		if (ins->Flags & DELETED)
			return(result);
		if (isRedundant == 0 &&
			regsrc == 0 &&
			(ins->Flags & SRCDEREFERENCE) == 0 &&
			((ins->Flags & SRCOFFSET) == 0 || ins->SrcReg == EBP)) {
			State[ins->DstReg] == src;
		}
			
	}
	if (ins->DstReg > ESP) {
		if (ins->DstReg < SP+1) State[ins->DstReg-ESP] = Nullst;
		else if ((ins->Flags & ISGENERICMOVE) == 0) {
			int r;

			r = ins->DstReg & 0xFF;
			if (r < ESP) {
				State[r] = Nullst;
				Printf2("%s = NULL\n",RegisterNames[r]);
			}
			r = (ins->DstReg >> 8) & 0xFF;
			if (r < ESP) {
				State[r] = Nullst;
				Printf2("%s = NULL\n",RegisterNames[r]);
			}
		}
	}
	if (isMovl &&
		regsrc &&
		regdst &&
		isImmediate == 0 &&
		(ins->Flags&CHANGED) == 0 &&
		ins->SrcReg < EBP &&
		ins->DstReg < EBP) {
		int i = RegToRegCopy();
		if (i) return i;
	}
	/*
	This should have taken into account the fact that after an
	orl	%eax,%eax
	jne _$label
	%eax is zero. Then any 'xor %eax,%eax' after this can be deleted
	The results are disappointing. 210 bytes gained from 543188...
	*/
	if (isMovl == 0 && regsrc && regdst
		&& ins->SrcReg == ins->DstReg
		&& opcode[0] == 'o' && opcode[1] == 'r'
		&& (opcode[2] == 0 || opcode[2] == 'l')
		&& ins->SrcReg < EBP) {
		if ((nextIns->Flags & (CHANGED|DELETED)) == 0
			&& !strcmp(nextIns->Name,"jne")) {
			Instruction *tmpins = nextIns;
			nextIns++;
			if ((nextIns->Flags & (CHANGED|DELETED)) == 0) {
				if (nextIns->SrcReg == ins->SrcReg &&
					nextIns->DstReg == ins->SrcReg &&
					nextIns->src[0] == '%' &&
					nextIns->dst[0] == '%' &&
					!strcmp(nextIns->Name,"xor")) {
					nextIns++;
					if (strcmp(nextIns->Name,"jmp")) {
						nextIns--;
						nextIns->Flags |= DELETED;
						deleted++;
						Printf1("Optimization 47\n");
					}
					else {
						// This is ridiculous. Changed from
						// 542968 to 542924: 44 bytes saved only!
						// should be faster though, since a jump is saved
						if (!strncmp(nextIns->End,tmpins->src,strlen(tmpins->src))
							&& ins->SrcReg == EAX) {
							int lab = atoi(nextIns->src+2);
							if (lab == lastLabel) {
								ChangeInstruction(tmpins,bb,"je",nextIns->src,"");
								nextIns--;
								nextIns->Flags |= DELETED;
								deleted++;
								nextIns++;
								nextIns->Flags |= DELETED;
								deleted++;
								return(4);
							}
						}
					}
				}
				else if (nextIns->src[0] == '$' &&
					nextIns->src[1] == '0' &&
					nextIns->src[2] == 0 &&
					(!strcmp(nextIns->Name,"movl") || (nextIns->Flags & ISCOMPARE))) {
					ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,nextIns->dst);
					Printf1("Optimization 47\n");
					return(3);
				}
			}
		}
		return(result);
	}
	if (isMovl == 0){
		int r;

		if (ins->Flags & ISCOMPARE)
			return compare();
		else if (ins->Name[0] == 'c' && ins->Name[1] == 'm' &&
			ins->Name[2] == 'p') {
			r = ImproveSetEqual(0);
			if (r) return r;
		}
	}

	if ((ins->Flags & ISGENERICMOVE) == 0) {
		/* delete additions and substractions of zero */
		if ((ins->Flags & (CHANGED|DELETED))==0 &&
			(opcode[0] == 'a' && opcode[1] == 'd' && opcode[2] == 'd') ||
			(opcode[0] == 's' && opcode[1] == 'u' && opcode[2] == 'b')) {
			int reg;
			if (isImmediate && src[1] == '0') {
				if (src[2] == 0 || (src[2] == 'x' && src[3] == '0' && src[4] == 0)) {
					ins->Flags |= DELETED;
					return result;
				}
			}
#if 1
			if (!isImmediate && !regsrc) {
				reg = CheckValueAlreadyLoaded(ins->src);
				if (reg) {
					sprintf(tbuf,"%%%s",RegisterNames[reg]);
					ChangeInstruction(ins,bb,ins->Name,tbuf,ins->dst);
				}
			}
#endif
			lastIns = GetLastInstruction(idxInstruction);
			/*
				Replace
				addl	$-1,reg
				by
				inc		reg
			*/
			if (((ins->Flags & CHANGED) == 0) && isImmediate && src[1] == '-'
				&& src[2] == '1' && src[3] == 0) {
				unsigned char *op;
				if (regdst) {
					tbuf[0] = '%';
					strcpy(tbuf+1,dst);
				}
				else strcpy(tbuf,dst);
				if (*opcode == 'a')
					op = "decl";
				else
					op = "incl";
				if (*dst != '%') doclobber(dst,10000);
				ChangeInstruction(ins,bb,op,tbuf,"");
				Printf1("addl/subl->inc/dec\n");
			}
			else
			/*
				Replace postincrement from
					mov mem,reg1	load value
					mov reg1,reg2	save old value in reg2
					inc reg1		add offset
					mov reg1,mem	store updated value

					to

					mov	mem,reg1	load value
					inc reg1		add offset
					xchg reg1,mem	store new value AND reload old
			*/
			if ((ins->Flags & CHANGED) == 0 && recursion == 0 &&
				(ins->Flags & ISREGDST) &&
				isImmediate && idxInstruction >1) {
				if ((lastIns->Flags & ISREGSRC) && (lastIns->Flags & ISREGDST)
					&& (lastIns->Flags & ISMOVL) &&
					lastIns->DstReg == ins->DstReg &&
					!IsAliveValue(bb,idxInstruction+2,ins->DstReg)) {
					Instruction *tmp;

					tmp = lastIns - 1;
					if (((tmp->Flags & CHANGED)==0) &&
						(tmp->Flags & ISMOVL) &&
						(tmp->Flags & ISREGSRC) == 0 &&
						tmp->DstReg == lastIns->SrcReg) {

						if ((nextIns->Flags & ISREGSRC) && !strcmp(tmp->src,nextIns->dst)) {
							unsigned char *srcC;
							if (lastIns->Flags & CHANGED) {
								srcC = InstructionTable[lastIns->ChangedIdx].src;
							}
							else
								srcC = lastIns->src;
							lastIns->Flags |= DELETED;
							deleted++;
							tmp->Flags &= ~DELETED;
							if (opcode[0] == 's') {
								sprintf(tbuf,"$-%s",src+1);
							}
							else strcpy(tbuf,src);
							ChangeInstruction(tmp,bb,"movl",nextIns->dst,srcC);
							insDst = ChangeInstruction(ins,bb,"add",tbuf,nextIns->dst);
							nextIns->Flags |= DELETED;
							deleted++;
							doclobber(insDst->src,10000);
							if (lastIns->SrcReg < ESP)
								State[lastIns->SrcReg] = Nullst;
							Printf3("%s = %s = NULL\n",RegisterNames[lastIns->SrcReg],
								RegisterNames[lastIns->DstReg]);
							Printf1("Optimization 13 (postincrement)\n");
							return(result+1);
						}
					}
					else if ((lastIns->Flags & CHANGED) == 0 &&
						!hasRegisterVariables) {
						unsigned char *minus;

						if (opcode[0] == 's') minus = "-";
						else minus = "";
						sprintf(tbuf,"%s%s(%s)",minus,ins->src+1,lastIns->src);
						ChangeInstruction(ins,bb,"leal",tbuf,ins->dst);
						lastIns->Flags |= DELETED;
						delete

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -