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

📄 optim.c

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