Example #1
0
void CppEmitShift(OpcodeInfo *theOp, char *oper, int imm, int issigned)
{
	char *us = "";

	if (issigned)
		us = "(unsigned int)";

	// Dest

	RebuildEmit("	%s = ", Cpp_reg[theOp->rd]);

	// Typecast and Src

	RebuildEmit("%s %s", us, Cpp_reg[theOp->rd]);

	// Operator

	RebuildEmit(" %s ", oper);

	if (imm)
	{
		RebuildEmit("0x%x;", theOp->imm);
		return;
	}
	else
		RebuildEmit("%s;", Cpp_reg[theOp->rs]);
	return;
}
Example #2
0
void JavaDecodeReturn(int emit_r15)
{
	switch(ThisFunctionRetType)
	{
		case RET_null:
		RebuildEmit("	return ?; // Error report to MobileSorcery");
		break;

		case RET_void:
		RebuildEmit("	return;");
		break;

		case RET_float:
		case RET_int:
		RebuildEmit("	return r14;");
		break;

		case RET_double:

		if (emit_r15)
			RebuildEmit("	" DBL_HIGH " = r15;\n");

		RebuildEmit("	return r14;");
		break;
	}
}
Example #3
0
void CppEmitJumpCond(OpcodeInfo *theOp, char *str, int unsign)
{
	if(unsign)
		RebuildEmit("	if ((unsigned long)%s %s (unsigned long)%s) ",Cpp_reg[theOp->rd], str, Cpp_reg[theOp->rs]);
	else
		RebuildEmit("	if (%s %s %s) ",Cpp_reg[theOp->rd], str, Cpp_reg[theOp->rs]);
	CppDecodeLabel(theOp, "goto label_%d;");

	unsign = 0;
}
Example #4
0
void CppEmitArith(OpcodeInfo *theOp, char *str, int imm)
{
	if (imm)
	{
		RebuildEmit("	%s %s= 0x%x;", Cpp_reg[theOp->rd], str, theOp->imm);
		return;
	}

	RebuildEmit("	%s %s= %s;", Cpp_reg[theOp->rd], str, Cpp_reg[theOp->rs]);
	return;
}
Example #5
0
void RebuildCppEpilog(SYMBOL *sym)
{
//	ThisFunctionExit

	if (ReturnCount > 0)
		RebuildEmit("label_0:;\n");

	CppDecodeReturn(1);
	RebuildEmit("\n");

	RebuildEmit("} // %s\n", sym->Name);
}
Example #6
0
void CppEmitDivu(OpcodeInfo *theOp, int imm)
{
	if (imm)
	{
		if (theOp->imm == 0)
			Warning("Division by zero in recompiler");

		RebuildEmit("	%s = (int) ((unsigned long)(%s)) / ((unsigned long)(%d));", Cpp_reg[theOp->rd], Cpp_reg[theOp->rd], theOp->imm);
	}
	else
	{
		RebuildEmit("	if(%s == 0) MoSyncDiv0();\n", Cpp_reg[theOp->rs]);
		RebuildEmit("	%s = (int) ((unsigned long)(%s)) / ((unsigned long)(%s));", Cpp_reg[theOp->rd], Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
	}
}
Example #7
0
int CppDecodeLabel(OpcodeInfo *theOp, char *str)
{

	SYMBOL *ref, *labref;
	int addr;

	ref = (SYMBOL *) ArrayGet(&CallArray, theOp->rip);

	// !! Check if what it points to in lablearry and use that !!

	if (!ref)
		return 0;

	addr = ref->Value;

	labref = (SYMBOL *) ArrayGet(&CodeLabelArray, addr);

	if (!labref)
		return 0;

	ref = labref;

	RebuildEmit(str, ref->LabelEnum);
	return 1;
}
Example #8
0
void Cpp_LoadMem(OpcodeInfo *theOp, char *str)
{

	if (theOp->rs == 0)
	{
		RebuildEmit("	%s = %s(0x%x);", Cpp_reg[theOp->rd], str, theOp->imm);
		return;
	}

	if (theOp->imm == 0)
	{
		RebuildEmit("	%s = %s(%s);", Cpp_reg[theOp->rd], str, Cpp_reg[theOp->rs]);
		return;
	}

	RebuildEmit("	%s = %s(%s+0x%x);", Cpp_reg[theOp->rd], str, Cpp_reg[theOp->rs], theOp->imm);
}
Example #9
0
void Cpp_StoreMem(OpcodeInfo *theOp, char *str)
{

	if (theOp->rd == 0)
	{
		RebuildEmit("	%s(0x%x, %s);", str, theOp->imm, Cpp_reg[theOp->rs]);
		return;
	}

	if (theOp->imm == 0)
	{
		RebuildEmit("	%s(%s, %s);", str, Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
		return;
	}

	RebuildEmit("	%s(%s+0x%x, %s);", str, Cpp_reg[theOp->rd], theOp->imm, Cpp_reg[theOp->rs]);
}
Example #10
0
int CppDecodeSwitch(OpcodeInfo *theOp)
{
	int start, len, data_ip, def_ip, i;
	int lab_ip;

	data_ip = theOp->imm;

	start	= GetDataMemLong(data_ip++);
	len		= GetDataMemLong(data_ip++);
	def_ip	= GetDataMemLong(data_ip++);	// default case


	RebuildEmit("	switch(%s)\n",  Cpp_reg[theOp->rd]);
	RebuildEmit("	{\n");

	for (i=0;i<len+1;i++)
	{
		lab_ip = GetDataMemLong(data_ip++);

		RebuildEmit("		case 0x%x: ", start);
		CppDecodeCase(lab_ip);
		RebuildEmit("\n");
		start++;
	}

	RebuildEmit("		default: ", start);
	CppDecodeCase(def_ip);
	RebuildEmit("\n");


	RebuildEmit("	}\n");


	return 1;
}
Example #11
0
void RebuildCpp_EmitDS()
{
	int need_comma;
	int count;
	int n;

	RebuildEmit("\n");
	RebuildEmit("//****************************************\n");
	RebuildEmit("//             Data Section\n");
	RebuildEmit("//****************************************\n\n");

	RebuildEmit("#define ds_len %d\n", DataIP >> 2);
	RebuildEmit("#define bs_len %d\n", BssIP >> 2);
	RebuildEmit("#define all_len %d\n\n", (BssIP + DataIP) >> 2);
	RebuildEmit("#define MaxDataIP %d\n\n", MaxDataIP >> 2);

	RebuildEmit("int *mem_ds\n");
}
Example #12
0
void CppEmitDiv(OpcodeInfo *theOp, int imm)
{
	if ((theOp->rs == 0) || (theOp->imm == 0))
		printf(" ");

	if (imm)
	{
		if (theOp->imm == 0)
			Warning("Division by zero in recompiler");

		RebuildEmit("	%s /= %d;", Cpp_reg[theOp->rd], theOp->imm);
	}
	else
	{
		RebuildEmit("	if (%s == 0) MoSyncDiv0();\n", Cpp_reg[theOp->rs]);
		RebuildEmit("	%s /= %s;", Cpp_reg[theOp->rd], Cpp_reg[theOp->rs]);
	}
}
Example #13
0
void RebuildEmitStabs(int ip)
{
	int line  = ArrayGet(&SLD_Line_Array, ip);
	int file = ArrayGet(&SLD_File_Array, ip);
	char *FileStr;
	
	if (line == 0)
		return;

	if (file != lastfileno)
	{
		lastfileno = file;

		FileStr = GetFileNumString(file);

		if (FileStr)
			RebuildEmit(".sourcefile '%s'\n", FileStr);
	}

	RebuildEmit(".line %d\n", line);
}
Example #14
0
int CppDecodeCase(int ip)
{
	SYMBOL *ref;

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

	if (!ref)
		return 0;

	RebuildEmit("goto label_%d;", ref->LabelEnum);
	return 1;
}
Example #15
0
void CppEmitReturnDecl(int rettype)
{
	switch(rettype)
	{
		case RET_null:
		RebuildEmit("? // Error report to MoSync");
		break;

		case RET_void:
		RebuildEmit("void ");
		break;

		case RET_float:
		case RET_int:
		RebuildEmit("int ");
		break;

		case RET_double:
		RebuildEmit("int ");
		break;
	}
}
Example #16
0
void Java_LoadMem(OpcodeInfo *theOp, char *str)
{
	SetRegInit(theOp->rd);

	if (strcmp(str, "RINT") == 0)
	{
		// Optimization for int

		if (theOp->rs == 0)
		{
			RebuildEmit("	%s = " MEM_DS "[0x%x];", java_reg[theOp->rd], theOp->imm >> 2);
			return;
		}

		if (theOp->imm == 0)
		{
			RebuildEmit("	%s = " MEM_DS "[%s >> 2];", java_reg[theOp->rd], java_reg[theOp->rs]);
			return;
		}
			
		RebuildEmit("	%s = " MEM_DS "[(%s+0x%x) >> 2];", java_reg[theOp->rd], java_reg[theOp->rs], theOp->imm);
		return;
	}
Example #17
0
void RebuildCpp_EmitProtos()
{
	SYMBOL *sym;
	int n;

	RebuildEmit("\n// Prototypes\n\n");

	RebuildEmit("static int CallReg(int s, int i0, int i1, int i2, int i3);\n");

	for (n=0;n<CodeIP+1;n++)
	{
		sym = (SYMBOL *) ArrayGet(&CodeLabelArray, n);

		if (sym)
		{
			if (sym->Flags & SymFlag_Ref)
			if (sym->LabelType >= label_Function)
			{
				RebuildCppFunc(sym, 1);
			}
		}
	}
}
Example #18
0
void CppDecodeReturnNull()
{
	switch(ThisFunctionRetType)
	{
		case RET_null:
		RebuildEmit("	return ?; // Error report to MobileSorcery");
		break;

		case RET_void:
		RebuildEmit("	return;");
		break;

		case RET_float:
		case RET_int:
		RebuildEmit("	return 0;");
		break;

		case RET_double:
		RebuildEmit("	__dbl_high = 0;\n");
		RebuildEmit("	return 0;");
		break;
	}
}
Example #19
0
int CppCallFunction(SYMBOL *ref, int emit_r15)
{
	int param_count, need_comma, n;
	int rettype = ref->RetType;
	int regs;

	CppEmitReturnType(rettype);

	RebuildEmit("%s_%d(", ref->Name, ref->LocalScope);

	param_count = ref->Params;

	if (param_count > 4)
		param_count = 4;

	need_comma = 0;

	regs = funcprop.reg_used;

	for (n=0;n<param_count;n++)
	{
		if (need_comma)
			RebuildEmit(", ");

		RebuildEmit("%s", Cpp_reg[REG_i0 + n]);
		need_comma = 1;
	}

	RebuildEmit(");");

	if (rettype == RET_double && emit_r15 && (regs & REGBIT(REG_r15)))
	{
		RebuildEmit("\n	r15 = __dbl_high;");
		SetRegInit(REG_r15);
	}
	return 1;
}
Example #20
0
void CppDecodeReturn(int shouldPassR15)
{
	switch(ThisFunctionRetType)
	{
		case RET_null:
		RebuildEmit("	return ?; // Error report to MobileSorcery");
		break;

		case RET_void:
		RebuildEmit("	return;");
		break;

		case RET_float:
		case RET_int:
			RebuildEmit("	return r14;");
		break;

		case RET_double:
		if(shouldPassR15)
			RebuildEmit("	__dbl_high = r15;\n");
		RebuildEmit("	return r14;");
		break;
	}
}
Example #21
0
void CppDecodeSysCall(OpcodeInfo *theOp)
{
	int param_count, need_comma, n;

	SYMBOL *syscall =  FindSysCall(theOp->imm);

	if (!syscall)
	{
		Error(Error_System, "Could'nt locate syscall\n");
		return;
	}

	CppSyscallUsed[theOp->imm]++;

	param_count = syscall->Params;

	CppEmitReturnType(syscall->RetType);


	RebuildEmit("SYSCALL(");
	RebuildEmit("%s", &syscall->Name[1]);
	RebuildEmit(")(");

	if (param_count > 4)
		param_count = 4;

	need_comma = 0;

	for (n=0;n<param_count;n++)
	{
		if (need_comma)
			RebuildEmit(", ");

		RebuildEmit("%s", Cpp_reg[REG_i0 + n]);
		need_comma = 1;
	}

	RebuildEmit(");");

	if (syscall->RetType == RET_double)
		RebuildEmit("\n	r15 = __dbl_high;");
}
Example #22
0
void JavaDecodeSysCall(OpcodeInfo *theOp)
{
	int param_count, need_comma, n;

	SYMBOL *theSysCall =  FindSysCall(theOp->imm);

	if (!theSysCall)
	{
		Error(Error_System, "Could'nt locate syscall\n");
		return;
	}

	JavaSyscallUsed[theOp->imm]++;

	param_count = theSysCall->Params;

	JavaEmitReturnType(theSysCall->RetType);

	if (theSysCall->Interface == 0)
		RebuildEmit( SYSCALLDOT "%s(", theSysCall->Name + 1);
	else
		RebuildEmit("%s(", theSysCall->Name);

	if (param_count > 4)
		param_count = 4;

	need_comma = 0;

	for (n=0;n<param_count;n++)
	{
		if (need_comma)
			RebuildEmit(", ");				
	
		RebuildEmit("%s", java_reg[REG_i0 + n]);
		need_comma = 1;
	}

	RebuildEmit(");");

	if (theSysCall->RetType == RET_double)
	{
		RebuildEmit("\n	r15 = " DBL_HIGH ";");
		SetRegInit(REG_r15);
	}
}
Example #23
0
void Rebuild_Main()
{
	ArrayInit(&RebuildArray, sizeof(char), 0);
	ArrayInit(&LabelDone, sizeof(char), 0);

	lastfileno = -1;
	Rebuild_Mode = 1;

	RebuildEmit("//****************************************\n");
	RebuildEmit("// Generated code\n");
	RebuildEmit("//****************************************\n\n");

	RebuildEmit(".lfile 'rebuild.s'\n");

	RebuildEmit(".code\n");
	Rebuild_Code();

	RebuildEmit(".data\n");
	Rebuild_Memory();

	ArrayWrite(&RebuildArray, "rebuild.s");
} 
Example #24
0
void Rebuild_Data(SYMBOL *sym)
{
	SYMBOL *thisSym;

	//uint ta = 0;
	
	int ip;
	int len;
	int n;
	int c;
	int left;
	int align;
	int opt_bss;

	// decode the field
	
	ip = sym->Value;

	if (sym->Type == SECT_bss)
		ip += MaxDataIP;

	len = sym->EndIP;
	left = len;

	// Has this been done already

	if (ArrayGet(&LabelDone, ip))
		return;

	// Mark as done

	ArraySet(&LabelDone, ip, 1);
	
	if (!len)
	{
		len = FindLabelExtent(ip);


		if (!len)
		{
			RebuildEmit("// empty %s_%d,%d\n", sym->Name, sym->LocalScope, len);
			return;
		}

		// Save the result for later

		sym->EndIP = len;

		RebuildEmit("// found extent %s_%d,%d\n", sym->Name, sym->LocalScope, len);
	}

	align = ArrayGet(&DataAlignArray, ip);
	
	if (sym->Type == SECT_bss)
	{
		RebuildEmit("\t.comm %s_%d,%d\n", sym->Name, sym->LocalScope, len);
		return;
	}
	
	if (sym->Type != SECT_data)
		Error(Error_System, "(Rebuild_Data) Illegal section in data output");

	// Check if this data field can be moved to bss

#if 1
	opt_bss  = Rebuild_CanMoveToBss(ip, len);

	if (opt_bss)
	{
		// Make sure bss output is aligned
		int bss_len = len;
		
		while(bss_len & 3)
			bss_len++;
		
		RebuildEmit("\t.comm %s_%d,%d	//moved to bss\n", sym->Name, sym->LocalScope, bss_len);
		return;
	}
#endif

	if (align)
		RebuildEmit("\t.align %d\n", align);

	// write a data section field

	RebuildEmit("%s_%d:\n", sym->Name, sym->LocalScope );

	// write array

	c = 0;

	for (n=ip;n<ip+len;n++)
	{
		thisSym = (SYMBOL *) ArrayGet(&DataArray, n);

		if (!thisSym)
		{
			RebuildEmit("\t.byte 0x%s\n", Hex8(GetDataMem(n)) );
			left--;
			continue;
		}

		// check if we hit a .word reference

		if (left >= 4)
		{
			if (thisSym)
			{
				SYMBOL *labref = NULL;
				int addr;

				addr = thisSym->Value;
	
				if (thisSym->Type == SECT_code)
				{
					labref = (SYMBOL *) ArrayGet(&CodeLabelArray, addr);

					if (labref == 0)
						Error(Error_System, "Could not repoint label !!");
//						labref = thisSym;
				}

				if (thisSym->Type == SECT_data)
				{
					labref = (SYMBOL *) ArrayGet(&LabelArray, addr);

					if (labref == 0)
						Error(Error_System, "Could not repoint label !!");
				}

				if (thisSym->Type == SECT_bss)
				{
					labref = (SYMBOL *) ArrayGet(&LabelArray, addr + MaxDataIP);

					if (labref == 0)
						Error(Error_System, "Could not repoint label !!");
				}
	
				if(labref == NULL)
					Error(Error_System, "Broken label");

				RebuildEmit("\t.word %s_%d\n", labref->Name, labref->LocalScope);
	
				left-=4;
				n+=3;

			}
		}
	}

	RebuildEmit("\n\n");
	return;
}
Example #25
0
void CppDecodeCallReg(OpcodeInfo *theOp)
{
	// changed ThisFunctionRegs to funcprop.reg_used (didn't take the parameters to the function into account).
	int i0 = funcprop.reg_used & REGBIT(REG_i0);
	int i1 = funcprop.reg_used & REGBIT(REG_i1);
	int i2 = funcprop.reg_used & REGBIT(REG_i2);
	int i3 = funcprop.reg_used & REGBIT(REG_i3);

	RebuildEmit("	r14 = CallReg(%s", Cpp_reg[theOp->rd]);

	if (i0)
		RebuildEmit(", i0");
	else
		RebuildEmit(", 0");

	if (i1)
		RebuildEmit(", i1");
	else
		RebuildEmit(", 0");

	if (i2)
		RebuildEmit(", i2");
	else
		RebuildEmit(", 0");

	if (i3)
		RebuildEmit(", i3");
	else
		RebuildEmit(", 0");

	CppUsedCallReg = 1;

	RebuildEmit(");\n");

	// r14 and r15 are always scratch registers after a function call (they may have changed. So we can safely overwrite the content here).
	if(funcprop.reg_used & REGBIT(REG_r15))
	{
		RebuildEmit("	r15 = __dbl_high;\n");
	}
}
Example #26
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;
}
Example #27
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);	
	}
}
Example #28
0
void RebuildCppProlog(SYMBOL *sym, int isproto)
{
	int reg_used;
	int reg_alloc;

	int param_count;
	int need_comma;
	int n;

	// Find registers used in function

	reg_used = FunctionRegAnalyse(sym, &funcprop);

	reg_alloc = 0;

	// Output helpful header

	if (isproto == 0)
	{
		RebuildEmit("\n//****************************************\n");
		RebuildEmit("// Function: %s\n", sym->Name);
		RebuildEmit("//****************************************\n\n");
	}

	if (!isproto)
	{
		RebuildEmit("//             rrrrrrrrrrrrrrrriiiiddddddddfrsz\n");
		RebuildEmit("//             fedcba9876543210321076543210rtpr\n");

		RebuildEmit("//src_reg    = %s\n", Bin32(funcprop.src_reg));
		RebuildEmit("//dst_reg    = %s\n", Bin32(funcprop.dst_reg));
		RebuildEmit("//assign_reg = %s\n", Bin32(funcprop.assign_reg));
		RebuildEmit("//uninit_reg = %s\n", Bin32(funcprop.uninit_reg));
		RebuildEmit("//used_reg   = %s\n", Bin32(funcprop.reg_used));
		RebuildEmit("//tfr        = %s\n", Bin32(ThisFunctionRegs));
		RebuildEmit("\n");
	}
	else RebuildEmit("static ");

	// Output function decl
	switch(ThisFunctionRetType)
	{
		case RET_null:
		RebuildEmit(" ?; // Error report to MobileSorcery\n");
		break;

		case RET_void:
		RebuildEmit("void ");
		break;

		case RET_float:
		case RET_int:
		case RET_double:
		RebuildEmit("int ");
		break;
	}

	RebuildEmit("%s_%d(", sym->Name, sym->LocalScope);

	param_count = sym->Params;

	if (param_count > 4)
		param_count = 4;

	need_comma = 0;

	for (n=0;n<param_count;n++)
	{
		if (need_comma)
			RebuildEmit(", ");

		RebuildEmit("int %s", Cpp_reg[REG_i0 + n]);
		need_comma = 1;

		reg_alloc |=  1 << (REG_i0 + n);

	}

	if (isproto)
	{
		RebuildEmit(");\n");
		return;
	}

	RebuildEmit(")\n{\n");

	// Write local decl

	// Remove regs that are already declared in func decl

	// ok this has sort of been reverse engineered by looking at the bitmasks in the rebuilt code... ;)
	// this is added to remove warnings about unusued variables.
	reg_used &= ThisFunctionRegs | (1 << REG_r14) | (1 << REG_r15) | (1 << REG_i0) | (1 << REG_i1) | (1 << REG_i2) | (1 << REG_i3);

	reg_used &= (~reg_alloc);

	// remove sp from locals

	reg_used &= ~(1 << REG_sp);
	reg_used &= ~(1 << REG_zero);

	if (ThisFunctionRetType != RET_null && ThisFunctionRetType != RET_void)
		reg_used |= (1 << REG_r14);
	if (ThisFunctionRetType == RET_double)
		reg_used |= (1 << REG_r15);

	if (reg_used)
	{
		RebuildEmit("\tint ");

		need_comma = 0;

		for (n=0;n<32;n++)
		{
			if (reg_used & (1 << n))
			{
				if (need_comma)
					RebuildEmit(", ");

				RebuildEmit("%s", Cpp_reg[n]);

				if (funcprop.uninit_reg & (1<<n))
					RebuildEmit("=0");

				need_comma = 1;
			}
		}

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

}
Example #29
0
void RebuildCpp_EmitSyscallFunc(SYMBOL *sym, int proto, int stub)
{
	int param_count, need_comma, n;

	if (!stub)
		if (!sym->Interface)
			return;

	if (!proto)
	{
		RebuildEmit("\n");
		RebuildEmit("//****************************************\n");
		RebuildEmit("//  Syscall interface '%s'\n", sym->Name);
		RebuildEmit("//****************************************\n");
		RebuildEmit("\n");
	}

	param_count = sym->Params;

	CppEmitReturnDecl(sym->RetType);

	RebuildEmit("%s(", sym->Name);

	if (param_count > 4)
		param_count = 4;

	need_comma = 0;

	for (n=0;n<param_count;n++)
	{
		if (need_comma)
			RebuildEmit(", ");

		RebuildEmit("int %s", Cpp_reg[REG_i0 + n]);
		need_comma = 1;
	}

	RebuildEmit(")");

	if (proto)
	{
		RebuildEmit(";\n");
		return;
	}

	RebuildEmit("\n{\n");

	if (!stub)
		RebuildEmit("	%s", sym->Interface);
	else
	{
		ThisFunctionRetType = sym->RetType;
		CppDecodeReturnNull();
	}

	RebuildEmit("\n}\n");
}
Example #30
0
void RebuildCpp_Main()
{
	if (ArgConstOpt != 0)
		Error(Error_System, "(RebuildCpp_Main) ArgConstOpt must be switched off");

	#ifdef CPP_SHOW_LINES
	InitFiles();
	#endif

	ArrayInit(&RebuildArray, sizeof(char), 0);
	ArrayInit(&LabelDone, sizeof(char), 0);

	memset(CppSyscallUsed, 0, sizeof(CppSyscallUsed));

	CppForceSysCallUsed("RBYTE");
	CppForceSysCallUsed("WBYTE");

	Rebuild_Mode = 1;
	CppUsedCallReg = 0;

	RebuildEmit("//****************************************\n");
	RebuildEmit("//          Generated Cpp code\n");
	RebuildEmit("//****************************************\n");

	RebuildEmit("\n");
	RebuildEmit("#include \"mstypeinfo.h\"\n");
	RebuildEmit("\n");

#if 0			//My Testing only
	RebuildCpp_EmitExtensionsProto();
#endif

	RebuildCpp_EmitProtos();

//	RebuildCpp_EmitDS();

//	RebuildEmit("class MoSyncCode\n");
//	RebuildEmit("{\n");

//	RebuildEmit("\n");					// Out in .h file
//	RebuildEmit("int sp;\n");
//	RebuildEmit("int __dbl_high;\n");

	RebuildEmit("\n");

//	RebuildCpp_EmitDS();
	RebuildCpp_StartUp();

	MaxEnumLabel = 0;

	RebuildCpp_Code();
	//RebuildCpp_EmitExtensions(1);
	RebuildCpp_CallReg();

//	RebuildEmit("}; // End of MosyncCode class\n");
//	RebuildEmit("// MaxEnumLabel=%d\n", MaxEnumLabel);

//	RebuildCpp_FlowClass();

	#ifdef CPP_SHOW_LINES
	FreeFiles();
	#endif

	ArrayWrite(&RebuildArray, "rebuild.build.cpp");
}