diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-18 08:55:51 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-18 08:55:51 +0000 |
| commit | 4b74a1be58d940ae58a4d7325bac64994bd0f35c (patch) | |
| tree | b671d78e5513246a672157c5f7c475c87ed3ef70 /src | |
| parent | 2aeb77736f07bdc3bd259093c02aadfd20d69e7f (diff) | |
| download | box64-4b74a1be58d940ae58a4d7325bac64994bd0f35c.tar.gz box64-4b74a1be58d940ae58a4d7325bac64994bd0f35c.zip | |
[RV64_DYNAREC] Added D3 /4 /5 SHL opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 17 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_shift.c | 48 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
3 files changed, 61 insertions, 6 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 8f71c229..ffe95ade 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -670,14 +670,21 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD3: nextop = F8; switch((nextop>>3)&7) { + case 4: + case 6: + INST_NAME("SHL Ed, CL"); + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined + ANDI(x3, xRCX, rex.w?0x3f:0x1f); + GETED(0); + if(!rex.w && MODREG) {ZEROUP(ed);} + CBZ_NEXT(x3); + emit_shl32(dyn, ninst, rex, ed, x3, x5, x4, x6); + WBACK; + break; case 7: INST_NAME("SAR Ed, CL"); SETFLAGS(X_ALL, SF_PENDING); - if(rex.w) { - ANDI(x3, xRCX, 0x3f); - } else { - ANDI(x3, xRCX, 0x1f); - } + ANDI(x3, xRCX, rex.w?0x3f:0x1f); GETED(0); if(!rex.w && MODREG) {ZEROUP(ed);} CBZ_NEXT(x3); diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c index eccf668b..015ea2f5 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c @@ -23,6 +23,54 @@ #include "dynarec_rv64_functions.h" #include "dynarec_rv64_helper.h" +// emit SHL32 instruction, from s1 , shift s2, store result in s1 using s3, s4 and s5 as scratch +void emit_shl32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +{ + // s2 is not 0 here and is 1..1f/3f + CLEAR_FLAGS(); + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, op1)); + SDxw(s2, xEmu, offsetof(x64emu_t, op2)); + SET_DF(s4, rex.w?d_shl64:d_shl32); + } else IFX(X_ALL) { + SET_DFNONE(s4); + } + + IFX(X_CF) { + SUBI(s5, s2, rex.w?64:32); + NEG(s5, s5); + SRL(s3, s1, s5); + ANDI(s5, s3, 1); // LSB + BEQZ(s5, 8); + ORI(xFlags, xFlags, 1 << F_CF); + } + + SLL(s1, s1, s2); + + IFX(X_SF) { + BGE(s1, xZR, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + if (!rex.w) { + ZEROUP(s1); + } + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + BNEZ(s1, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_OF) { + SRLIxw(s3, s1, rex.w?63:31); + XOR(s3, s3, s5); + BEQZ(s3, 8); + ORI(xFlags, xFlags, 1 << F_OF2); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} // emit SHL32 instruction, from s1 , constant c, store result in s1 using s3, s4 and s5 as scratch void emit_shl32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4, int s5) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index ba7f675f..eedded89 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -583,7 +583,7 @@ void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i //void emit_neg32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4); //void emit_neg16(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); //void emit_neg8(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); -//void emit_shl32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); +void emit_shl32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_shl32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4, int s5); //void emit_shr32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_shr32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); |