From 2f34872a898a60027704096bbf0950bec8e1cab8 Mon Sep 17 00:00:00 2001 From: Zero Tang Date: Fri, 29 Jan 2021 01:47:26 +0800 Subject: [PATCH] Update by Jan.29th, 2021 Add support to trap instructions Add support to conditional branch (and link) instructions. Add support to clo/clz instructions. Add support to unaligned memory access instructions (lwl/lwr/swl/swr). By now, I assume there is only coprocessor instructions remaining unsupported by mipsivm in comparison to MARS. Add test case for unaligned memory accesses. Fix disassembly in nop instruction. Fix missing disassembly compilation in free script preset. Update readme. --- .gitattributes | 3 +- README.md | 12 ++ compfre_win10x64.bat | 6 + src/disasm-i.c | 90 ++++++++ src/disasm-r.c | 51 ++++- src/disasm.c | 5 + src/include/devkit.h | 11 +- src/include/disasm.h | 414 +++++++++++++++++++++++-------------- src/include/simulation.h | 414 +++++++++++++++++++++++-------------- src/include/vmcb.h | 1 + src/mars.c | 6 +- src/sim-i.c | 221 ++++++++++++++++++++ src/sim-r.c | 96 ++++++++- src/vcpu.c | 25 ++- test/unaligned/build.bat | 7 + test/unaligned/unaligned.s | 39 ++++ 16 files changed, 1065 insertions(+), 336 deletions(-) create mode 100644 test/unaligned/build.bat create mode 100644 test/unaligned/unaligned.s 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