diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-02-07 12:13:13 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-02-07 12:13:21 +0100 |
| commit | 46ad2261e760b3bb96c41205ab22dbfa8c54e963 (patch) | |
| tree | ab609bfa6de42626fbfa11b99a1189aa80e56a7a /src/libtools | |
| parent | 6c60ad4695c167ac0a9f75b4b139eb46f5abaab9 (diff) | |
| download | box64-46ad2261e760b3bb96c41205ab22dbfa8c54e963.tar.gz box64-46ad2261e760b3bb96c41205ab22dbfa8c54e963.zip | |
[ARM64_DYNAREC] Optimized REP MOVSB
Diffstat (limited to 'src/libtools')
| -rw-r--r-- | src/libtools/signals.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 10dbdb74..e87b1c34 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -991,6 +991,47 @@ int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd, p->uc_mcontext.pc+=4; // go to next opcode return 1; } + if((opcode&0b10111111111000000000110000000000) == 0b10111000010000000000010000000000) { + // this is a LDR postoffset + int size = 1<<((opcode>>30)&3); + int val = opcode&31; + int dest = (opcode>>5)&31; + int64_t offset = (opcode>>12)&0b111111111; + if((offset>>(9-1))&1) + offset |= (0xffffffffffffffffll<<9); + volatile uint8_t* addr = (void*)(p->uc_mcontext.regs[dest]); + uint64_t value = 0; + if(size==8 && (((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + value |= ((uint64_t)((volatile uint32_t*)addr)[i]) << (i*32); + } else + for(int i=0; i<size; ++i) + value |= ((uint64_t)addr[i]) << (i*8); + p->uc_mcontext.regs[val] = value; + p->uc_mcontext.regs[dest] += offset; + p->uc_mcontext.pc+=4; // go to next opcode + return 1; + } + if((opcode&0b10111111111000000000110000000000) == 0b10111000000000000000010000000000) { + // this is a STR postoffset + int size = 1<<((opcode>>30)&3); + int val = opcode&31; + int src = (opcode>>5)&31; + int64_t offset = (opcode>>12)&0b111111111; + if((offset>>(9-1))&1) + offset |= (0xffffffffffffffffll<<9); + volatile uint8_t* addr = (void*)(p->uc_mcontext.regs[src]); + uint64_t value = p->uc_mcontext.regs[val]; + if(size==8 && (((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + ((volatile uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff; + } else + for(int i=0; i<size; ++i) + addr[i] = (value>>(i*8))&0xff; + p->uc_mcontext.regs[src] += offset; + p->uc_mcontext.pc+=4; // go to next opcode + return 1; + } #elif RV64 #define GET_FIELD(v, high, low) (((v) >> low) & ((1ULL << (high - low + 1)) - 1)) #define SIGN_EXT(val, val_sz) (((int32_t)(val) << (32 - (val_sz))) >> (32 - (val_sz))) |