diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-20 15:17:15 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-20 15:17:15 +0100 |
| commit | 9a9d51440a09dc42a6066e5cdb4767f26b6fcb3e (patch) | |
| tree | 40598d46206460a0f1ee854f6fbc36518295df68 /src | |
| parent | 4b3e632d14667af1a81e2a3125b5f1ee7d979fc6 (diff) | |
| download | box64-9a9d51440a09dc42a6066e5cdb4767f26b6fcb3e.tar.gz box64-9a9d51440a09dc42a6066e5cdb4767f26b6fcb3e.zip | |
[DYNAREC] Added F6 opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 59 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_math.c | 90 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_tests.c | 65 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 4 |
4 files changed, 135 insertions, 83 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 02a67cf1..c3a79c4c 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -1102,6 +1102,65 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin *ok = 0; break; + case 0xF6: + nextop = F8; + switch((nextop>>3)&7) { + case 0: + case 1: + INST_NAME("TEST Eb, Ib"); + SETFLAGS(X_ALL, SF_SET); + GETEB(x1, 1); + u8 = F8; + MOV32w(x2, u8); + emit_test8(dyn, ninst, x1, x2, x3, x4, x5); + break; + case 2: + INST_NAME("NOT Eb"); + GETEB(x1, 0); + MVNw_REG(x1, x1); + EBBACK; + break; + case 3: + INST_NAME("NEG Eb"); + SETFLAGS(X_ALL, SF_PENDING); + GETEB(x1, 0); + emit_neg8(dyn, ninst, x1, x2, x4); + EBBACK; + break; + case 4: + INST_NAME("MUL AL, Ed"); + SETFLAGS(X_ALL, SF_PENDING); + UFLAG_DF(x1, d_mul8); + GETEB(x1, 0); + UXTBw(x2, xRAX); + MULw(x1, x2, x1); + UFLAG_RES(x1); + BFIx(xRAX, x1, 0, 16); + break; + case 5: + INST_NAME("IMUL AL, Eb"); + SETFLAGS(X_ALL, SF_PENDING); + UFLAG_DF(x1, d_imul8); + GETSEB(x1, 0); + SXTBw(x2, xRAX); + MULw(x1, x2, x1); + UFLAG_RES(x1); + BFIx(xRAX, x1, 0, 16); + break; + case 6: + INST_NAME("DIV Eb"); + SETFLAGS(X_ALL, SF_SET); + GETEB(x1, 0); + CALL(div8, -1); + break; + case 7: + INST_NAME("IDIV Eb"); + SETFLAGS(X_ALL, SF_SET); + GETEB(x1, 0); + CALL(idiv8, -1); + break; + } + break; case 0xF7: nextop = F8; switch((nextop>>3)&7) { diff --git a/src/dynarec/dynarec_arm64_emit_math.c b/src/dynarec/dynarec_arm64_emit_math.c index 932af359..91fb0a14 100755 --- a/src/dynarec/dynarec_arm64_emit_math.c +++ b/src/dynarec/dynarec_arm64_emit_math.c @@ -1826,49 +1826,47 @@ void emit_neg16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) } // emit NEG8 instruction, from s1, store result in s1 using s3 and s4 as scratch -//void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) -//{ -// IFX(X_PEND) { -// STR_IMM9(s1, xEmu, offsetof(x64emu_t, op1)); -// SET_DF(s3, d_neg8); -// } else IFX(X_ALL) { -// SET_DFNONE(s3); -// } -// IFX(X_ZF|X_CF) { -// BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0); -// } -// IFX(X_CF) { -// TSTS_REG_LSL_IMM5(s1, s1, 0); -// ORR_IMM8_COND(cNE, xFlags, xFlags, 1<<F_CF, 0); -// } -// IFX(X_AF|X_OF) { -// MOV_REG_LSL_IMM5(s3, s1, 0); -// } -// RSB_IMM8(s1, s1, 0); -// IFX(X_PEND) { -// STR_IMM9(s1, xEmu, offsetof(x64emu_t, res)); -// } -// IFX(X_AF|X_OF) { -// ORR_REG_LSL_IMM5(s3, s3, s1, 0); // bc = op1 | res -// IFX(X_AF) { -// MOV_REG_LSR_IMM5(s4, s3, 3); -// BFI(xFlags, s4, F_AF, 1); // AF: bc & 0x08 -// } -// IFX(X_OF) { -// MOV_REG_LSR_IMM5(s4, s3, 6); -// XOR_REG_LSR_IMM8(s4, s4, s4, 1); -// BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 -// } -// } -// IFX(X_ZF) { -// ANDS_IMM8(s1, s1, 0xff); -// ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0); -// } -// IFX(X_SF) { -// MOV_REG_LSR_IMM5(s3, s1, 7); -// BFI(xFlags, s3, F_SF, 1); -// } -// IFX(X_PF) { -// emit_pf(dyn, ninst, s1, s3, s4); -// } -//} \ No newline at end of file +void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) +{ + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, op1)); + SET_DF(s3, d_neg8); + } else IFX(X_ALL) { + SET_DFNONE(s3); + } + IFX(X_CF) { + TSTw_REG(s1, s1); + CSETw(s4, cNE); + BFIw(xFlags, s4, F_CF, 1); + } + IFX(X_AF|X_OF) { + MOVw_REG(s3, s1); + } + NEGSw_REG(s1, s1); + IFX(X_PEND) { + STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_AF|X_OF) { + ORRw_REG(s3, s3, s1); // bc = op1 | res + IFX(X_AF) { + LSRw(s4, s3, 3); + BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08 + } + IFX(X_OF) { + LSRw(s4, s3, 6); + EORx_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 + } + } + IFX(X_ZF) { + CSETw(s4, cEQ); + BFIw(xFlags, s4, F_ZF, 1); + } + IFX(X_SF) { + LSRw(s3, s1, 7); + BFIw(xFlags, s3, F_SF, 1); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} \ No newline at end of file diff --git a/src/dynarec/dynarec_arm64_emit_tests.c b/src/dynarec/dynarec_arm64_emit_tests.c index 14b9eac1..aead03b8 100755 --- a/src/dynarec/dynarec_arm64_emit_tests.c +++ b/src/dynarec/dynarec_arm64_emit_tests.c @@ -352,38 +352,33 @@ void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, } // emit TEST8 instruction, from test s1 , s2, using s3 and s4 as scratch -//void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) -//{ -// IFX(X_PEND) { -// SET_DF(s3, d_tst8); -// } else { -// SET_DFNONE(s4); -// } -// IFX(X_OF) { -// BFC(xFlags, F_OF, 1); -// } -// IFX(X_ZF|X_CF) { -// BIC_IMM8(xFlags, xFlags, (1<<F_ZF)|(1<<F_CF), 0); -// } -// ANDS_REG_LSL_IMM5(s3, s1, s2, 0); // res = s1 & s2 -// IFX(X_PEND) { -// STR_IMM9(s3, xEmu, offsetof(x64emu_t, res)); -// } -// IFX(X_ZF) { -// ORR_IMM8_COND(cEQ, xFlags, xFlags, 1<<F_ZF, 0); -// } -// IFX(X_SF) { -// MOV_REG_LSR_IMM5(s4, s3, 7); -// BFI(xFlags, s4, F_SF, 1); -// } -// // PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) -// IFX(X_PF) { -// AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied -// MOV32(s4, GetParityTab()); -// LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer -// AND_REG_LSL_IMM5(s3, s1, s2, 0); -// AND_IMM8(s3, s3, 31); -// MVN_REG_LSR_REG(s4, s4, s3); -// BFI(xFlags, s4, F_PF, 1); -// } -//} +void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) +{ + IFX(X_PEND) { + SET_DF(s3, d_tst8); + } else { + SET_DFNONE(s4); + } + IFX(X_OF) { + BFCw(xFlags, F_OF, 1); + } + IFX(X_CF) { + BFCw(xFlags, F_CF, 1); + } + ANDSw_REG(s5, s1, s2); // res = s1 & s2 + IFX(X_PEND) { + STRB_U12(s5, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + CSETw(s4, cEQ); + BFIw(xFlags, s4, F_ZF, 1); + } + IFX(X_SF) { + LSRw(s4, s5, 7); + BFIw(xFlags, s4, F_SF, 1); + } + // PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) + IFX(X_PF) { + emit_pf(dyn, ninst, s5, s3, s4); + } +} diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index fed7c411..0a11e94c 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -637,7 +637,7 @@ void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); //void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4); -//void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4); +void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_test32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_add32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); @@ -690,7 +690,7 @@ void emit_sbb8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 //void emit_sbb16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); void emit_neg32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4); void emit_neg16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); -//void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); +void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int32_t c, int s3, int s4); void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); |