diff options
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 22 |
1 files changed, 16 insertions, 6 deletions
@@ -351,20 +351,30 @@ static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ } static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { - uint64_t sum = reg << value; - sum |= getflag(C); + uint64_t sum; + uint64_t c = getflag(C); + switch (value & 0x3F) { + case 0 : return reg; + case 1 : sum = (reg << 1) | (c & 1); break; + default: sum = (reg << value) | (c << (value-1)) | (reg >> (65-value)); break; + } setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(reg >> (uint64_t)(64-value), C); + setflag((reg >> (64-value)) & 1, C); return sum; } static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { - uint64_t sum = reg >> value; - sum |= (uint64_t)getflag(C) << (uint64_t)(64-value); + uint64_t sum; + uint64_t c = getflag(C); + switch (value & 0x3F) { + case 0 : return reg; + case 1 : sum = (reg >> 1) | (c << 63); break; + default: sum = (reg >> value) | (c << (64-value)) | (reg << (65-value)); break; + } setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(reg & 1, C); + setflag((reg >> (value-1)) & 1, C); return sum; } |