From 79f3afc2eb57420de1e8830e10dbac55c8e10a32 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Tue, 14 Mar 2023 15:22:22 +0800 Subject: [RV64_DYNAREC] Added 31 XOR opcode (#560) * [RV64_DYNAREC] Move things around * [RV64_DYNAREC] Added 31 XOR opcode --- src/dynarec/rv64/dynarec_rv64_00.c | 42 ++++++++++++++--------- src/dynarec/rv64/dynarec_rv64_emit_logic.c | 53 ++++++++++++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_helper.h | 2 +- src/dynarec/rv64/rv64_emitter.h | 9 ++++- 4 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 src/dynarec/rv64/dynarec_rv64_emit_logic.c (limited to 'src') diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 39fa3a7d..1cf10f31 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -62,6 +62,16 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni WBACK; break; + case 0x31: + INST_NAME("XOR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED(0); + emit_xor32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x50: case 0x51: case 0x52: @@ -76,6 +86,22 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SUBI(xRSP, xRSP, 8); break; + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + INST_NAME("POP reg"); + gd = xRAX+(opcode&0x07)+(rex.b<<3); + LD(gd, xRSP, 0); + if(gd!=xRSP) { + ADDI(xRSP, xRSP, 8); + } + break; + case 0x81: case 0x83: nextop = F8; @@ -136,22 +162,6 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - INST_NAME("POP reg"); - gd = xRAX+(opcode&0x07)+(rex.b<<3); - LD(gd, xRSP, 0); - if(gd!=xRSP) { - ADDI(xRSP, xRSP, 8); - } - break; - default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c new file mode 100644 index 00000000..e9086276 --- /dev/null +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" +#include "../tools/bridge_private.h" + +#include "rv64_printer.h" +#include "dynarec_rv64_private.h" +#include "dynarec_rv64_functions.h" +#include "dynarec_rv64_helper.h" + +// emit XOR32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch +void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4) +{ + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(s4, rex.w?d_xor64:d_xor32); + } else IFX(X_ALL) { + SET_DFNONE(s4); + } + + XORxw(s1, s1, s2); + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + + IFX(X_ZF) { + BNEZ(s1, 4); + ORI(xFlags, xFlags, F_ZF); + } + IFX(X_SF) { + SRLI(s3, s1, rex.w?63:31); + BEQZ(s3, 4); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 53702fab..5d9f2140 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -347,7 +347,7 @@ void emit_sub32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i //void emit_sub8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5); //void emit_or32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); //void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); -//void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); +void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); //void emit_xor32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); //void emit_and32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); //void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 5b77f607..10cf325b 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -155,7 +155,7 @@ f28–31 ft8–11 FP temporaries Caller // rd = rs1 - rs2 #define SUB(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, 0b0110011)) // rd = rs1 - rs2 -#define SUBxw(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011)) +#define SUBxw(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011)) // rd = rs1<>rs2 logical #define SRL(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, 0b0110011)) // rd = rs1>>rs2 aritmetic @@ -236,6 +238,11 @@ f28–31 ft8–11 FP temporaries Caller // Shift Right Aritmetic Immediate #define SRAI(rd, rs1, imm6) EMIT(I_type((imm6)|(0b010000<<6), rs1, 0b101, rd, 0b0010011)) +// rd = rs1 + imm12 +#define ADDIW(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, 0b0011011)) + +#define SEXT_W(rd, rs1) ADDIW(rd, rs1, 0) + // rd = rs1<>rs2 logical -- cgit 1.4.1