diff --git a/.gitattributes b/.gitattributes index 4227428..0d3843a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,4 +2,5 @@ * text=auto *.c linguist-language=C *.h linguist-language=C -*.asm linguist-language=Assembly \ No newline at end of file +*.asm linguist-language=Assembly +*.s linguist-language=Assembly \ No newline at end of file diff --git a/README.md b/README.md index e085d4f..9b9ee02 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ Each PTE is an 8-byte entry. There are 512 PTEs. For each entry, there are 64 bi | PDE | Page-Directory Entry | The second level of address-translation | | PDPTE | Page-Directory Pointer Table Entry | The third level of address-translation | | XTLB | Execution Translate Lookaside Buffer | TLB that accelerates instruction fetching | +| DTLB | Data Translate Lookaside Buffer | TLB that accelerates data reading/writing | ## FAQ Following lists the frequently asked questions, and corresponding answers. @@ -103,6 +104,7 @@ Here list all command-line arguments. - `/nologo` suppresses the logo printer. - `/runtime` specifies the runtime preset of MIPS Virtual Machine. Default runtime preset is `MARS`. +- `/debug` specifies mipsivm to break at program startup. Following runtime presets are available: @@ -121,5 +123,15 @@ mipsivm /nologo /runtime mars /ds helloworld.data.bin /ts helloworld.text.bin ``` This code would suppress the logo printer then load `helloworld.data.bin` as `.data` section and `helloworld.text.bin` as `.text` section of the program, with 64KiB default stack, and run the program. +## Debug Mode +Debugging is the new feature of mipsivm. In case of break-on-startup, `break` instructions or `trap` instructions, mipsivm would enter debug mode and accepts command line input to debug.
+Following are debug commands: +- `d` is dumping command: Dump memory content and display in console. (Not started) +- `e` is editing command: Edit memory content. (Not started) +- `g` is continue command: Continue simulation of program. +- `r` is register dump command: Dump register file and display in console. +- `t` is single-step command: Start single-stepping with instruction-granularity. +- `u` is disassembly command: Disassemble instructions display in console. (Incomplete) + ## License This repository is licensed under the MIT license. \ No newline at end of file diff --git a/compfre_win10x64.bat b/compfre_win10x64.bat index 64139ca..7ec711d 100644 --- a/compfre_win10x64.bat +++ b/compfre_win10x64.bat @@ -27,6 +27,12 @@ cl .\src\sim-i.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /O2 /D"_msvc" /D"_amd cl .\src\sim-j.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /O2 /D"_msvc" /D"_amd64" /D"_mips_simj" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\sim-j.cod" /Fo"%objpath%\sim-j.obj" /Fd"%objpath%\vc140.pdb" /Qspectre /GS- /Gd /TC /c /errorReport:queue +cl .\src\disasm-r.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /O2 /D"_msvc" /D"_amd64" /D"_mips_disasmr" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\disasm-r.cod" /Fo"%objpath%\disasm-r.obj" /Fd"%objpath%\vc140.pdb" /Qspectre /GS- /Gd /TC /c /errorReport:queue + +cl .\src\disasm-i.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /O2 /D"_msvc" /D"_amd64" /D"_mips_disasmi" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\disasm-i.cod" /Fo"%objpath%\disasm-i.obj" /Fd"%objpath%\vc140.pdb" /Qspectre /GS- /Gd /TC /c /errorReport:queue + +cl .\src\disasm.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /O2 /D"_msvc" /D"_amd64" /D"_mips_disasm" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\disasm.cod" /Fo"%objpath%\disasm.obj" /Fd"%objpath%\vc140.pdb" /Qspectre /GS- /Gd /TC /c /errorReport:queue + echo ============Start Linking============ link "%objpath%\*.obj" /LIBPATH:"%libpath%\um\x64" /LIBPATH:"%libpath%\ucrt\x64" /LIBPATH:"%ddkpath%\lib\x64" /NOLOGO /DEBUG /PDB:"%objpath%\mipsivm.pdb" /INCREMENTAL:NO /OUT:"%binpath%\mipsivm.exe" /SUBSYSTEM:CONSOLE /Machine:X64 /ERRORREPORT:QUEUE diff --git a/src/disasm-i.c b/src/disasm-i.c index 1cada70..c7cc96e 100644 --- a/src/disasm-i.c +++ b/src/disasm-i.c @@ -100,6 +100,12 @@ void mips_disasm_i_lh(char* mnemonic,u32 length,u32 pc,mips_instruction instruct sim_snprintf(mnemonic,length,"lh %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); } +void mips_disasm_i_lwl(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"lwl %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + void mips_disasm_i_lw(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { const i32 imm=(i32)((i16)instruction.i.imm); @@ -118,6 +124,12 @@ void mips_disasm_i_lhu(char* mnemonic,u32 length,u32 pc,mips_instruction instruc sim_snprintf(mnemonic,length,"lhu %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); } +void mips_disasm_i_lwr(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"lwr %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + void mips_disasm_i_sb(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { const i32 imm=(i32)((i16)instruction.i.imm); @@ -130,15 +142,93 @@ void mips_disasm_i_sh(char* mnemonic,u32 length,u32 pc,mips_instruction instruct sim_snprintf(mnemonic,length,"sh %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); } +void mips_disasm_i_swl(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"swl %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + void mips_disasm_i_sw(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { const i32 imm=(i32)((i16)instruction.i.imm); sim_snprintf(mnemonic,length,"sw %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); } +void mips_disasm_i_swr(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"swr %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + +void mips_disasm_i_ll(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"ll %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + +void mips_disasm_i_sc(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"sc %s,%d(%s)",mips_gpr_string[instruction.i.rt],imm,mips_gpr_string[instruction.i.rs]); +} + // RegImm I-Format Instructions... +void mips_disasm_i_bltz(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"bltz %s,0x%X",mips_gpr_string[instruction.i.rs],pc+(imm<<2)); +} + void mips_disasm_i_bgez(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { const i32 imm=(i32)((i16)instruction.i.imm); sim_snprintf(mnemonic,length,"bgez %s,0x%X",mips_gpr_string[instruction.i.rs],pc+(imm<<2)); +} + +void mips_disasm_i_tgei(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"tgei %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_tgeiu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"tgeiu %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_tlti(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"tlti %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_tltiu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"tltiu %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_teqi(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"teqi %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_tnei(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"tnei %s,%d",mips_gpr_string[instruction.i.rs],imm); +} + +void mips_disasm_i_bltzal(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"bltzal %s,0x%X",mips_gpr_string[instruction.i.rs],pc+(imm<<2)); +} + +void mips_disasm_i_bgezal(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + const i32 imm=(i32)((i16)instruction.i.imm); + sim_snprintf(mnemonic,length,"bgezal %s,0x%X",mips_gpr_string[instruction.i.rs],pc+(imm<<2)); } \ No newline at end of file diff --git a/src/disasm-r.c b/src/disasm-r.c index d4f49f0..b10ff3c 100644 --- a/src/disasm-r.c +++ b/src/disasm-r.c @@ -19,7 +19,10 @@ void mips_disasm_r_sll(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { - sim_snprintf(mnemonic,length,"sll %s,%s,%u",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rt],instruction.r.shamt); + if(instruction.value==0) + sim_snprintf(mnemonic,length,"nop"); // NOP instruction. + else + sim_snprintf(mnemonic,length,"sll %s,%s,%u",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rt],instruction.r.shamt); } void mips_disasm_r_srl(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) @@ -54,7 +57,10 @@ void mips_disasm_r_jr(char* mnemonic,u32 length,u32 pc,mips_instruction instruct void mips_disasm_r_jalr(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { - sim_snprintf(mnemonic,length,"jalr %s",mips_gpr_string[instruction.r.rs]); + if(instruction.r.rd==31 || instruction.r.rd==0) + sim_snprintf(mnemonic,length,"jalr %s",mips_gpr_string[instruction.r.rs]); + else + sim_snprintf(mnemonic,length,"jalr %s,%s",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rs]); } void mips_disasm_r_movz(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) @@ -170,4 +176,45 @@ void mips_disasm_r_slt(char* mnemonic,u32 length,u32 pc,mips_instruction instruc void mips_disasm_r_sltu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { sim_snprintf(mnemonic,length,"sltu %s,%s,%s",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_tge(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"tge %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_tgeu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"tgeu %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_tlt(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"tlt %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_tltu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"tltu %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_teq(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"teq %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +void mips_disasm_r_tne(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"tne %s,%s",mips_gpr_string[instruction.r.rs],mips_gpr_string[instruction.r.rt]); +} + +// R2-Format Instructions +void mips_disasm_r_clz(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"clz %s,%s",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rs]); +} + +void mips_disasm_r_clo(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + sim_snprintf(mnemonic,length,"clo %s,%s",mips_gpr_string[instruction.r.rd],mips_gpr_string[instruction.r.rs]); } \ No newline at end of file diff --git a/src/disasm.c b/src/disasm.c index 9f633e5..4298b53 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -37,6 +37,11 @@ void mips_disasm_r_format(char* mnemonic,u32 length,u32 pc,mips_instruction inst mips_disasm_r_funct[instruction.r.funct](mnemonic,length,pc,instruction); } +void mips_disasm_r2_format(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) +{ + mips_disasm_r2_funct[instruction.r.funct](mnemonic,length,pc,instruction); +} + void mips_disasm_regimm_i_format(char* mnemonic,u32 length,u32 pc,mips_instruction instruction) { mips_disasm_regimm_i_funct[instruction.i.rt](mnemonic,length,pc,instruction); diff --git a/src/include/devkit.h b/src/include/devkit.h index 7a08770..98365a4 100644 --- a/src/include/devkit.h +++ b/src/include/devkit.h @@ -37,4 +37,13 @@ bool unload_section(void* section); void* alloc_page(u32 size); bool free_page(void* address); void* alloc_mem(u32 size); -bool free_mem(void* address); \ No newline at end of file +bool free_mem(void* address); + +#if defined(_msvc) +#define intrin_bt _bittest +#define intrin_bts _bittestandset +#define intrin_btr _bittestandreset +#define intrin_btc _bittestandcomplement + +#define intrin_locked_xchg _InterlockedExchange +#endif \ No newline at end of file diff --git a/src/include/disasm.h b/src/include/disasm.h index d807253..a430a93 100644 --- a/src/include/disasm.h +++ b/src/include/disasm.h @@ -54,6 +54,16 @@ void mips_disasm_r_xor(char* mnemonic,u32 length,u32 pc,mips_instruction instruc void mips_disasm_r_nor(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_r_slt(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_r_sltu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_tge(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_tgeu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_tlt(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_tltu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_teq(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_tne(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); + +// R2-Format Instructions +void mips_disasm_r_clz(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r_clo(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); // I-Format Instructions void mips_disasm_i_beq(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); @@ -70,15 +80,30 @@ void mips_disasm_i_xori(char* mnemonic,u32 length,u32 pc,mips_instruction instru void mips_disasm_i_lui(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_lb(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_lh(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_lwl(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_lw(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_lbu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_lhu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_lwr(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_sb(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_sh(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_swl(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_sw(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_swr(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_ll(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_sc(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); // RegImm I-Format Instructions +void mips_disasm_i_bltz(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_i_bgez(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_tgei(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_tgeiu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_tlti(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_tltiu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_teqi(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_tnei(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_bltzal(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_i_bgezal(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); // J-Format Instructions void mips_disasm_j_j(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); @@ -86,6 +111,7 @@ void mips_disasm_j_jal(char* mnemonic,u32 length,u32 pc,mips_instruction instruc // Miscellaneous void mips_disasm_r_format(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); +void mips_disasm_r2_format(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_regimm_i_format(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_fpu(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); void mips_disasm_unknown_instruction(char* mnemonic,u32 length,u32 pc,mips_instruction instruction); @@ -93,173 +119,241 @@ void mips_disasm_unknown_instruction(char* mnemonic,u32 length,u32 pc,mips_instr #if defined(_mips_disasm) mips_disasm_procedure mips_disasm_by_opcode[64]= { - mips_disasm_r_format, - mips_disasm_regimm_i_format, - mips_disasm_j_j, - mips_disasm_j_jal, - mips_disasm_i_beq, - mips_disasm_i_bne, - mips_disasm_i_blez, - mips_disasm_i_bgtz, - mips_disasm_i_addi, - mips_disasm_i_addiu, - mips_disasm_i_slti, - mips_disasm_i_sltiu, - mips_disasm_i_andi, - mips_disasm_i_ori, - mips_disasm_i_xori, - mips_disasm_i_lui, - mips_disasm_unknown_instruction, - mips_disasm_fpu, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_i_lb, - mips_disasm_i_lh, - mips_disasm_unknown_instruction, - mips_disasm_i_lw, - mips_disasm_i_lbu, - mips_disasm_i_lhu, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_i_sb, - mips_disasm_i_sh, - mips_disasm_unknown_instruction, - mips_disasm_i_sw, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction + mips_disasm_r_format, // 0x00 + mips_disasm_regimm_i_format, // 0x01 + mips_disasm_j_j, // 0x02 + mips_disasm_j_jal, // 0x03 + mips_disasm_i_beq, // 0x04 + mips_disasm_i_bne, // 0x05 + mips_disasm_i_blez, // 0x06 + mips_disasm_i_bgtz, // 0x07 + mips_disasm_i_addi, // 0x08 + mips_disasm_i_addiu, // 0x09 + mips_disasm_i_slti, // 0x0A + mips_disasm_i_sltiu, // 0x0B + mips_disasm_i_andi, // 0x0C + mips_disasm_i_ori, // 0x0D + mips_disasm_i_xori, // 0x0E + mips_disasm_i_lui, // 0x0F + mips_disasm_unknown_instruction, // 0x10 + mips_disasm_fpu, // 0x11 + mips_disasm_unknown_instruction, // 0x12 + mips_disasm_unknown_instruction, // 0x13 + mips_disasm_unknown_instruction, // 0x14 + mips_disasm_unknown_instruction, // 0x15 + mips_disasm_unknown_instruction, // 0x16 + mips_disasm_unknown_instruction, // 0x17 + mips_disasm_unknown_instruction, // 0x18 + mips_disasm_unknown_instruction, // 0x19 + mips_disasm_unknown_instruction, // 0x1A + mips_disasm_unknown_instruction, // 0x1B + mips_disasm_r2_format, // 0x1C + mips_disasm_unknown_instruction, // 0x1D + mips_disasm_unknown_instruction, // 0x1E + mips_disasm_unknown_instruction, // 0x1F + mips_disasm_i_lb, // 0x20 + mips_disasm_i_lh, // 0x21 + mips_disasm_i_lwl, // 0x22 + mips_disasm_i_lw, // 0x23 + mips_disasm_i_lbu, // 0x24 + mips_disasm_i_lhu, // 0x25 + mips_disasm_i_lwr, // 0x26 + mips_disasm_unknown_instruction, // 0x27 + mips_disasm_i_sb, // 0x28 + mips_disasm_i_sh, // 0x29 + mips_disasm_i_swl, // 0x2A + mips_disasm_i_sw, // 0x2B + mips_disasm_unknown_instruction, // 0x2C + mips_disasm_unknown_instruction, // 0x2D + mips_disasm_i_swr, // 0x2E + mips_disasm_unknown_instruction, // 0x2F + mips_disasm_i_ll, // 0x30 + mips_disasm_unknown_instruction, // 0x31 + mips_disasm_unknown_instruction, // 0x32 + mips_disasm_unknown_instruction, // 0x33 + mips_disasm_unknown_instruction, // 0x34 + mips_disasm_unknown_instruction, // 0x35 + mips_disasm_unknown_instruction, // 0x36 + mips_disasm_unknown_instruction, // 0x37 + mips_disasm_i_sc, // 0x38 + mips_disasm_unknown_instruction, // 0x39 + mips_disasm_unknown_instruction, // 0x3A + mips_disasm_unknown_instruction, // 0x3B + mips_disasm_unknown_instruction, // 0x3C + mips_disasm_unknown_instruction, // 0x3D + mips_disasm_unknown_instruction, // 0x3E + mips_disasm_unknown_instruction // 0x3F }; mips_disasm_procedure mips_disasm_r_funct[64]= { - mips_disasm_r_sll, - mips_disasm_unknown_instruction, - mips_disasm_r_srl, - mips_disasm_r_sra, - mips_disasm_r_sllv, - mips_disasm_unknown_instruction, - mips_disasm_r_srlv, - mips_disasm_r_srav, - mips_disasm_r_jr, - mips_disasm_r_jalr, - mips_disasm_r_movz, - mips_disasm_r_movn, - mips_disasm_r_syscall, - mips_disasm_r_break, - mips_disasm_unknown_instruction, - mips_disasm_r_sync, - mips_disasm_r_mfhi, - mips_disasm_r_mthi, - mips_disasm_r_mflo, - mips_disasm_r_mtlo, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_r_mult, - mips_disasm_r_multu, - mips_disasm_r_div, - mips_disasm_r_divu, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_r_add, - mips_disasm_r_addu, - mips_disasm_r_sub, - mips_disasm_r_subu, - mips_disasm_r_and, - mips_disasm_r_or, - mips_disasm_r_xor, - mips_disasm_r_nor, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_r_slt, - mips_disasm_r_sltu, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction + mips_disasm_r_sll, // 0x00 + mips_disasm_unknown_instruction, // 0x01 + mips_disasm_r_srl, // 0x02 + mips_disasm_r_sra, // 0x03 + mips_disasm_r_sllv, // 0x04 + mips_disasm_unknown_instruction, // 0x05 + mips_disasm_r_srlv, // 0x06 + mips_disasm_r_srav, // 0x07 + mips_disasm_r_jr, // 0x08 + mips_disasm_r_jalr, // 0x09 + mips_disasm_r_movz, // 0x0A + mips_disasm_r_movn, // 0x0B + mips_disasm_r_syscall, // 0x0C + mips_disasm_r_break, // 0x0D + mips_disasm_unknown_instruction, // 0x0E + mips_disasm_r_sync, // 0x0F + mips_disasm_r_mfhi, // 0x10 + mips_disasm_r_mthi, // 0x11 + mips_disasm_r_mflo, // 0x12 + mips_disasm_r_mtlo, // 0x13 + mips_disasm_unknown_instruction, // 0x14 + mips_disasm_unknown_instruction, // 0x15 + mips_disasm_unknown_instruction, // 0x16 + mips_disasm_unknown_instruction, // 0x17 + mips_disasm_r_mult, // 0x18 + mips_disasm_r_multu, // 0x19 + mips_disasm_r_div, // 0x1A + mips_disasm_r_divu, // 0x1B + mips_disasm_unknown_instruction, // 0x1C + mips_disasm_unknown_instruction, // 0x1D + mips_disasm_unknown_instruction, // 0x1E + mips_disasm_unknown_instruction, // 0x1F + mips_disasm_r_add, // 0x20 + mips_disasm_r_addu, // 0x21 + mips_disasm_r_sub, // 0x22 + mips_disasm_r_subu, // 0x23 + mips_disasm_r_and, // 0x24 + mips_disasm_r_or, // 0x25 + mips_disasm_r_xor, // 0x26 + mips_disasm_r_nor, // 0x27 + mips_disasm_unknown_instruction, // 0x28 + mips_disasm_unknown_instruction, // 0x29 + mips_disasm_r_slt, // 0x2A + mips_disasm_r_sltu, // 0x2B + mips_disasm_unknown_instruction, // 0x2C + mips_disasm_unknown_instruction, // 0x2D + mips_disasm_unknown_instruction, // 0x2E + mips_disasm_unknown_instruction, // 0x2F + mips_disasm_r_tge, // 0x30 + mips_disasm_r_tgeu, // 0x31 + mips_disasm_r_tlt, // 0x32 + mips_disasm_r_tltu, // 0x33 + mips_disasm_r_teq, // 0x34 + mips_disasm_unknown_instruction, // 0x35 + mips_disasm_r_tne, // 0x36 + mips_disasm_unknown_instruction, // 0x37 + mips_disasm_unknown_instruction, // 0x38 + mips_disasm_unknown_instruction, // 0x39 + mips_disasm_unknown_instruction, // 0x3A + mips_disasm_unknown_instruction, // 0x3B + mips_disasm_unknown_instruction, // 0x3C + mips_disasm_unknown_instruction, // 0x3D + mips_disasm_unknown_instruction, // 0x3E + mips_disasm_unknown_instruction // 0x3F +}; + +mips_disasm_procedure mips_disasm_r2_funct[64]= +{ + mips_disasm_unknown_instruction, // 0x00 + mips_disasm_unknown_instruction, // 0x01 + mips_disasm_unknown_instruction, // 0x02 + mips_disasm_unknown_instruction, // 0x03 + mips_disasm_unknown_instruction, // 0x04 + mips_disasm_unknown_instruction, // 0x05 + mips_disasm_unknown_instruction, // 0x06 + mips_disasm_unknown_instruction, // 0x07 + mips_disasm_unknown_instruction, // 0x08 + mips_disasm_unknown_instruction, // 0x09 + mips_disasm_unknown_instruction, // 0x0A + mips_disasm_unknown_instruction, // 0x0B + mips_disasm_unknown_instruction, // 0x0C + mips_disasm_unknown_instruction, // 0x0D + mips_disasm_unknown_instruction, // 0x0E + mips_disasm_unknown_instruction, // 0x0F + mips_disasm_unknown_instruction, // 0x10 + mips_disasm_unknown_instruction, // 0x11 + mips_disasm_unknown_instruction, // 0x12 + mips_disasm_unknown_instruction, // 0x13 + mips_disasm_unknown_instruction, // 0x14 + mips_disasm_unknown_instruction, // 0x15 + mips_disasm_unknown_instruction, // 0x16 + mips_disasm_unknown_instruction, // 0x17 + mips_disasm_unknown_instruction, // 0x18 + mips_disasm_unknown_instruction, // 0x19 + mips_disasm_unknown_instruction, // 0x1A + mips_disasm_unknown_instruction, // 0x1B + mips_disasm_unknown_instruction, // 0x1C + mips_disasm_unknown_instruction, // 0x1D + mips_disasm_unknown_instruction, // 0x1E + mips_disasm_unknown_instruction, // 0x1F + mips_disasm_r_clz, // 0x20 + mips_disasm_r_clo, // 0x21 + mips_disasm_unknown_instruction, // 0x22 + mips_disasm_unknown_instruction, // 0x23 + mips_disasm_unknown_instruction, // 0x24 + mips_disasm_unknown_instruction, // 0x25 + mips_disasm_unknown_instruction, // 0x26 + mips_disasm_unknown_instruction, // 0x27 + mips_disasm_unknown_instruction, // 0x28 + mips_disasm_unknown_instruction, // 0x29 + mips_disasm_unknown_instruction, // 0x2A + mips_disasm_unknown_instruction, // 0x2B + mips_disasm_unknown_instruction, // 0x2C + mips_disasm_unknown_instruction, // 0x2D + mips_disasm_unknown_instruction, // 0x2E + mips_disasm_unknown_instruction, // 0x2F + mips_disasm_unknown_instruction, // 0x30 + mips_disasm_unknown_instruction, // 0x31 + mips_disasm_unknown_instruction, // 0x32 + mips_disasm_unknown_instruction, // 0x33 + mips_disasm_unknown_instruction, // 0x34 + mips_disasm_unknown_instruction, // 0x35 + mips_disasm_unknown_instruction, // 0x36 + mips_disasm_unknown_instruction, // 0x37 + mips_disasm_unknown_instruction, // 0x38 + mips_disasm_unknown_instruction, // 0x39 + mips_disasm_unknown_instruction, // 0x3A + mips_disasm_unknown_instruction, // 0x3B + mips_disasm_unknown_instruction, // 0x3C + mips_disasm_unknown_instruction, // 0x3D + mips_disasm_unknown_instruction, // 0x3E + mips_disasm_unknown_instruction // 0x3F }; mips_disasm_procedure mips_disasm_regimm_i_funct[32]= { - mips_disasm_unknown_instruction, - mips_disasm_i_bgez, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction, - mips_disasm_unknown_instruction + mips_disasm_i_bltz, // 0x00 + mips_disasm_i_bgez, // 0x01 + mips_disasm_unknown_instruction, // 0x02 + mips_disasm_unknown_instruction, // 0x03 + mips_disasm_unknown_instruction, // 0x04 + mips_disasm_unknown_instruction, // 0x05 + mips_disasm_unknown_instruction, // 0x06 + mips_disasm_unknown_instruction, // 0x07 + mips_disasm_i_tgei, // 0x08 + mips_disasm_i_tgeiu, // 0x09 + mips_disasm_i_tlti, // 0x0A + mips_disasm_i_tltiu, // 0x0B + mips_disasm_i_teqi, // 0x0C + mips_disasm_unknown_instruction, // 0x0D + mips_disasm_i_tnei, // 0x0E + mips_disasm_unknown_instruction, // 0x0F + mips_disasm_i_bltzal, // 0x10 + mips_disasm_i_bgezal, // 0x11 + mips_disasm_unknown_instruction, // 0x12 + mips_disasm_unknown_instruction, // 0x13 + mips_disasm_unknown_instruction, // 0x14 + mips_disasm_unknown_instruction, // 0x15 + mips_disasm_unknown_instruction, // 0x16 + mips_disasm_unknown_instruction, // 0x17 + mips_disasm_unknown_instruction, // 0x18 + mips_disasm_unknown_instruction, // 0x19 + mips_disasm_unknown_instruction, // 0x1A + mips_disasm_unknown_instruction, // 0x1B + mips_disasm_unknown_instruction, // 0x1C + mips_disasm_unknown_instruction, // 0x1D + mips_disasm_unknown_instruction, // 0x1E + mips_disasm_unknown_instruction // 0x1F }; #endif \ No newline at end of file diff --git a/src/include/simulation.h b/src/include/simulation.h index 171895d..6e5ecbd 100644 --- a/src/include/simulation.h +++ b/src/include/simulation.h @@ -52,6 +52,16 @@ void mips_interpreter_r_xor(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_r_nor(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_r_slt(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_r_sltu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_tge(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_tgeu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_tlt(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_tltu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_teq(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_tne(vmcb_p vcpu,mips_instruction instruction); + +// R2-Format Instructions +void mips_interpreter_r_clz(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_clo(vmcb_p vcpu,mips_instruction instruction); // I-Format Instructions void mips_interpreter_i_beq(vmcb_p vcpu,mips_instruction instruction); @@ -68,15 +78,30 @@ void mips_interpreter_i_xori(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lui(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lb(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lh(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lwl(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lw(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lbu(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_lhu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lwr(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_sb(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_sh(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_swl(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_sw(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_swr(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_ll(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_sc(vmcb_p vcpu,mips_instruction instruction); // RegImm I-Format Instructions +void mips_interpreter_i_bltz(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_i_bgez(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_tgei(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_tgeiu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_tlti(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_tltiu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_teqi(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_tnei(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_bltzal(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_bgezal(vmcb_p vcpu,mips_instruction instruction); // J-Format Instructions void mips_interpreter_j_j(vmcb_p vcpu,mips_instruction instruction); @@ -85,6 +110,7 @@ void mips_interpreter_j_jal(vmcb_p vcpu,mips_instruction instruction); // Miscellaneous void mips_interpreter_unhandled_instruction(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_r_format(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r2_format(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_regimm_i_format(vmcb_p vcpu,mips_instruction instruction); void mips_interpreter_fpu(vmcb_p vcpu,mips_instruction instruction); void mips_mars_syscall_handler(vmcb_p vcpu); @@ -92,174 +118,242 @@ void mips_mars_syscall_handler(vmcb_p vcpu); #if defined(_mips_hvm) mips_interpreter_procedure cpu_interpreter_by_opcode[64]= { - mips_interpreter_r_format, - mips_interpreter_regimm_i_format, - mips_interpreter_j_j, - mips_interpreter_j_jal, - mips_interpreter_i_beq, - mips_interpreter_i_bne, - mips_interpreter_i_blez, - mips_interpreter_i_bgtz, - mips_interpreter_i_addi, - mips_interpreter_i_addiu, - mips_interpreter_i_slti, - mips_interpreter_i_sltiu, - mips_interpreter_i_andi, - mips_interpreter_i_ori, - mips_interpreter_i_xori, - mips_interpreter_i_lui, - mips_interpreter_unhandled_instruction, - mips_interpreter_fpu, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_i_lb, - mips_interpreter_i_lh, - mips_interpreter_unhandled_instruction, - mips_interpreter_i_lw, - mips_interpreter_i_lbu, - mips_interpreter_i_lhu, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_i_sb, - mips_interpreter_i_sh, - mips_interpreter_unhandled_instruction, - mips_interpreter_i_sw, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction + mips_interpreter_r_format, // 0x00 + mips_interpreter_regimm_i_format, // 0x01 + mips_interpreter_j_j, // 0x02 + mips_interpreter_j_jal, // 0x03 + mips_interpreter_i_beq, // 0x04 + mips_interpreter_i_bne, // 0x05 + mips_interpreter_i_blez, // 0x06 + mips_interpreter_i_bgtz, // 0x07 + mips_interpreter_i_addi, // 0x08 + mips_interpreter_i_addiu, // 0x09 + mips_interpreter_i_slti, // 0x0A + mips_interpreter_i_sltiu, // 0x0B + mips_interpreter_i_andi, // 0x0C + mips_interpreter_i_ori, // 0x0D + mips_interpreter_i_xori, // 0x0E + mips_interpreter_i_lui, // 0x0F + mips_interpreter_unhandled_instruction, // 0x10 + mips_interpreter_fpu, // 0x11 + mips_interpreter_unhandled_instruction, // 0x12 + mips_interpreter_unhandled_instruction, // 0x13 + mips_interpreter_unhandled_instruction, // 0x14 + mips_interpreter_unhandled_instruction, // 0x15 + mips_interpreter_unhandled_instruction, // 0x16 + mips_interpreter_unhandled_instruction, // 0x17 + mips_interpreter_unhandled_instruction, // 0x18 + mips_interpreter_unhandled_instruction, // 0x19 + mips_interpreter_unhandled_instruction, // 0x1A + mips_interpreter_unhandled_instruction, // 0x1B + mips_interpreter_r2_format, // 0x1C + mips_interpreter_unhandled_instruction, // 0x1D + mips_interpreter_unhandled_instruction, // 0x1E + mips_interpreter_unhandled_instruction, // 0x1F + mips_interpreter_i_lb, // 0x20 + mips_interpreter_i_lh, // 0x21 + mips_interpreter_i_lwl, // 0x22 + mips_interpreter_i_lw, // 0x23 + mips_interpreter_i_lbu, // 0x24 + mips_interpreter_i_lhu, // 0x25 + mips_interpreter_i_lwr, // 0x26 + mips_interpreter_unhandled_instruction, // 0x27 + mips_interpreter_i_sb, // 0x28 + mips_interpreter_i_sh, // 0x29 + mips_interpreter_i_swl, // 0x2A + mips_interpreter_i_sw, // 0x2B + mips_interpreter_unhandled_instruction, // 0x2C + mips_interpreter_unhandled_instruction, // 0x2D + mips_interpreter_i_swr, // 0x2E + mips_interpreter_unhandled_instruction, // 0x2F + mips_interpreter_i_ll, // 0x30 + mips_interpreter_unhandled_instruction, // 0x31 + mips_interpreter_unhandled_instruction, // 0x32 + mips_interpreter_unhandled_instruction, // 0x33 + mips_interpreter_unhandled_instruction, // 0x34 + mips_interpreter_unhandled_instruction, // 0x35 + mips_interpreter_unhandled_instruction, // 0x36 + mips_interpreter_unhandled_instruction, // 0x37 + mips_interpreter_i_sc, // 0x38 + mips_interpreter_unhandled_instruction, // 0x39 + mips_interpreter_unhandled_instruction, // 0x3A + mips_interpreter_unhandled_instruction, // 0x3B + mips_interpreter_unhandled_instruction, // 0x3C + mips_interpreter_unhandled_instruction, // 0x3D + mips_interpreter_unhandled_instruction, // 0x3E + mips_interpreter_unhandled_instruction // 0x3F }; mips_interpreter_procedure cpu_interpreter_r_funct[64]= { - mips_interpreter_r_sll, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_srl, - mips_interpreter_r_sra, - mips_interpreter_r_sllv, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_srlv, - mips_interpreter_r_srav, - mips_interpreter_r_jr, - mips_interpreter_r_jalr, - mips_interpreter_r_movz, - mips_interpreter_r_movn, - mips_interpreter_r_syscall, - mips_interpreter_r_break, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_sync, - mips_interpreter_r_mfhi, - mips_interpreter_r_mthi, - mips_interpreter_r_mflo, - mips_interpreter_r_mtlo, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_mult, - mips_interpreter_r_multu, - mips_interpreter_r_div, - mips_interpreter_r_divu, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_add, - mips_interpreter_r_addu, - mips_interpreter_r_sub, - mips_interpreter_r_subu, - mips_interpreter_r_and, - mips_interpreter_r_or, - mips_interpreter_r_xor, - mips_interpreter_r_nor, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_r_slt, - mips_interpreter_r_sltu, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction + mips_interpreter_r_sll, // 0x00 + mips_interpreter_unhandled_instruction, // 0x01 + mips_interpreter_r_srl, // 0x02 + mips_interpreter_r_sra, // 0x03 + mips_interpreter_r_sllv, // 0x04 + mips_interpreter_unhandled_instruction, // 0x05 + mips_interpreter_r_srlv, // 0x06 + mips_interpreter_r_srav, // 0x07 + mips_interpreter_r_jr, // 0x08 + mips_interpreter_r_jalr, // 0x09 + mips_interpreter_r_movz, // 0x0A + mips_interpreter_r_movn, // 0x0B + mips_interpreter_r_syscall, // 0x0C + mips_interpreter_r_break, // 0x0D + mips_interpreter_unhandled_instruction, // 0x0E + mips_interpreter_r_sync, // 0x0F + mips_interpreter_r_mfhi, // 0x10 + mips_interpreter_r_mthi, // 0x11 + mips_interpreter_r_mflo, // 0x12 + mips_interpreter_r_mtlo, // 0x13 + mips_interpreter_unhandled_instruction, // 0x14 + mips_interpreter_unhandled_instruction, // 0x15 + mips_interpreter_unhandled_instruction, // 0x16 + mips_interpreter_unhandled_instruction, // 0x17 + mips_interpreter_r_mult, // 0x18 + mips_interpreter_r_multu, // 0x19 + mips_interpreter_r_div, // 0x1A + mips_interpreter_r_divu, // 0x1B + mips_interpreter_unhandled_instruction, // 0x1C + mips_interpreter_unhandled_instruction, // 0x1D + mips_interpreter_unhandled_instruction, // 0x1E + mips_interpreter_unhandled_instruction, // 0x1F + mips_interpreter_r_add, // 0x20 + mips_interpreter_r_addu, // 0x21 + mips_interpreter_r_sub, // 0x22 + mips_interpreter_r_subu, // 0x23 + mips_interpreter_r_and, // 0x24 + mips_interpreter_r_or, // 0x25 + mips_interpreter_r_xor, // 0x26 + mips_interpreter_r_nor, // 0x27 + mips_interpreter_unhandled_instruction, // 0x28 + mips_interpreter_unhandled_instruction, // 0x29 + mips_interpreter_r_slt, // 0x2A + mips_interpreter_r_sltu, // 0x2B + mips_interpreter_unhandled_instruction, // 0x2C + mips_interpreter_unhandled_instruction, // 0x2D + mips_interpreter_unhandled_instruction, // 0x2E + mips_interpreter_unhandled_instruction, // 0x2F + mips_interpreter_r_tge, // 0x30 + mips_interpreter_r_tgeu, // 0x31 + mips_interpreter_r_tlt, // 0x32 + mips_interpreter_r_tltu, // 0x33 + mips_interpreter_r_teq, // 0x34 + mips_interpreter_unhandled_instruction, // 0x35 + mips_interpreter_r_tne, // 0x36 + mips_interpreter_unhandled_instruction, // 0x37 + mips_interpreter_unhandled_instruction, // 0x38 + mips_interpreter_unhandled_instruction, // 0x39 + mips_interpreter_unhandled_instruction, // 0x3A + mips_interpreter_unhandled_instruction, // 0x3B + mips_interpreter_unhandled_instruction, // 0x3C + mips_interpreter_unhandled_instruction, // 0x3D + mips_interpreter_unhandled_instruction, // 0x3E + mips_interpreter_unhandled_instruction // 0x3F +}; + +mips_interpreter_procedure cpu_interpreter_r2_funct[64]= +{ + mips_interpreter_unhandled_instruction, // 0x00 + mips_interpreter_unhandled_instruction, // 0x01 + mips_interpreter_unhandled_instruction, // 0x02 + mips_interpreter_unhandled_instruction, // 0x03 + mips_interpreter_unhandled_instruction, // 0x04 + mips_interpreter_unhandled_instruction, // 0x05 + mips_interpreter_unhandled_instruction, // 0x06 + mips_interpreter_unhandled_instruction, // 0x07 + mips_interpreter_unhandled_instruction, // 0x08 + mips_interpreter_unhandled_instruction, // 0x09 + mips_interpreter_unhandled_instruction, // 0x0A + mips_interpreter_unhandled_instruction, // 0x0B + mips_interpreter_unhandled_instruction, // 0x0C + mips_interpreter_unhandled_instruction, // 0x0D + mips_interpreter_unhandled_instruction, // 0x0E + mips_interpreter_unhandled_instruction, // 0x0F + mips_interpreter_unhandled_instruction, // 0x10 + mips_interpreter_unhandled_instruction, // 0x11 + mips_interpreter_unhandled_instruction, // 0x12 + mips_interpreter_unhandled_instruction, // 0x13 + mips_interpreter_unhandled_instruction, // 0x14 + mips_interpreter_unhandled_instruction, // 0x15 + mips_interpreter_unhandled_instruction, // 0x16 + mips_interpreter_unhandled_instruction, // 0x17 + mips_interpreter_unhandled_instruction, // 0x18 + mips_interpreter_unhandled_instruction, // 0x19 + mips_interpreter_unhandled_instruction, // 0x1A + mips_interpreter_unhandled_instruction, // 0x1B + mips_interpreter_unhandled_instruction, // 0x1C + mips_interpreter_unhandled_instruction, // 0x1D + mips_interpreter_unhandled_instruction, // 0x1E + mips_interpreter_unhandled_instruction, // 0x1F + mips_interpreter_r_clz, // 0x20 + mips_interpreter_r_clo, // 0x21 + mips_interpreter_unhandled_instruction, // 0x22 + mips_interpreter_unhandled_instruction, // 0x23 + mips_interpreter_unhandled_instruction, // 0x24 + mips_interpreter_unhandled_instruction, // 0x25 + mips_interpreter_unhandled_instruction, // 0x26 + mips_interpreter_unhandled_instruction, // 0x27 + mips_interpreter_unhandled_instruction, // 0x28 + mips_interpreter_unhandled_instruction, // 0x29 + mips_interpreter_unhandled_instruction, // 0x2A + mips_interpreter_unhandled_instruction, // 0x2B + mips_interpreter_unhandled_instruction, // 0x2C + mips_interpreter_unhandled_instruction, // 0x2D + mips_interpreter_unhandled_instruction, // 0x2E + mips_interpreter_unhandled_instruction, // 0x2F + mips_interpreter_unhandled_instruction, // 0x30 + mips_interpreter_unhandled_instruction, // 0x31 + mips_interpreter_unhandled_instruction, // 0x32 + mips_interpreter_unhandled_instruction, // 0x33 + mips_interpreter_unhandled_instruction, // 0x34 + mips_interpreter_unhandled_instruction, // 0x35 + mips_interpreter_unhandled_instruction, // 0x36 + mips_interpreter_unhandled_instruction, // 0x37 + mips_interpreter_unhandled_instruction, // 0x38 + mips_interpreter_unhandled_instruction, // 0x39 + mips_interpreter_unhandled_instruction, // 0x3A + mips_interpreter_unhandled_instruction, // 0x3B + mips_interpreter_unhandled_instruction, // 0x3C + mips_interpreter_unhandled_instruction, // 0x3D + mips_interpreter_unhandled_instruction, // 0x3E + mips_interpreter_unhandled_instruction // 0x3F }; mips_interpreter_procedure cpu_interpreter_regimm_i_funct[32]= { - mips_interpreter_unhandled_instruction, - mips_interpreter_i_bgez, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction, - mips_interpreter_unhandled_instruction + mips_interpreter_i_bltz, // 0x00 + mips_interpreter_i_bgez, // 0x01 + mips_interpreter_unhandled_instruction, // 0x02 + mips_interpreter_unhandled_instruction, // 0x03 + mips_interpreter_unhandled_instruction, // 0x04 + mips_interpreter_unhandled_instruction, // 0x05 + mips_interpreter_unhandled_instruction, // 0x06 + mips_interpreter_unhandled_instruction, // 0x07 + mips_interpreter_i_tgei, // 0x08 + mips_interpreter_i_tgeiu, // 0x09 + mips_interpreter_i_tlti, // 0x0A + mips_interpreter_i_tltiu, // 0x0B + mips_interpreter_i_teqi, // 0x0C + mips_interpreter_unhandled_instruction, // 0x0D + mips_interpreter_i_tnei, // 0x0E + mips_interpreter_unhandled_instruction, // 0x0F + mips_interpreter_i_bltzal, // 0x10 + mips_interpreter_i_bgezal, // 0x11 + mips_interpreter_unhandled_instruction, // 0x12 + mips_interpreter_unhandled_instruction, // 0x13 + mips_interpreter_unhandled_instruction, // 0x14 + mips_interpreter_unhandled_instruction, // 0x15 + mips_interpreter_unhandled_instruction, // 0x16 + mips_interpreter_unhandled_instruction, // 0x17 + mips_interpreter_unhandled_instruction, // 0x18 + mips_interpreter_unhandled_instruction, // 0x19 + mips_interpreter_unhandled_instruction, // 0x1A + mips_interpreter_unhandled_instruction, // 0x1B + mips_interpreter_unhandled_instruction, // 0x1C + mips_interpreter_unhandled_instruction, // 0x1D + mips_interpreter_unhandled_instruction, // 0x1E + mips_interpreter_unhandled_instruction // 0x1F }; mips_interpreter_procedure fpu_interpreter[64]; diff --git a/src/include/vmcb.h b/src/include/vmcb.h index 976a3dd..fa75acf 100644 --- a/src/include/vmcb.h +++ b/src/include/vmcb.h @@ -15,6 +15,7 @@ #include "midef.h" #define mipsivm_vcpu_flags_stop_interpretation 31 +#define mipsivm_vcpu_flags_trapped 1 #define mipsivm_vcpu_flags_debug_break 0 // We use paging to virtualize memory. diff --git a/src/mars.c b/src/mars.c index 5efb687..d8f9b45 100644 --- a/src/mars.c +++ b/src/mars.c @@ -114,7 +114,7 @@ void mips_mars_syscall_handler(vmcb_p vcpu) } case mips_mars_syscall_exit: { - _bittestandset(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation); + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation); vcpu->tsc+=2; break; } @@ -131,7 +131,7 @@ void mips_mars_syscall_handler(vmcb_p vcpu) } case mips_mars_syscall_print_hex: { - sim_printf("0x%X",vcpu->gpr.ureg[mips_gpr_a0]); + sim_printf("0x%08x",vcpu->gpr.ureg[mips_gpr_a0]); break; } case mips_mars_syscall_print_unsigned: @@ -166,7 +166,7 @@ bool mips_init_mars_vm(void* ds,void* ts,u32 ds_size,u32 ts_size,u32 stack_size, vm.stack.address=alloc_page(stack_size); vm.stack.size=stack_size; if(vm.stack.address==null)return false; - if(break_on_start)_bittestandset(&vm.vcpu.flags,mipsivm_vcpu_flags_debug_break); + if(break_on_start)intrin_bts(&vm.vcpu.flags,mipsivm_vcpu_flags_debug_break); return mips_init_mars_vm_npt(); } diff --git a/src/sim-i.c b/src/sim-i.c index b924b4a..a0f57a2 100644 --- a/src/sim-i.c +++ b/src/sim-i.c @@ -15,6 +15,7 @@ #include #include #include +#include // Normal I-Format Instructions void mips_interpreter_i_beq(vmcb_p vcpu,mips_instruction instruction) @@ -180,6 +181,24 @@ void mips_interpreter_i_lh(vmcb_p vcpu,mips_instruction instruction) vcpu->tsc+=3; } +void mips_interpreter_i_lwl(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Word Left + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + const u32 n=gpa&3; + u8* p=(u8*)mips_ref_hmem(vcpu,gpa-n,true,false,false,true); + if(p) + { + u8* q=(u8*)&vcpu->gpr.ureg[rt]; + for(u32 i=0;i<=n;i++) + q[i+3-n]=p[i]; + } + vcpu->gpr.pc+=4; + vcpu->tsc+=4; +} + void mips_interpreter_i_lw(vmcb_p vcpu,mips_instruction instruction) { // Definition: Load Word @@ -225,6 +244,24 @@ void mips_interpreter_i_lhu(vmcb_p vcpu,mips_instruction instruction) vcpu->tsc+=3; } +void mips_interpreter_i_lwr(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Word Right + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + const u32 n=gpa&3; + u8* p=(u8*)mips_ref_hmem(vcpu,gpa-n,true,false,false,true); + if(p) + { + u8* q=(u8*)&vcpu->gpr.ureg[rt]; + for(u8 i=0;i<4-n;i++) + q[i]=p[i+2-n]; + } + vcpu->gpr.pc+=4; + vcpu->tsc+=4; +} + void mips_interpreter_i_sb(vmcb_p vcpu,mips_instruction instruction) { // Definition: Store Byte @@ -254,6 +291,23 @@ void mips_interpreter_i_sh(vmcb_p vcpu,mips_instruction instruction) vcpu->tsc+=3; } +void mips_interpreter_i_swl(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Word Left + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + const u32 n=gpa&3; + u8* p=(u8*)mips_ref_hmem(vcpu,gpa-n,true,false,false,true); + if(p) + { + u8* q=(u8*)&vcpu->gpr.ureg[rt]; + for(u8 i=0;i<=n;i++)p[i]=q[i+3-n]; + } + vcpu->gpr.pc+=4; + vcpu->tsc+=4; +} + void mips_interpreter_i_sw(vmcb_p vcpu,mips_instruction instruction) { // Definition: Store Word @@ -270,7 +324,71 @@ void mips_interpreter_i_sw(vmcb_p vcpu,mips_instruction instruction) vcpu->tsc+=3; } +void mips_interpreter_i_swr(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Word Right + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + const u32 n=gpa&3; + u8* p=(u8*)mips_ref_hmem(vcpu,gpa-n,true,false,false,true); + if(p) + { + u8* q=(u8*)&vcpu->gpr.ureg[rt]; + for(u8 i=0;i<4-n;i++)p[i+4-n]=q[i]; + } + vcpu->gpr.pc+=4; + vcpu->tsc+=4; +} + +void mips_interpreter_i_ll(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Linked + // Formula (x86 Asm): lock mov rt,dword ptr[rs+imm] + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 3)==0) // Alignment Check + { + i32* volatile hva=(i32*)mips_ref_hmem(vcpu,gpa,true,false,false,true); + if(hva)vcpu->gpr.ireg[rt]=*hva; + } + vcpu->gpr.pc+=4; + vcpu->tsc+=3; +} + +void mips_interpreter_i_sc(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Conditional + // Formula (x86 Asm): lock mov rt,dword ptr[rs+imm] + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 3)==0) // Alignment Check + { + i32* volatile hva=(i32*)mips_ref_hmem(vcpu,gpa,true,false,false,true); + if(hva) + { + intrin_locked_xchg(hva,vcpu->gpr.ireg[rt]); + vcpu->gpr.ireg[rt]=1; + } + } + vcpu->gpr.pc+=4; + vcpu->tsc+=3; +} + // RegImm I-Format Instructions +void mips_interpreter_i_bltz(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Greater than or Equal to Zero + // Formula: if rs>=0 then pc+=(imm<<2)+4 + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]<0)vcpu->gpr.pc+=(imm<<2); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + void mips_interpreter_i_bgez(vmcb_p vcpu,mips_instruction instruction) { // Definition: Branch if Greater than or Equal to Zero @@ -279,4 +397,107 @@ void mips_interpreter_i_bgez(vmcb_p vcpu,mips_instruction instruction) const u32 rs=instruction.i.rs; if(vcpu->gpr.ireg[rs]>=0)vcpu->gpr.pc+=(imm<<2); vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_tgei(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Greater than or Equal to Immediate. + // Formula: if rs>=imm then trap. + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]>=imm) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_tgeiu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Greater than or Equal to Immediate Unsigned. + // Formula: if rs>=imm then trap. + const u32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ureg[rs]>=imm) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_tlti(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Less Than Immediate. + // Formula: if rsgpr.ireg[rs]flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_tltiu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Less Than Immediate Unsigned. + // Formula: if rsgpr.ureg[rs]flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_teqi(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Equal to Immediate. + // Formula: if rs==imm then trap. + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]==imm) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_tnei(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Not Equal to Immediate. + // Formula: if rs!=imm then trap. + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]!=imm) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_i_bltzal(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Greater than or Equal to Zero + // Formula: if rs>=0 then ra=pc+4;pc+=(imm<<2)+4 + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + vcpu->gpr.pc+=4; + if(vcpu->gpr.ireg[rs]<0) + { + vcpu->gpr.ureg[mips_gpr_ra]=vcpu->gpr.pc; + vcpu->gpr.pc+=(imm<<2); + } + vcpu->tsc+=1; +} + +void mips_interpreter_i_bgezal(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Greater than or Equal to Zero + // Formula: if rs>=0 then pc+=(imm<<2)+4 + const i32 imm=(i32)((i16)instruction.i.imm); + const u32 rs=instruction.i.rs; + vcpu->gpr.pc+=4; + if(vcpu->gpr.ireg[rs]>=0) + { + vcpu->gpr.ureg[mips_gpr_ra]=vcpu->gpr.pc; + vcpu->gpr.pc+=(imm<<2); + } + vcpu->tsc+=1; } \ No newline at end of file diff --git a/src/sim-r.c b/src/sim-r.c index c6f429e..7ce83b6 100644 --- a/src/sim-r.c +++ b/src/sim-r.c @@ -96,8 +96,9 @@ void mips_interpreter_r_jr(vmcb_p vcpu,mips_instruction instruction) void mips_interpreter_r_jalr(vmcb_p vcpu,mips_instruction instruction) { // Definition: jalr - Jump And Link uregister - // Formula: rd=pc+8;pc=rs - const u32 rd=instruction.r.rd,rs=instruction.r.rs; + // Formula: rd=pc+4;pc=rs + u32 rd=instruction.r.rd,rs=instruction.r.rs; + if(rd==0)rd=31; // rd=0 implies ra register. vcpu->gpr.ureg[rd]=vcpu->gpr.pc+4; vcpu->gpr.pc=vcpu->gpr.ureg[rs]; vcpu->tsc+=1; @@ -142,7 +143,7 @@ void mips_interpreter_r_break(vmcb_p vcpu,mips_instruction instruction) { // Definition: Breakpoint // Formula: trap into break exception handler - _bittestandset(&vcpu->flags,mipsivm_vcpu_flags_debug_break); + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_debug_break); vcpu->gpr.pc+=4; } @@ -334,4 +335,93 @@ void mips_interpreter_r_sltu(vmcb_p vcpu,mips_instruction instruction) vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]gpr.ureg[rt]?1:0; vcpu->gpr.pc+=4; vcpu->tsc+=1; +} + +void mips_interpreter_r_tge(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Greater than or Equal to. + // Formula: if rs>=rt then trap. + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + if(vcpu->gpr.ireg[rs]>=vcpu->gpr.ireg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_r_tgeu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Greater than or Equal to Unsigned. + // Formula: if rs>=rt then trap. + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + if(vcpu->gpr.ureg[rs]>=vcpu->gpr.ureg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_r_tlt(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Less Than. + // Formula: if rsgpr.ireg[rs]gpr.ireg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_r_tltu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Less Than Unsigned. + // Formula: if rsgpr.ureg[rs]gpr.ureg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_r_teq(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Equal to. + // Formula: if rs==rt then trap. + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + if(vcpu->gpr.ureg[rs]==vcpu->gpr.ureg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +void mips_interpreter_r_tne(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Trap if Not Equal to. + // Formula: if rs!=rt then trap. + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + if(vcpu->gpr.ureg[rs]!=vcpu->gpr.ureg[rt]) + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_trapped); + vcpu->gpr.pc+=4; + vcpu->tsc+=1; +} + +// R2-Format Instructions +void mips_interpreter_r_clz(vmcb_p vcpu,mips_instruction instruction) +{ + i32 i=31; + for(;i>=0;i--) + if(!intrin_bt(&vcpu->gpr.ureg[instruction.r.rs],i)) + break; + vcpu->gpr.ireg[instruction.r.rd]=31-i; + vcpu->gpr.pc+=4; + vcpu->tsc+=2; +} + +void mips_interpreter_r_clo(vmcb_p vcpu,mips_instruction instruction) +{ + i32 i=31; + for(;i>=0;i--) + if(intrin_bt(&vcpu->gpr.ureg[instruction.r.rs],i)) + break; + vcpu->gpr.ireg[instruction.r.rd]=31-i; + vcpu->gpr.pc+=4; + vcpu->tsc+=2; } \ No newline at end of file diff --git a/src/vcpu.c b/src/vcpu.c index b8be095..856b497 100644 --- a/src/vcpu.c +++ b/src/vcpu.c @@ -138,7 +138,7 @@ void mips_npt_cleanup(vmcb_p vcpu) void mips_interpreter_unhandled_instruction(vmcb_p vcpu,mips_instruction instruction) { sim_printf("#UD Exception! (Unknown Instruction)\n"); - _bittestandset(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation); + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation); } void mips_interpreter_r_format(vmcb_p vcpu,mips_instruction instruction) @@ -146,6 +146,11 @@ void mips_interpreter_r_format(vmcb_p vcpu,mips_instruction instruction) cpu_interpreter_r_funct[instruction.r.funct](vcpu,instruction); } +void mips_interpreter_r2_format(vmcb_p vcpu,mips_instruction instruction) +{ + cpu_interpreter_r2_funct[instruction.r.funct](vcpu,instruction); +} + void mips_interpreter_regimm_i_format(vmcb_p vcpu,mips_instruction instruction) { cpu_interpreter_regimm_i_funct[instruction.i.rt](vcpu,instruction); @@ -171,10 +176,15 @@ void mips_vcpu_dump_state(vmcb_p vcpu) void mips_vcpu_process_debugbreak(vmcb_p vcpu,mips_instruction instruction) { - if(_bittest(&vcpu->flags,mipsivm_vcpu_flags_debug_break)) + bool dbg_break=intrin_bt(&vcpu->flags,mipsivm_vcpu_flags_debug_break); + bool trapped=intrin_bt(&vcpu->flags,mipsivm_vcpu_flags_trapped); + if(dbg_break || trapped) { bool in_dbg=true; - sim_printf("Debug-break is intercepted!\n"); + if(dbg_break) + sim_printf("Debug-break is intercepted!\n"); + else + sim_printf("Trap condition is met!\n"); while(in_dbg) { char dbgcmd[64]; @@ -221,7 +231,8 @@ void mips_vcpu_process_debugbreak(vmcb_p vcpu,mips_instruction instruction) case 'g': // Continue. in_dbg=false; - _bittestandreset(&vcpu->flags,mipsivm_vcpu_flags_debug_break); + intrin_btr(&vcpu->flags,mipsivm_vcpu_flags_debug_break); + intrin_btr(&vcpu->flags,mipsivm_vcpu_flags_trapped); break; case 'r': // Dump Registers. @@ -229,7 +240,9 @@ void mips_vcpu_process_debugbreak(vmcb_p vcpu,mips_instruction instruction) break; case 't': // Step. - in_dbg=false; // DO NOT RESET DEBUG-BREAK FLAGS HERE! + in_dbg=false; + intrin_bts(&vcpu->flags,mipsivm_vcpu_flags_debug_break); + intrin_btr(&vcpu->flags,mipsivm_vcpu_flags_trapped); break; case 'u': // Disassemble. @@ -249,7 +262,7 @@ void mips_vcpu_process_debugbreak(vmcb_p vcpu,mips_instruction instruction) void mips_vcpu_start_interpretation(vmcb_p vcpu) { - while(!_bittest(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation)) + while(!intrin_bt(&vcpu->flags,mipsivm_vcpu_flags_stop_interpretation)) { // Reference HVA by GPA. u32* ip=(u32*)mips_ref_hmem(vcpu,vcpu->gpr.pc,true,false,true,true); diff --git a/test/unaligned/build.bat b/test/unaligned/build.bat new file mode 100644 index 0000000..55116d3 --- /dev/null +++ b/test/unaligned/build.bat @@ -0,0 +1,7 @@ +@echo off + +echo Assembling... +java -jar ..\mars.jar nc a .\unaligned.s dump .text Binary .\unaligned.text.bin dump .data Binary .\unaligned.data.bin +echo Completed! + +pause. \ No newline at end of file diff --git a/test/unaligned/unaligned.s b/test/unaligned/unaligned.s new file mode 100644 index 0000000..b6c3fef --- /dev/null +++ b/test/unaligned/unaligned.s @@ -0,0 +1,39 @@ +.data +stuff: .word 0x01020304, 0x05060708 + +.text +.globl main +main: + move $a1, $zero + la $a1, stuff + # Load Left and Print + lwl $a2, 2($a1) + li $v0, 34 + move $a0, $a2 + syscall + # New linefeed + li $v0, 11 + li $a0, '\n' + syscall + # Load Right and Print + lwr $a2, 5($a1) + li $v0, 34 + move $a0, $a2 + syscall + # New linefeed + li $v0, 11 + li $a0, '\n' + syscall + # Write Back + li $a3, 0xAABBCCDD + swr $a3, 6($a1) + swl $a3, 1($a1) + # Print Memory + li $v0, 34 + lw $a0, 0($a1) + syscall + lw $a0, 4($a1) + syscall + # Quit + li $v0, 10 + syscall