示例#1
0
void RebuildFunc(SYMBOL *sym)
{
	OpcodeInfo thisOp;
	SYMBOL *ref;

	uchar *ip, *ip_end, *ip_last;
	
	int real_ip;
	char str[256];

	if (!sym)
		return;

	RebuildEmit("\n//****************************************\n");
	RebuildEmit("// Function: %s\n", sym->Name);
	RebuildEmit("//****************************************\n\n");

#if 0 //OLD
	if (strcmp(sym->Name, Code_EntryPoint) == 0)
	{
		RebuildEmit(".global %s\n", sym->Name);
		RebuildEmit(".func %s\n", sym->Name);
	}
	else
	{
		RebuildEmit(".func %s_%d\n", sym->Name, sym->LocalScope);
	}
#else //New

	if (strcmp(sym->Name, Code_EntryPoint) == 0)
	{
		RebuildEmit(".global %s\n", sym->Name);
		RebuildEmit(".func %s, %d, %s\n", sym->Name, sym->Params, RebuildRetType(sym->RetType) );
	}
	else
	{
		RebuildEmit(".func %s_%d, %d, %s\n", sym->Name, sym->LocalScope, sym->Params, RebuildRetType(sym->RetType));
	}

#endif

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);
	real_ip	= sym->Value;

	while(1)
	{
		ip_last = ip;
		
		if (ip > ip_end)
			break;

		// Print labels
		
		ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip);

		if (ref)
		{
			if (ref->LabelType == label_Local)
				RebuildEmit("%s_%d:\n", ref->Name, ref->LocalScope);
		}

		RebuildEmitStabs(real_ip);
	
//		Peeper(ip, ip_end);

		if (ArgSkipElim == 0)
			if (ArrayGet(&CodeTouchArray, real_ip) == 0)
				RebuildEmit("// ");

		CaseRef = 0;

		ip = DecodeOpcode(&thisOp, ip);
		DecodeAsmString(&thisOp, str, 1);
		RebuildEmit("\t%s", str);

//		DecodeAsmString(&thisOp, str, 0);			// Sanity testing
//		CodeSanityChecker(thisOp.rip, str);

		if (ArgDebugRebuild)
		{
			int len = 4 + strlen(str);		
			str[0] = 0;
			
			while(len < 40)
			{
				RebuildEmit(" ", str);
				len++;
			}
			
			RebuildEmit("; 0x%x - ", real_ip);
			
			DisassembleFromSource(real_ip, str);
			RebuildEmit("%s", str);
		}

		RebuildEmit("\n");

		// Check for case statement, which need case data after them
		
		if (CaseRef)
		{
			RebuildEmit(".data\n");
			Rebuild_Data(CaseRef);
			RebuildEmit(".code\n");
		}

		real_ip += (ip - ip_last);	
	}
}
示例#2
0
int RebuildCppInst(OpcodeInfo *theOp)
{
	int ip = theOp->rip;
	char str[256];

#ifdef CPP_DEBUG
	str[0] = 0;
	DisassembleFromSource(ip, str);
	RebuildEmit("\t\t\t\t\t\t//%s\n", str);
#endif


#ifdef CPP_SHOW_LINES
	{
		int line = ArrayGet(&SLD_Line_Array, ip);
		int file = ArrayGet(&SLD_File_Array, ip);

		if(line!=0) {
			RebuildEmit("\n	// %s:%d\n", GetFileNumString(file), line);
			RebuildEmit("	// %s\n", GetFileLine(file, line));
		}
	}
#endif

	switch (theOp->op)
	{
		case _PUSH:
			RebuildEmit("	//push %s,%d\n",Cpp_reg[theOp->rd], theOp->rs);

			if (REGUSED(funcprop.reg_used, REG_sp))
			{
				RebuildEmit("	sp -= %d;\n",theOp->rs*4);
			}
		return 1;

		case _POP:
			RebuildEmit("	//pop  %s,%d\n",Cpp_reg[theOp->rd], theOp->rs);

			if (REGUSED(funcprop.reg_used, REG_sp))
			{
				RebuildEmit("	sp += %d;\n",theOp->rs*4);
			}

		return 1;

		case _CASE:
			CppDecodeSwitch(theOp);
		break;


		case _CALLI:
			CppDecodeCall(theOp);
		break;

		case _SYSCALL:
			CppDecodeSysCall(theOp);
		break;

		case _CALL:
			CppDecodeCallReg(theOp);
		break;

		case _LDI:
			RebuildEmit("	%s = 0x%x;", Cpp_reg[theOp->rd], theOp->imm);
		break;

		case _LDR:
		{
			if (IsRegConst(theOp->rs))
				RebuildEmit("	%s = 0x%x;", Cpp_reg[theOp->rd], ConstRegValue(theOp->rs));
			else
				RebuildEmit("	%s = %s;", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		}
		break;

		// Arithmatic

		case _ADD:
			CppEmitArith(theOp,"+", 0);
		break;

		case _ADDI:
			CppEmitArith(theOp,"+", 1);
		break;

		case _MUL:
			CppEmitArith(theOp,"*", 0);
		break;

		case _MULI:
			CppEmitArith(theOp,"*", 1);
		break;

		case _SUB:
			CppEmitArith(theOp,"-", 0);
		break;

		case _SUBI:
			CppEmitArith(theOp,"-", 1);
		break;

		case _AND:
			CppEmitArith(theOp,"&", 0);
		break;

		case _ANDI:
			CppEmitArith(theOp,"&", 1);
		break;

		case _OR:
			CppEmitArith(theOp,"|", 0);
		break;

		case _ORI:
			CppEmitArith(theOp,"|", 1);
		break;

		case _XOR:
			CppEmitArith(theOp,"^", 0);
		break;

		case _XORI:
			CppEmitArith(theOp,"^", 1);
		break;

		case _DIVU:
			CppEmitDivu(theOp, 0);
		break;

		case _DIVUI:
			CppEmitDivu(theOp, 1);
		break;

		case _DIV:
			CppEmitArith(theOp,"/", 0);
		break;

		case _DIVI:
			CppEmitArith(theOp,"/", 1);
		break;

		// Shifts

		case _SLL:
			CppEmitShift(theOp,"<<", 0, 0);
		break;

		case _SLLI:
			CppEmitShift(theOp,"<<", 1, 0);
		break;

		case _SRA:
			CppEmitShift(theOp,">>", 0, 0);
		break;

		case _SRAI:
			CppEmitShift(theOp,">>", 1, 0);
		break;

		case _SRL:
			CppEmitShift(theOp,">>", 0, 1);		// Unsigned
		break;

		case _SRLI:
			CppEmitShift(theOp,">>", 1, 1);		// Unsigned
		break;

		case _NOT:
			RebuildEmit("	%s = ~%s;", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		break;

		case _NEG:
			RebuildEmit("	%s = -%s;", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		break;

		case _RET:
		{
			if (ThisFunctionExit == 0)	// Don't output a return jump on last instruction
			{
				RebuildEmit("	goto label_0;	// return");
				ReturnCount++;
			}
		}
		break;

		// Conditional jumps

		case _JC_EQ:
			CppEmitJumpCond(theOp, "==", 0);
		break;

		case _JC_NE:
			CppEmitJumpCond(theOp, "!=", 0);
		break;

		case _JC_GE:
			CppEmitJumpCond(theOp, ">=", 0);
		break;

		case _JC_GEU:
			CppEmitJumpCond(theOp, ">=", 1);
		break;

		case _JC_GT:
			CppEmitJumpCond(theOp, ">", 0);
		break;

		case _JC_GTU:
			CppEmitJumpCond(theOp, ">", 1);
		break;

		case _JC_LE:
			CppEmitJumpCond(theOp, "<=", 0);
		break;

		case _JC_LEU:
			CppEmitJumpCond(theOp, "<=", 1);
		break;

		case _JC_LT:
			CppEmitJumpCond(theOp, "<", 0);
		break;

		case _JC_LTU:
			CppEmitJumpCond(theOp, "<", 1);
		break;

		case _JPI:
			CppDecodeLabel(theOp, "	goto label_%d;");
		break;

		// Memory instructions

		case _LDW:
			Cpp_LoadMem(theOp, "RINT");
		break;

		case _LDH:
			Cpp_LoadMem(theOp, "RSHORT");
		break;

		case _LDB:
			Cpp_LoadMem(theOp, "RBYTE");
		break;

		case _STW:
			Cpp_StoreMem(theOp, "WINT");
		break;

		case _STH:
			Cpp_StoreMem(theOp, "WSHORT");
		break;

		case _STB:
			Cpp_StoreMem(theOp, "WBYTE");
		break;

		case _XB:
			RebuildEmit("	%s = (int)((char) %s);", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		break;

		case _XH:
			RebuildEmit("	%s = (int)((short) %s);", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		break;

		default:
			str[0] = 0;
			DisassembleFromSource(ip, str);
			ErrorOnIP(Error_Fatal, ip, "Missing instruction in Cpp rebuilder '%s'\n", str);
	}

	//	ArraySet(&SLD_Line_Array, CodeIP, line);
	//	ArraySet(&SLD_File_Array, CodeIP, This_SLD_File);

//	RebuildEmit("\n");

	RebuildEmit("\n");

#ifdef LOG_REGISTER_STATE_CHANGES
	if (funcprop.reg_used)
	{
		/*
		int n;
		for (n=0;n<32;n++)
		{
			if (reg_used & (1 << n))
			{
				RebuildEmit("if(last_%s != %s) { LOG_REGISTER(%s); last_%s = %s;}\n", Cpp_reg[n], Cpp_reg[n], Cpp_reg[n], Cpp_reg[n], Cpp_reg[n]);
			}
		}
		RebuildEmit(";\n\n");
		*/
		RebuildEmit("\tLOG_REGISTER_STATE_CHANGES(0x%x)\n", funcprop.reg_used);
	}
#endif


	return 1;
}
示例#3
0
int FunctionRegAnalyse(SYMBOL *sym, FuncProp *fp)
{
	OpcodeInfo thisOp;
	uchar *ip, *ip_end;
	int params,n;

	fp->src_reg = 0;
	fp->dst_reg = 0;
	fp->assign_reg = 0;
	fp->uninit_reg = 0;
	
	// Make sure we have a valid symbol
	
	if (!sym)
		return -1;

	// Make sure the symbol is a function

	if (sym->Type != SECT_code)
		return -1;

	// Get the start and end of the function in the code array

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);

	// Set up the parameter regs
	
	params = sym->Params;
	
	for (n=0;n<params;n++)
	{
		fp->assign_reg |=  REGBIT(REG_i0 + n);
	}
	
	// Scan the function

#ifdef AFDEBUG
	printf("\n");
#endif

	while(1)
	{		
		if (ip > ip_end)
			break;

#ifdef AFDEBUG
		{
			char buf[2560];
			buf[0] = 0;
			DisassembleFromSource(ip - CodeMemArray.array, buf);
			printf("%s\n", buf);
		}
#endif
	
		ip = DecodeOpcode(&thisOp, ip);

		// Ignor push and pop
		
		if (thisOp.op == _PUSH)
			continue;

		if (thisOp.op == _POP)
			continue;

		//-----------------------------------------
		// Deal with syscalls
		// for some strange reason rd is the syscallId which will
		// tag unused registers as used for void functions
		//-----------------------------------------

		if(thisOp.op == _SYSCALL)
		{
			FunctionReg_Syscall(&thisOp, fp);
		}

		// Check for a dest reg		
		else if (thisOp.flags & fetch_d)
		{
			if (thisOp.rd < 32)
			{
				// Since this is a dst regs we say its initialized
				fp->assign_reg |=  REGBIT(thisOp.rd);
	
				// Say this reg was used as a dst reg
				fp->dst_reg |= REGBIT(thisOp.rd);
			}
		}

		// Check for a source reg
		
		if (thisOp.flags & fetch_s)
		{
			if (thisOp.rs < 32)
			{
				// check if this reg was assigned previously, if it was'nt it is uninitialized before use
			
				int is_assigned = fp->assign_reg & REGBIT(thisOp.rs);
			
				if (!is_assigned)
					fp->uninit_reg |= REGBIT(thisOp.rs);
			
				fp->src_reg |= REGBIT(thisOp.rs);
			}
		}

		//-----------------------------------------
		//		Deal with immediate calls
		//-----------------------------------------
		
		// Add the call parameters to the used list

		if (thisOp.op == _CALLI)
		{

			FunctionReg_Calli(&thisOp, fp);
		}

		//-----------------------------------------
		//		Deal with register calls
		//-----------------------------------------
		
		// Add the call parameters to the used list

		if (thisOp.op == _CALL)
		{
			FunctionReg_CallReg(&thisOp, fp);
		}
	}


#ifdef AFDEBUG

	printf("\n");

	printf("                  rrrrrrrrrrrrrrrriiiiddddddddfrsz\n");
	printf("                  fedcba9876543210321076543210rtpr\n");

	printf("src_reg = %s\n", Bin32(fp->src_reg));
	printf("dst_reg = %s\n", Bin32(fp->dst_reg));
	printf("assign_reg    = %s\n", Bin32(fp->assign_reg));
	printf("uninit_reg      = %s\n", Bin32(fp->uninit_reg));

	if (fp->uninit_reg)
		printf("");

#endif

	// Make sure zr is never uninitialized
	
	fp->uninit_reg &= ~REGBIT(REG_zero);

	// Make a composit of which reg's were used

	fp->reg_used = fp->src_reg | fp->dst_reg;

	return fp->reg_used;
}
示例#4
0
void RebuildCppFunc(SYMBOL *sym, int isproto)
{
	OpcodeInfo thisOp;
	SYMBOL *ref;

	uchar *ip, *ip_end, *ip_last;

	int real_ip;
//	char str[256];

	if (!sym)
		return;

	// Say no returns yet

	ReturnCount = 0;

	// Enumerate this functions labels, unless we're generating a proto

	if (isproto	== 0)
		EnumerateFunctionLabels(sym);

	ThisFunctionRegs = FunctionRegUsage(sym);
	ThisFunctionRetType = sym->RetType;

	if (ThisFunctionRegs == -1)
		return;

	RebuildCppProlog(sym, isproto);

	// if we're generating a proto return

	if (isproto)
		return;

	ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP);
	ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value);
	real_ip	= sym->Value;

	while(1)
	{
		ip_last = ip;

		if (ip > ip_end)
			break;

		// Print labels

		ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip);

		if (ref)
		{
			if (ref->LabelType == label_Local)
			{
#ifdef Cpp_DEBUG
				RebuildEmit("// %s_%d:\n", ref->Name, ref->LocalScope);
#endif
				RebuildEmit("label_%d:;\n", ref->LabelEnum);
			}
		}

		if (ArrayGet(&CodeTouchArray, real_ip) == 0)
			RebuildEmit("// ");

		CaseRef = 0;

		ip = DecodeOpcode(&thisOp, ip);

		ThisFunctionExit = 0;

		if (ip > ip_end)
			ThisFunctionExit = 1;

		RebuildCppInst(&thisOp);

//		DecodeAsmString(&thisOp, str);
//		RebuildEmit("\t%s", str);

#ifdef CPP_DEBUG
		{
			int len = 4 + strlen(str);
			str[0] = 0;

			while(len < 40)
			{
				RebuildEmit(" ", str);
				len++;
			}

			DisassembleFromSource(real_ip, str);
			RebuildEmit(";%s", str);
		}
#endif

//		RebuildEmit("\n");

		// Check for case statement, which need case data after them

/*		if (CaseRef)
		{
			RebuildEmit(".data\n");
			Rebuild_Data(CaseRef);
			RebuildEmit(".code\n");
		}
*/
		real_ip += (ip - ip_last);
	}

	RebuildCppEpilog(sym);
}
示例#5
0
int RebuildJavaInst(OpcodeInfo *theOp)
{
	int ip = theOp->rip;
	char str[256];

#ifdef JRDEBUG
	str[0] = 0;
	DisassembleFromSource(ip, str);
	RebuildEmit("\t\t\t\t\t\t//%s\n", str);
#endif

	switch (theOp->op)
	{
		case _PUSH:
			RebuildEmit("	//push %s,%d\n",java_reg[theOp->rd], theOp->rs);

			if (function_registers_used & (1 << REG_sp))
			{
				RebuildEmit("	" SP_STR " -= %d;\n",theOp->rs*4);
			}
		return 1;
			
		case _POP:
			RebuildEmit("	//pop  %s,%d\n",java_reg[theOp->rd], theOp->rs);

			if (function_registers_used & (1 << REG_sp))
			{
				RebuildEmit("	" SP_STR " += %d;\n",theOp->rs*4);
			}

		return 1;

		case _CASE:
			JavaDecodeSwitch(theOp);
		break;


		case _CALLI:
			JavaDecodeCall(theOp);
		break;

		case _SYSCALL:
			JavaDecodeSysCall(theOp);
		break;

		case _CALL:
			JavaDecodeCallReg(theOp);
		break;

		case _LDI:
			RebuildEmit("	%s = 0x%x;", java_reg[theOp->rd], theOp->imm);			
			SetRegInit(theOp->rd);
		break;

		case _LDR:
		{
			SetRegInit(theOp->rd);

			if (IsRegConst(theOp->rs))
				RebuildEmit("	%s = 0x%x;", java_reg[theOp->rd], ConstRegValue(theOp->rs));
			else
				RebuildEmit("	%s = %s;", java_reg[theOp->rd], java_reg[theOp->rs]);		
		}
		break;

		// Arithmatic
		
		case _ADD:
			JavaEmitArith(theOp,"+", 0);
		break;

		case _ADDI:
			JavaEmitArith(theOp,"+", 1);
		break;

		case _MUL:
			JavaEmitArith(theOp,"*", 0);
		break;

		case _MULI:
			JavaEmitArith(theOp,"*", 1);
		break;

		case _SUB:
			JavaEmitArith(theOp,"-", 0);
		break;

		case _SUBI:
			JavaEmitArith(theOp,"-", 1);
		break;

		case _AND:
			JavaEmitArith(theOp,"&", 0);
		break;

		case _ANDI:
			JavaEmitArith(theOp,"&", 1);
		break;

		case _OR:
			JavaEmitArith(theOp,"|", 0);
		break;

		case _ORI:
			JavaEmitArith(theOp,"|", 1);
		break;

		case _XOR:
			JavaEmitArith(theOp,"^", 0);
		break;

		case _XORI:
			JavaEmitArith(theOp,"^", 1);
		break;

		case _DIVU:
			JavaEmitDivu(theOp, 0);
		break;

		case _DIVUI:
			JavaEmitDivu(theOp, 1);
		break;

		case _DIV:
			JavaEmitArith(theOp,"/", 0);
		break;

		case _DIVI:
			JavaEmitArith(theOp,"/", 1);
		break;

		// Shifts

		case _SLL:
			JavaEmitArith(theOp,"<<", 0);
		break;

		case _SLLI:
			JavaEmitArith(theOp,"<<", 1);
		break;

		case _SRA:
			JavaEmitArith(theOp,">>", 0);
		break;

		case _SRAI:
			JavaEmitArith(theOp,">>", 1);
		break;

		case _SRL:
			JavaEmitArith(theOp,">>>", 0);
		break;

		case _SRLI:
			JavaEmitArith(theOp,">>>", 1);
		break;

		case _NOT:
			RebuildEmit("	%s = ~%s;", java_reg[theOp->rd], java_reg[theOp->rs]);		
			SetRegInit(theOp->rd);
		break;

		case _NEG:
			RebuildEmit("	%s = -%s;", java_reg[theOp->rd], java_reg[theOp->rs]);
			SetRegInit(theOp->rd);
		break;

		case _RET:
		{
			if (ThisFunctionExit == 0)	// Don't output a return jump on last instruction
			{
				RebuildEmit("	ms.goto_0();	// return");
				ReturnCount++;
			}
		}
		break;

		// Conditional jumps

		case _JC_EQ:
			JavaEmitJumpCond(theOp, "==", 0);
		break;

		case _JC_NE:
			JavaEmitJumpCond(theOp, "!=", 0);
		break;

		case _JC_GE:
			JavaEmitJumpCond(theOp, ">=", 0);
		break;

		case _JC_GEU:
			JavaEmitJumpCond(theOp, ">=", 1);
		break;

		case _JC_GT:
			JavaEmitJumpCond(theOp, ">", 0);
		break;

		case _JC_GTU:
			JavaEmitJumpCond(theOp, ">", 1);
		break;

		case _JC_LE:
			JavaEmitJumpCond(theOp, "<=", 0);
		break;

		case _JC_LEU:
			JavaEmitJumpCond(theOp, "<=", 1);
		break;

		case _JC_LT:
			JavaEmitJumpCond(theOp, "<", 0);
		break;

		case _JC_LTU:
			JavaEmitJumpCond(theOp, "<", 1);
		break;

		case _JPI:
			JavaDecodeLabel(theOp, "	ms.goto_%d();");
		break;

#ifdef NO_ELIM
		case _JPR:
//			JavaDecodeLabel(theOp, "	ms.goto_%d();");
		break;
#endif
		// Memory instructions

		case _LDW:
			Java_LoadMem(theOp, "RINT");
		break;

		case _LDH:
			Java_LoadMem(theOp, "RSHORT");
		break;

		case _LDB:
			Java_LoadMem(theOp, "RBYTE");
		break;

		case _STW:
			Java_StoreMem(theOp, "WINT");
		break;

		case _STH:
			Java_StoreMem(theOp, "WSHORT");
		break;

		case _STB:
			Java_StoreMem(theOp, "WBYTE");
		break;

		case _XB:
			RebuildEmit("	%s = (int)((byte) %s);", java_reg[theOp->rd], java_reg[theOp->rs]);		
		break;

		case _XH:
			RebuildEmit("	%s = (int)((short) %s);", java_reg[theOp->rd], java_reg[theOp->rs]);		
		break;

		default:
			str[0] = 0;
			DisassembleFromSource(ip, str);
			ErrorOnIP(Error_Fatal, ip, "Missing instruction in Java rebuilder '%s'\n", str);
	}

	RebuildEmit("\n");
	return 1;
}