diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-04-10 00:33:41 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-09 18:33:41 +0200 |
| commit | db35542706827c411db79a2db97f6d6ce58f6e5e (patch) | |
| tree | 625431261702d644a25077cb3e5a61d5f47de0c1 /src | |
| parent | eda857cb10701ccb3f726118b8865b600484b708 (diff) | |
| download | box64-db35542706827c411db79a2db97f6d6ce58f6e5e.tar.gz box64-db35542706827c411db79a2db97f6d6ce58f6e5e.zip | |
[LA64_DYNAREC] Refined MOV64 macros (#1430)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 28 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 5 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 43 |
3 files changed, 48 insertions, 28 deletions
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 6c5b76b5..5bba9433 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -1067,3 +1067,31 @@ void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2 if(cacheupd&1) flagsCacheTransform(dyn, ninst, s1); } + +void la64_move32(dynarec_la64_t* dyn, int ninst, int reg, int32_t val, int zeroup) +{ + if ((val & 0xfff) == val) { + ORI(reg, xZR, val); + } else if (((val << 20) >> 20) == val) { + ADDI_W(reg, xZR, val & 0xfff); + } else if ((val & 0xfff) == 0) { + LU12I_W(reg, (val >> 12) & 0xfffff); + } else { + LU12I_W(reg, (val >> 12) & 0xfffff); + ORI(reg, reg, val & 0xfff); + } + if (zeroup && val < 0) ZEROUP(reg); +} + +void la64_move64(dynarec_la64_t* dyn, int ninst, int reg, int64_t val) +{ + la64_move32(dyn, ninst, reg, val, 0); + if (((val << 32) >> 32) == val) { + return; + } + LU32I_D(reg, (val >> 32) & 0xfffff); + if (((val << 12) >> 12) == val) { + return; + } + LU52I_D(reg, reg, (val >> 52) & 0xfff); +} \ No newline at end of file diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 49229c09..8f306681 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -688,6 +688,8 @@ void* la64_next(x64emu_t* emu, uintptr_t addr); #define fpu_unreflectcache STEPNAME(fpu_unreflectcache) #define CacheTransform STEPNAME(CacheTransform) +#define la64_move64 STEPNAME(la64_move64) +#define la64_move32 STEPNAME(la64_move32) /* setup r2 to address pointed by */ uintptr_t geted(dynarec_la64_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); @@ -769,6 +771,9 @@ int sse_get_reg_empty(dynarec_la64_t* dyn, int ninst, int s1, int a); void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2, int s3); +void la64_move64(dynarec_la64_t* dyn, int ninst, int reg, int64_t val); +void la64_move32(dynarec_la64_t* dyn, int ninst, int reg, int32_t val, int zeroup); + #if STEP < 2 #define CHECK_CACHE() 0 #else diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index be91b960..a948548b 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1726,34 +1726,21 @@ LSX instruction starts with V, LASX instruction starts with XV. } \ } while (0) -#define MOV32w(rd, imm32) MOV32w_(rd, imm32, 1) -// GR[rd] = imm64 -#define MOV64x(rd, imm64) \ - do { \ - MOV32w_(rd, imm64, 0); \ - if (((uint64_t)(imm64)) > 0xffffffffu) { \ - LU32I_D(rd, ((uint64_t)(imm64)) >> 32); \ - LU52I_D(rd, rd, ((uint64_t)(imm64)) >> 52); \ - } \ - } while (0) - -#define MOV64xw(A, B) \ - do { \ - if (rex.w) { \ - MOV64x(A, B); \ - } else { \ - MOV32w(A, B); \ - } \ - } while (0) - -#define MOV64z(A, B) \ - do { \ - if (rex.is32bits) { \ - MOV32w(A, B); \ - } else { \ - MOV64x(A, B); \ - } \ - } while (0) +// MOV64x/MOV32w is quite complex, so use a function for this +#define MOV64x(A, B) la64_move64(dyn, ninst, A, B) +#define MOV32w(A, B) la64_move32(dyn, ninst, A, B, 1) +#define MOV64xw(A, B) \ + if (rex.w) { \ + MOV64x(A, B); \ + } else { \ + MOV32w(A, B); \ + } +#define MOV64z(A, B) \ + if (rex.is32bits) { \ + MOV32w(A, B); \ + } else { \ + MOV64x(A, B); \ + } // rd[63:0] = rj[63:0] (pseudo instruction) #define MV(rd, rj) ADDI_D(rd, rj, 0) |