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); } }
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; }
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; }
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; }