diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-05-03 14:39:42 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-05-03 14:39:42 +0000 |
| commit | 3245ff59d3927242de7e7241548565ae863200cf (patch) | |
| tree | 9cffb8f8fd4eb778b8ce5fb42ad6e2870f8e681e /src | |
| parent | 3a4d58f114a2f030f0937abae4c0ef7ec882641a (diff) | |
| download | box64-3245ff59d3927242de7e7241548565ae863200cf.tar.gz box64-3245ff59d3927242de7e7241548565ae863200cf.zip | |
[RV64_DYNAREC] Added several 67 prfixed opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_67.c | 491 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 131 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 32 |
3 files changed, 653 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c new file mode 100644 index 00000000..5ac5cbb9 --- /dev/null +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -0,0 +1,491 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> +#include <assert.h> + +#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 "rv64_printer.h" +#include "dynarec_rv64_private.h" +#include "dynarec_rv64_helper.h" +#include "dynarec_rv64_functions.h" + +uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + (void)ip; (void)need_epilog; + + uint8_t opcode = F8; + uint8_t nextop; + uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2; + int64_t fixedaddress; + int unscaled; + int8_t i8; + uint8_t u8; + int32_t i32; + int64_t j64, i64; + int cacheupd = 0; + int lock; + int v0, v1, s0; + MAYUSE(i32); + MAYUSE(j64); + MAYUSE(v0); + MAYUSE(v1); + MAYUSE(s0); + MAYUSE(lock); + MAYUSE(cacheupd); + + // REX prefix before the 67 are ignored + rex.rex = 0; + while(opcode>=0x40 && opcode<=0x4f) { + rex.rex = opcode; + opcode = F8; + } + rep = 0; + while((opcode==0xF2) || (opcode==0xF3)) { + rep = opcode-0xF1; + opcode = F8; + } + + switch(opcode) { + + case 0x01: + INST_NAME("ADD Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_add32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; + case 0x02: + INST_NAME("ADD Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_add8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x4); + break; + case 0x03: + INST_NAME("ADD Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_add32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + + case 0x05: + INST_NAME("ADD EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_add32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5, x6); + break; + + case 0x09: + INST_NAME("OR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_or32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x0A: + INST_NAME("OR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_or8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x4); + break; + case 0x0B: + INST_NAME("OR Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_or32(dyn, ninst, rex, gd, ed, x3, x4); + break; + + case 0x0D: + INST_NAME("OR EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_or32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + + case 0x0F: + opcode=F8; + switch(opcode) { + + default: + DEFAULT; + } + break; + + case 0x11: + INST_NAME("ADC Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; + + case 0x13: + INST_NAME("ADC Gd, Ed"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_adc32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + + case 0x15: + INST_NAME("ADC EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x1, i64); + emit_adc32(dyn, ninst, rex, xRAX, x1, x3, x4, x5); + break; + + case 0x19: + INST_NAME("SBB Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; + case 0x1A: + INST_NAME("SBB Gb, Eb"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_sbb8(dyn, ninst, x1, x2, x3, x4, x5); + GBBACK(x4); + break; + case 0x1B: + INST_NAME("SBB Gd, Ed"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sbb32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + + case 0x1D: + INST_NAME("SBB EAX, Id"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + MOV64xw(x2, i64); + emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); + break; + + case 0x21: + INST_NAME("AND Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_and32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x22: + INST_NAME("AND Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_and8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x4); + break; + case 0x23: + INST_NAME("AND Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_and32(dyn, ninst, rex, gd, ed, x3, x4); + break; + + case 0x25: + INST_NAME("AND EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_and32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + + case 0x29: + INST_NAME("SUB Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sub32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; + case 0x2A: + INST_NAME("SUB Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_sub8(dyn, ninst, x1, x2, x3, x4, x5); + GBBACK(x5); + break; + case 0x2B: + INST_NAME("SUB Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_sub32(dyn, ninst, rex, gd, ed, x3, x4, x5); + break; + + case 0x2D: + INST_NAME("SUB EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_sub32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5, x6); + break; + + case 0x31: + INST_NAME("XOR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_xor32(dyn, ninst, rex, ed, gd, x3, x4); + WBACK; + break; + case 0x32: + INST_NAME("XOR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_xor8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x4); + break; + case 0x33: + INST_NAME("XOR Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_xor32(dyn, ninst, rex, gd, ed, x3, x4); + break; + + case 0x35: + INST_NAME("XOR EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_xor32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + + case 0x38: + INST_NAME("CMP Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x1, 0); + GETGB(x2); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + case 0x39: + INST_NAME("CMP Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_cmp32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6); + break; + case 0x3A: + INST_NAME("CMP Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB32(x2, 0); + GETGB(x1); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + case 0x3B: + INST_NAME("CMP Gd, Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED32(0); + emit_cmp32(dyn, ninst, rex, gd, ed, x3, x4, x5, x6); + break; + case 0x3C: + INST_NAME("CMP AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + ANDI(x1, xRAX, 0xff); + if(u8) { + MOV32w(x2, u8); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + } else { + emit_cmp8_0(dyn, ninst, x1, x3, x4); + } + break; + case 0x3D: + INST_NAME("CMP EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + if(i64) { + MOV64xw(x2, i64); + emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); + } else + emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); + break; + + case 0x81: + case 0x83: + nextop = F8; + switch((nextop>>3)&7) { + case 0: //ADD + if(opcode==0x81) {INST_NAME("ADD Ed, Id");} else {INST_NAME("ADD Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6); + WBACK; + break; + case 1: //OR + if(opcode==0x81) {INST_NAME("OR Ed, Id");} else {INST_NAME("OR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_or32c(dyn, ninst, rex, ed, i64, x3, x4); + WBACK; + break; + case 2: //ADC + if(opcode==0x81) {INST_NAME("ADC Ed, Id");} else {INST_NAME("ADC Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + MOV64xw(x5, i64); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x5); + WBACK; + break; + case 3: //SBB + if(opcode==0x81) {INST_NAME("SBB Ed, Id");} else {INST_NAME("SBB Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + MOV64xw(x5, i64); + emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, x5); + WBACK; + break; + case 4: //AND + if(opcode==0x81) {INST_NAME("AND Ed, Id");} else {INST_NAME("AND Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_and32c(dyn, ninst, rex, ed, i64, x3, x4); + WBACK; + break; + case 5: //SUB + if(opcode==0x81) {INST_NAME("SUB Ed, Id");} else {INST_NAME("SUB Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_sub32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6); + WBACK; + break; + case 6: //XOR + if(opcode==0x81) {INST_NAME("XOR Ed, Id");} else {INST_NAME("XOR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + emit_xor32c(dyn, ninst, rex, ed, i64, x3, x4); + WBACK; + break; + case 7: //CMP + if(opcode==0x81) {INST_NAME("CMP Ed, Id");} else {INST_NAME("CMP Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32((opcode==0x81)?4:1); + if(opcode==0x81) i64 = F32S; else i64 = F8S; + if(i64) { + MOV64xw(x2, i64); + emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6); + } else + emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); + break; + } + break; + + case 0x88: + INST_NAME("MOV Eb, Gb"); + nextop = F8; + gd = ((nextop&0x38)>>3)+(rex.r<<3); + if(rex.rex) { + gb2 = 0; + gb1 = xRAX + gd; + } else { + gb2 = ((gd&4)>>2); + gb1 = xRAX+(gd&3); + } + gd = x4; + if(gb2) { + SRLI(x4, gb1, 8); + gb1 = x4; + } + if(MODREG) { + ed = (nextop&7) + (rex.b<<3); + if(rex.rex) { + eb1 = xRAX+ed; + eb2 = 0; + } else { + eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx + eb2 = ((ed&4)>>2); // L or H + } + ANDI(gd, gb1, 0xff); + if(eb2) { + MOV64x(x1, 0xffffffffffff00ffLL); + ANDI(x1, eb1, x1); + SLLI(gd, gd, 8); + OR(eb1, x1, gd); + } else { + ANDI(x1, eb1, ~0xff); + OR(eb1, x1, gd); + } + } else { + addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); + SB(gb1, ed, fixedaddress); + SMWRITELOCK(lock); + } + break; + + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index eca4ceff..ec47b91d 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -208,6 +208,137 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, return addr; } +/* setup r2 to address pointed by ED, also fixaddress is an optionnal delta in the range [-absmax, +absmax], with delta&mask==0 to be added to ed for LDR/STR */ +uintptr_t geted32(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int *l, int i12, int delta) +{ + MAYUSE(dyn); MAYUSE(ninst); MAYUSE(delta); + + int lock = l?((l==LOCK_LOCK)?1:2):0; + if(lock==2) + *l = 0; + uint8_t ret = x2; + *fixaddress = 0; + if(hint>0) ret = hint; + int maxval = 2047; + if(i12>1) + maxval -= i12; + MAYUSE(scratch); + if(!(nextop&0xC0)) { + if((nextop&7)==4) { + uint8_t sib = F8; + int sib_reg = ((sib>>3)&7)+(rex.x<<3); + if((sib&0x7)==5) { + int64_t tmp = F32S; + if (sib_reg!=4) { + if(tmp && (!((tmp>=-2048) && (tmp<=2047) && i12))) { + MOV64x(scratch, tmp); + if((sib>>6)) { + if(rv64_zba) SHxADD(ret, xRAX+sib_reg, (sib>>6), scratch); else {SLLI(ret, xRAX+sib_reg, sib>>6); ADD(ret, ret, scratch);} + } else + ADD(ret, xRAX+sib_reg, scratch); + } else { + if(sib>>6) + SLLI(ret, xRAX+sib_reg, (sib>>6)); + else + ret = xRAX+sib_reg; + *fixaddress = tmp; + } + } else { + switch(lock) { + case 1: addLockAddress(tmp); break; + case 2: if(isLockAddress(tmp)) *l=1; break; + } + MOV64x(ret, tmp); + } + } else { + if (sib_reg!=4) { + if((sib>>6)) { + if(rv64_zba) SHxADD(ret, xRAX+sib_reg, (sib>>6), xRAX+(sib&0x7)+(rex.b<<3)); else {SLLI(ret, xRAX+sib_reg, (sib>>6)); ADD(ret, ret, xRAX+(sib&0x7)+(rex.b<<3));} + } else + ADD(ret, xRAX+(sib&0x7)+(rex.b<<3), xRAX+(sib&0x7)+(rex.b<<3)); + } else { + ret = xRAX+(sib&0x7)+(rex.b<<3); + } + } + } else if((nextop&7)==5) { + uint32_t tmp = F32; + MOV32w(ret, tmp); + GETIP(addr+delta); + ADD(ret, ret, xRIP); + switch(lock) { + case 1: addLockAddress(addr+delta+tmp); break; + case 2: if(isLockAddress(addr+delta+tmp)) *l=1; break; + } + } else { + ret = xRAX+(nextop&7)+(rex.b<<3); + if(ret==hint) { + AND(hint, ret, xMASK); //to clear upper part + } + } + } else { + int64_t i64; + uint8_t sib = 0; + int sib_reg = 0; + if((nextop&7)==4) { + sib = F8; + sib_reg = ((sib>>3)&7)+(rex.x<<3); + } + if(nextop&0x80) + i64 = F32S; + else + i64 = F8S; + if(i64==0 || !((i64>=-2048) && (i64<=2047) && i12)) { + *fixaddress = i64; + if((nextop&7)==4) { + if (sib_reg!=4) { + if(sib>>6) { + if(rv64_zba) SHxADD(ret, xRAX+sib_reg, (sib>>6), xRAX+(sib&0x07)+(rex.b<<3)); else {SLLI(ret, xRAX+sib_reg, (sib>>6)); ADD(ret, ret, xRAX+(sib&0x07)+(rex.b<<3));} + } else + ADD(ret, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg); + } else { + ret = xRAX+(sib&0x07)+(rex.b<<3); + } + } else { + ret = xRAX+(nextop&0x07)+(rex.b<<3); + } + } else { + if(i64>=-2048 && i64<=2047 && i12) { + if((nextop&7)==4) { + if (sib_reg!=4) { + if(sib>>6) { + if(rv64_zba) SHxADD(scratch, xRAX+sib_reg, (sib>>6), xRAX+(sib&0x07)+(rex.b<<3)); else {SLLI(scratch, xRAX+sib_reg, sib>>6); ADD(scratch, scratch, xRAX+(sib&0x07)+(rex.b<<3));} + } else + ADD(scratch, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg); + } else { + scratch = xRAX+(sib&0x07)+(rex.b<<3); + } + } else + scratch = xRAX+(nextop&0x07)+(rex.b<<3); + ADDI(ret, scratch, i64); + } else { + MOV32w(scratch, i64); + if((nextop&7)==4) { + if (sib_reg!=4) { + ADD(scratch, scratch, xRAX+(sib&0x07)+(rex.b<<3)); + if(sib>>6) { + if(rv64_zba) SHxADD(ret, xRAX+sib_reg, (sib>>6), scratch); else {SLLI(ret, xRAX+sib_reg, (sib>>6)); ADD(ret, ret, scratch);} + } else + ADD(ret, scratch, xRAX+sib_reg); + } else { + PASS3(int tmp = xRAX+(sib&0x07)+(rex.b<<3)); + ADD(ret, tmp, scratch); + } + } else { + PASS3(int tmp = xRAX+(nextop&0x07)+(rex.b<<3)); + ADD(ret, tmp, scratch); + } + } + } + } + *ed = ret; + return addr; +} + void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst) { MAYUSE(dyn); MAYUSE(ip); MAYUSE(ninst); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index b59dbfe7..7d6109aa 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -99,6 +99,16 @@ LD(x1, wback, fixedaddress); \ ed = x1; \ } +// GETED32 can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI +#define GETED32(D) if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + wback = 0; \ + } else { \ + SMREAD() \ + addr = geted32(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \ + LDxw(x1, wback, fixedaddress); \ + ed = x1; \ + } //GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI #define GETEDH(hint, D) if(MODREG) { \ ed = xRAX+(nextop&7)+(rex.b<<3); \ @@ -224,6 +234,26 @@ wb1 = 1; \ ed = i; \ } +// GETEB32 will use i for ed, and can use r3 for wback. +#define GETEB32(i, D) if(MODREG) { \ + if(rex.rex) { \ + wback = xRAX+(nextop&7)+(rex.b<<3); \ + wb2 = 0; \ + } else { \ + wback = (nextop&7); \ + wb2 = (wback>>2)*8; \ + wback = xRAX+(wback&3); \ + } \ + if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \ + wb1 = 0; \ + ed = i; \ + } else { \ + SMREAD(); \ + addr = geted32(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \ + LBU(i, wback, fixedaddress);\ + wb1 = 1; \ + ed = i; \ + } //GETGB will use i for gd #define GETGB(i) if(rex.rex) { \ @@ -899,7 +929,7 @@ void* rv64_next(x64emu_t* emu, uintptr_t addr); uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta); /* setup r2 to address pointed by */ -//uintptr_t geted32(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int64_t* fixaddress, int absmax, uint32_t mask, rex_t rex, int* l, int s, int delta); +uintptr_t geted32(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta); /* setup r2 to address pointed by */ //uintptr_t geted16(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int64_t* fixaddress, int absmax, uint32_t mask, int s); |