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

📄 optim.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
		if (ins->Flags & (ISCALL|CHANGED)) return(0);
		if (ins->DstReg == ECX || ins->DstReg == EDX)
			return(0);
		if (ins->SrcReg == ECX || ins->SrcReg == EDX)
			return(0);
		if (ins->Name[2] == 'q' && ins->Name[1] == 'd')
			return(0);
		if (ins->Name[0] == 'r' && ins->Name[1] == 'e' && ins->Name[2] == 'p')
			return(0);
		if (ins->Name[0] == 's' && ins->Name[1] == 'h' && ins->Name[3] == 'l')
			return(0);
		if (ins->src[0] == '%' && ins->src[1] == 'c')
			return(0);
		if (ins->dst[0] == '%' && (ins->Flags & ISGENERICMOVE) && ins->DstReg == aReg) {
			if (ins->SrcReg != aReg)
				break;
		}
		ins++;
		idxInstruction++;
	}
	return(result);
}

static int TestIfReturnFalse(Instruction *nextIns,int regNum)
{
	nextIns++;
	if (*(unsigned long *)(nextIns->Name) == JNE_CODE) {
		nextIns++;
		if (nextIns->Flags & ISMOVL) {
			if (nextIns->src[0] == '$' && nextIns->src[1] == '0'
				&& nextIns->src[2] == 0) {
				if (nextIns->dst[0] == '%' && nextIns->DstReg == regNum) {
					nextIns->Flags |= DELETED;
					Printf1("Optimization 12\n");
					return(1);
				}
			}
		}
	}
	return(0);
}

static void ChangeRedundantLoad(Instruction *ins,int regNum,BasicBlock *bb,int idxInstruction)
{
	unsigned char *regname,tbuf[60];
	Instruction *insDst,*nextIns;

	nextIns = &InstructionTable[idxInstruction+1];
	regname = RegisterNames[regNum];
	if (strlen(ins->src) <4) return;
	if (ins->DstReg > EBP) return;
	if (*(unsigned long *)(ins->Name) != MOVL_CODE) {
		/*
			We can use this byte widening instructions only with memory
			references. I assume that the compiler widens the arguments always
			before loading a register with a 16 or 8 bit value, a safe
			assumption I suppose.
		*/
//		strcpy(insDst->Name,"movl"); /*++++++++++++++++++*/
		return;
	}
	insDst = GetNextChangedInstruction(ins,bb);
	strcpy(insDst->Name,ins->Name);
	/* Print the regname into the source of the changed instruction */
	sprintf(tbuf,"%%%s",regname);
	strcpy(insDst->src,tbuf);
	/* The destination doesn't change */
	strcpy(insDst->dst,ins->dst);
	/* Update flags etc */
	ins->SrcReg = regNum;
	Printf1("Optimization 5\n");
}

static int ReadValue(unsigned char *src)
{
	int result,r;

	if (src[0] == '0' && (src[1] == 'x' || src[1] == 'X')) {
		r = sscanf(src+2,"%x",&result);
	}
	else {
		r = sscanf(src,"%d",&result);
	}
	if (r) return(result);
	return(0);
}

static Instruction *GetLastInstruction(int idxInstruction)
{
	int li = idxInstruction;
	Instruction *lastIns = NULL;

	do {
		li--;
		lastIns = &InstructionTable[li];
	} while (li >= 0 && (lastIns->Flags & DELETED));
	if (li >= 0) return(lastIns);
	return(NULL);
}

static int CheckValueAlreadyLoaded(unsigned char *p)
{
	if (State[EAX] && !strcmp(State[EAX],p)) {
		return(EAX);
	}
	if (State[EBX] && !strcmp(State[EBX],p)) {
		return(EBX);
	}
	if (State[ECX] && !strcmp(State[ECX],p)) {
		return(ECX);
	}
	if (State[EDX] && !strcmp(State[EDX],p)) {
		return(EDX);
	}
	if (State[ESI] && !strcmp(State[ESI],p)) {
		return(ESI);
	}
	if (State[EDI] && !strcmp(State[EDI],p)) {
		return(EDI);
	}
	return(0);
}

void FixCalls(Instruction *ins,BasicBlock *bb,int idxInstruction)
{
	int last,i,first;

	ins->Flags &= ~ISCALL;
	if (idxInstruction == bb->LastCall) {
		if (bb->FirstCall == idxInstruction) {
			bb->FirstCall = bb->LastCall = 0;
			return;
		}
		last = bb->FirstCall;
		for (i=bb->FirstCall+1;i<idxInstruction-1;i++) {
			if (InstructionTable[i].Flags & ISCALL)
				last = i;
		}
		if (last == bb->FirstCall) {
			bb->FirstCall = bb->LastCall = 0;
			return;
		}
		bb->LastCall = last;
		return;
	}
	if (idxInstruction == bb->FirstCall) {
		if (bb->LastCall == idxInstruction) {
			bb->FirstCall = bb->LastCall = 0;
			return;
		}
		first = 0;
		for (i=bb->FirstCall+1;i<bb->LastCall;i++) {
			if (InstructionTable[i].Flags & ISCALL) {
				first = i;
				break;
			}
		}
		bb->FirstCall = first;
		if (first == 0) bb->LastCall = 0;
		return;
	}
}
static char tbuf[70];
static unsigned char *src;
static unsigned char *dst;
static unsigned char *opcode;
static unsigned char *old,*savesrc;
static int regdst,regsrc,isImmediate;
static int aReg,isMovl,isRedundant;
static Instruction *insDst,*lastIns,*changedInstruction,*nextIns;
static Instruction *ins;
static BasicBlock *bb;
static int idxInstruction;

static int RegToRegCopy(void)
{
	/* Replace
	movl %eax,%edi
	movl %edi,-24(%ebp)

	with
	movl %eax,-24(%ebp)

	*/
	if (nextIns->Flags & CHANGED) return 0;
	if (nextIns->SrcReg == ins->DstReg) {
		if (ins->DstReg != EAX &&
		*(unsigned long *)(ins->Name) == MOVL_CODE &&
		*(unsigned long *)(nextIns->Name) == MOVL_CODE && 
		nextIns->SrcReg != nextIns->DstReg &&
		nextIns->src[0] == '%') {
		if (!IsAliveValue(bb,idxInstruction+2,ins->DstReg)) {
			insDst = ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,nextIns->dst);
			nextIns->SrcReg = ins->SrcReg;
			ins->Flags |= DELETED;
			deleted++;
			Printf1("Optimization 18\n");
//		  printf("1:\t%s\t%s\t%s\n2:\t%s\t%s\t%s\n3:\t%s\t%s\t%s\n",ins->Name,ins->src,ins->dst,
//			nextIns->Name,nextIns->src,nextIns->dst,insDst->Name,insDst->src,insDst->dst);
			State[ins->SrcReg] = nextIns->dst;
			return 2;
		}
		}
		if (!strcmp(ins->dst,nextIns->src) &&
			*(unsigned long *)(nextIns->Name) == PUSH_CODE &&
			!IsAliveValue(bb,idxInstruction+2,ins->DstReg)) {
				ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,"");
				ins->Flags |= DELETED;
				deleted++;
				return 2;
		}
	}
   /* Try to catch sequences like
		movl %eax,%edi
		cmpl $45, %edi
		and replace them with
		cmpl $45,%eax
   */
   if ((nextIns->Flags & ISCOMPARE) &&
		nextIns->src[0] == '$' && nextIns->dst[0] == '%' &&
		nextIns->DstReg != EAX &&
		!strcmp(nextIns->dst,ins->dst) &&
		!IsAliveValue(bb,idxInstruction+2,ins->DstReg)) {
		insDst = ChangeInstruction(nextIns,bb,nextIns->Name,nextIns->src,ins->src);
		ins->Flags |= DELETED;
		nextIns->DstReg = ins->SrcReg;
		Printf1("Optimization 17\n");
		deleted++;
		return 2;
	}
	return 0;
}
static int ImproveSetEqual(int islong)
{
	int wasxchg=0,condition;
	Instruction *next = nextIns;

//	if (recursion) return 0;
	if (!strcmp(nextIns->Name,"xchgl")) {
		wasxchg = 1;
		next++;
	}
	if (next->Name[0] == 's' && next->Name[1] == 'e') {
		int idx = idxInstruction+2;
		Instruction *i1 = &InstructionTable[idx+wasxchg*2];
		char *pdst = i1->dst;


		if (i1->src[0] == '$' && i1->src[1] == '1' &&
			(*(unsigned long *)(i1->Name) == ANDL_CODE)) {
			if (islong)
				condition = (!strstr(ins->src,pdst)) && (!strstr(ins->dst,pdst));
			else {
				char tmpregname[5];

				tmpregname[0] = '%';
				tmpregname[1] = pdst[2];
				tmpregname[2] = pdst[3];
				tmpregname[3] = 0;
				condition = (!strstr(tmpregname,ins->src) && !strstr(tmpregname,ins->dst));
				if (condition && tmpregname[2] != 'i') {
					tmpregname[2] = 'l';
					condition = (condition &&
						(!strstr(tmpregname,ins->src) && !strstr(tmpregname,ins->dst)));
				}
			}
			if (condition) {
				Instruction *changedIns = GetNextChangedInstruction(ins,bb);
				Instruction *i2 = GetNextChangedInstruction(changedIns,bb);

				sprintf(i2->Name,"\t%s\t",ins->Name);				
				strcpy(i2->src,ins->src);
				sprintf(i2->dst,",%s\n",ins->dst);
				changedIns->Flags &= ~ CHANGED;
				changedIns->Flags |= ADDED;
				strcpy(changedIns->Name,"xorl");
				strcpy(changedIns->src,pdst);
				strcpy(changedIns->dst,pdst);
				i1->Flags |= DELETED;
				deleted++;
				State[i1->DstReg] = Nullst;
//				printf("cmpl %s %s -> %s\n",ins->src,ins->dst,pdst);
				i1++;
				if (!strcmp(i1->Name,"cmpl") && !strcmp(i1->src,"$0") &&
					!strcmp(i1->dst,pdst)) {
					i1->Flags |= DELETED;
					deleted++;
					return 4;
				}
				return 3;
			}
		}
	}
	return 0;
}
int TestIfFlagsAlreadySet(Instruction *tmpins)
{
      int idx = idxInstruction;
	  unsigned long opcodeCode = *(unsigned long *)(tmpins->Name);
      if (tmpins) {
              while (idx > 0 && 
				  (opcodeCode == MOVL_CODE || opcodeCode == MOVW_CODE) &&
                      strcmp(tmpins->dst,ins->dst)) {
                      idx--;
                      tmpins--;
					opcodeCode = *(unsigned long *)(tmpins->Name);
              }
              if ((opcodeCode == SUBL_CODE
                      || opcodeCode == ADDL_CODE
                      || opcodeCode == SARL_CODE
                      || opcodeCode == ANDL_CODE) &&
                      !strcmp(tmpins->dst,ins->dst))  {
                      ins->Flags |= DELETED;
                      deleted++;
//                      printf("redundant compare deleted: last ins:%s\n",tmpins->Name);
                      return 1;
              }
      }
      return 0;
}
#if 0
static int OptimizeImul(void)
{
	char *p = strchr(ins->dst,',');
	int reg1,reg2,val,val3,val5,val9,n;
	char tregname[10],tbuf0[50],tbuf1[50];
	Instruction *ChangedIns,*addedIns;

	if (p == NULL)
		return 0;
	if (ins->dst[0] != '%')
		return 0;
	*p = 0;
	strcpy(tregname,ins->dst);
	*p++ = ',';
	if (*p != '%')
		return 0;
	reg1 = GetRegNumber(tregname+1);
	reg2 = GetRegNumber(p+1);
	if (reg1 > EBP || reg2 > EBP)
		return 0;
	val = ReadValue(ins->src+1);
	if (val < 0)
		return 0;
	if ((val % 5) != 0 && (val % 9) != 0 && (val % 3) != 0)
		return 0;
	if ((val % 5) == 0) {
		val5 = val/5;
		n = ispow2(val5);
		if (n || val == 5) {
			sprintf(tbuf0,"(%s,%s,4)",tregname,tregname);
			ChangedIns = ChangeInstruction(ins,bb,"leal",tbuf0,p);
			State[reg2] = Nullst;
			if (val == 5)
				return 1;
commonTail:
			addedIns = GetNextChangedInstruction(ChangedIns,bb);
			ChangedIns->Flags &= ~CHANGED;
			ChangedIns->Flags |= ADDED;
			strcpy(addedIns->Name,"\tshll\t");
			sprintf(tbuf1,"$%d,",n);
			strcpy(addedIns->src,tbuf1);
			sprintf(addedIns->dst,"%s\n",p);
			return 1;
		}

	}
	if ((val % 9) == 0) {
		val9 = val/9;
		n = ispow2(val9);
		if (n || val == 9) {
			sprintf(tbuf0,"(%s,%s,8)",tregname,tregname);
			ChangedIns = ChangeInstruction(ins,bb,"leal",tbuf0,p);
			State[reg2] = Nullst;
			if (val == 9)
				return 1;
			goto commonTail;
		}
	}
	if ((val % 3) == 0) {
		val3 = val/3;
		n = ispow2(val3);
		if (n || val == 3) {
			sprintf(tbuf0,"(%s,%s,2)",tregname,tregname);
			ChangedIns = ChangeInstruction(ins,bb,"leal",tbuf0,p);
			State[reg2] = Nullst;
			if (val == 3)
				return 1;
			goto commonTail;
		}
	}
	return 0;
}
#endif
static int compare(void)
{
	int reg;

	if (ins->Flags & (CHANGED|DELETED))
		return 1;
	reg = ImproveSetEqual(1);
	if (reg) return reg;
	/*
		replace
		cmpl $0,reg
		by
		or reg,reg
	*/
	if (regdst && !regsrc && isImmediate && src[1] == '0' && src[2] == 0) {
		if (TestIfFlagsAlreadySet(lastIns))
			  return 1;
		sprintf(tbuf,"%%%s",dst);
		ChangeInstruction(ins,bb,"or",tbuf,tbuf);
		Printf1("compl->or\n");
		TestIfReturnFalse(ins,ins->DstReg);
		return(1);
	}
	lastIns = GetLastInstruction(idxInstruction);
	if (!regdst /*&& isImmediate*/ && ins->Name[3] == 'l') {
		reg = CheckValueAlreadyLoaded(ins->dst);
		if (reg) {
			sprintf(tbuf,"%%%s",RegisterNames[reg]);
			if (isImmediate && ins->src[1] == '0' && ins->src[2] == 0) {
				ChangeInstruction(ins,bb,"orl",tbuf,tbuf);
			}
			else ChangeInstruction(ins,bb,ins->Name,ins->src,tbuf);
			Printf1("Optimization 44\n");
			return 1;
		}
	}
	/*
	Try to change a sequence of dword compares into a sequence of byte compares
	*/
	if (idxInstruction > 1 &&
		regdst && isImmediate && ins->Name[3] == 'l' &&
		(lastIns->Flags & (CHANGED|DELETED)) == 0) {
		if (!strcmp(lastIns->Name,"movsbl") ||
			!strcmp(lastIns->Name,"movzbl")) {
			if (!strcmp(lastIns->dst,ins->dst) &&
				isByteValue(ins->src)) {
				Instruction *i1,*i2;
				int idx,alive,changeAll,toChange,i,val;
				char dstByteReg[10];

				val = ReadValue(&ins->src[1]);
				if (val > 127 || val < 0) return 1;
				if (nextIns->Name[0] != 'j') {
					ChangeInstruction(ins,bb,"cmpb",ins->src,ins->dst);
					return 1;
				}
				if (ins->DstReg != EAX && ins->DstReg != EDX && ins->DstReg != EBX
					&& ins->DstReg != ECX) return 1;
				idx = idxInstruction+2;
				i1 = &InstructionTable[idx];
				changeAll = 1;
				while (idx < bb->NrOfInstructions && (i1->Flags & ISCOMPARE)) {
					if (i1->src[0] != '$') break;
					if (strcmp(ins->dst,i1->dst)) break;
					val = ReadValue(&i1->src[1]);
					if (val > 127 || val < 0)
						break;
					idx++;
					i1++;
					if (i1->Name[0] != 'j') { changeAll = 0; break; }
					idx++;
					i1++;
				}
				alive = IsAliveValue(bb,idx,ins->DstReg);
				toChange = idx - idxInstruction;
				dstByteReg[0] = '%';
				dstByteReg[1] = ins->dst[2];
				dstByteReg[2] = 'l';
				dstByteReg[3] = 0;
				if (changeAll) {
					if (!alive)
					ChangeInstruction(lastIns,bb,"movb",lastIns->src,dstByteReg);
					i2 = &InstructionTable[idxInstruction];
					for (i=idxInstruction;i < idx;i+=2,i2 += 2) {
						ChangeInstruction(i2,bb,"cmpb",i2->src,dstByteReg);
					}
					return toChange;
				}
				return 1;
			}
		}
	}

⌨️ 快捷键说明

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