summaryrefslogtreecommitdiff
path: root/sux.h
diff options
context:
space:
mode:
Diffstat (limited to 'sux.h')
-rw-r--r--sux.h22
1 files changed, 16 insertions, 6 deletions
diff --git a/sux.h b/sux.h
index 9004c74..744a2cc 100644
--- a/sux.h
+++ b/sux.h
@@ -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;
}