void InitFiles() { size_t n; for(n = 0; n < 1024; n++) { fileInfo[n].numLines = -1; fileInfo[n].fileData = NULL; } for (n=SLD_File_Array.lo;n<SLD_File_Array.hi+1;n++) { int file = ArrayGet(&SLD_File_Array, n); FILE *f; const char *fileName; if(fileInfo[file].numLines!=-1) continue; fileName = GetFileNumString(file); f = fopen(fileName, "rb"); if(f) { size_t i, dataSize, line, res; fseek(f, 0, SEEK_END); dataSize = ftell(f); fileInfo[file].fileData = (char*) malloc(dataSize+1); fileInfo[file].fileData[dataSize] = 0; fseek(f, 0, SEEK_SET); res = fread(fileInfo[file].fileData, 1, dataSize, f); if(res != dataSize) { printf("Error reading file '%s'\n", fileName); exit(1); } line = 0; for(i = 0; i < dataSize; i++) { if(fileInfo[file].fileData[i] == '\n') line++; } fileInfo[file].numLines = line; fileInfo[file].lines = (char**) malloc(sizeof(char*)*(line+1)); line = 0; fileInfo[file].lines[0] = fileInfo[file].fileData; for(i = 0; i < dataSize; i++) { if(fileInfo[file].fileData[i] == '\n') { line++; fileInfo[file].fileData[i] = 0; fileInfo[file].lines[line] = &fileInfo[file].fileData[i+1]; } } fclose(f); } } }
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); }
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; }