diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 11 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 13 |
2 files changed, 17 insertions, 7 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index daf89b2a..e72cb10d 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -2463,9 +2463,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ed = x1; wback = x3; } - if (rv64_zbs) - BEXT_(x4, ed, gd); - else { + if (rv64_zbs) { + if (rex.w) { + BEXT_(x4, ed, gd); + } else { + ANDI(x2, gd, 0xf); + BEXT_(x4, ed, x2); + } + } else { ANDI(x2, gd, rex.w ? 0x3f : 0xf); SRL(x4, ed, x2); ANDI(x4, x4, 1); diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index c873daad..ceb1917b 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -965,11 +965,16 @@ f28–31 ft8–11 FP temporaries Caller // Single-bit Set (Immediate) #define BSETI(rd, rs1, imm) EMIT(R_type(0b0010100, imm, rs1, 0b001, rd, 0b0010011)) -// Single-bit Extract (Register), s0 can be the same as rs2 +// Single-bit Extract (Register) #define BEXT(rd, rs1, rs2, s0) \ - if (rv64_zbs) \ - BEXT_(rd, rs1, rs2); \ - else { \ + if (rv64_zbs) { \ + if (rex.w) { \ + BEXT_(rd, rs1, rs2); \ + } else { \ + ANDI(s0, rs2, 0x1f); \ + BEXT_(rd, rs1, s0); \ + } \ + } else { \ ANDI(s0, rs2, rex.w ? 0x3f : 0x1f); \ SRL(rd, rs1, s0); \ ANDI(rd, rd, 1); \ |