summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2022-01-24 16:29:54 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2022-01-24 16:29:54 -0400
commit553e97d1e5159f2e1dea56dfff0901a029c74f62 (patch)
tree792bb124159d19ada39d9c40e686ca7cad8c27cb
parente6f8bc2b1f48422b8997ee8153f4051d33b04331 (diff)
sux.h: Add bitmasks for arithmetic operations.
-rw-r--r--sux.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/sux.h b/sux.h
index 19e1c16..a56d094 100644
--- a/sux.h
+++ b/sux.h
@@ -1778,6 +1778,14 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p
}
}
+#define shift(reg, value, sign, shift) (((reg) shift (value)) | ((sign)))
+#define rotate(sum, reg, value, shift1, shift2, c1, c2) \
+ switch (value & 0x3F) { \
+ case 0: sum = (reg); break; \
+ case 1: sum = shift(reg, value, c1, shift1); break; \
+ default: sum = shift(reg, value, c2, shift1) | shift(reg, (msb+1)-value, 0, shift2); break; \
+ }
+
#if 0
#define t(w8, w7, w6, w5, w4, w3, w2, w1, w0, code) \
do { \
@@ -1792,7 +1800,10 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p
#define inst(op, ext) \
static /*inline*/ void inst_##op(struct sux *cpu, uint8_t prefix, uint8_t size, int inc_pc, int inc_clk, uint8_t thread) { \
const unsigned int o8 = 0x##op / 32, o8m = 1 << (0x##op % 32); \
+ const uint8_t msb = size*8; \
uint8_t rs = ((1 << ((prefix >> 4) & 3)) - 1); \
+ uint8_t carry = 0; \
+ uint64_t sign = 0; \
uint64_t addr = 0, idx = 0, tmp = 0, tmp2 = 0; \
uint64_t dummy = 0, *reg = &dummy; \
uint64_t dummy2 = 0, *reg2 = &dummy; \
@@ -1851,6 +1862,20 @@ static /*inline*/ void inst_##op(struct sux *cpu, uint8_t prefix, uint8_t size,
/* Set program counter to supplied address */ \
t(7, 0x00011000, 0x10010000, 0x00010000, 0x00010001, 0x00000201, 0x00010001, 0x00010001, 0x00010000) { if (tmp) { cpu->pc = addr; } } /* If flag is 1. */ \
t(0, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000) { if (!tmp) { cpu->pc = addr; } } /* If flag is 0. */ \
+ /* Arithmetic operations. */ \
+ t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00000000) { sign = -(uint64_t)(*reg >> (msb-1)) << (msb-1)-tmp2; } /* asr. */ \
+ t(0, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00220022, 0x00660066) { carry = getflag(C); } /* adc, sbc, and rotate. */ \
+ t(0, 0x06000000, 0x00000000, 0x04000400, 0x00441044, 0x10000000, 0x00100110, 0x00100110, 0x00100110) { carry = 1; } /* cmp, cpb, cpx, and cpy. */ \
+ t(0, 0x06220022, 0x00220022, 0x04220422, 0x00441044, 0x10440044, 0x00540154, 0x00760176, 0x00760176) { tmp2 = tmp; } /* Copy source operand. */ \
+ t(0, 0x06000000, 0x00000000, 0x04000400, 0x00441044, 0x10000000, 0x00100110, 0x00320132, 0x00320132) { tmp += *reg + carry; carry = tmp < tmp2; } /* adc, sbc, and cmp. */ \
+ t(0, 0x00000000, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { tmp = (tmp2 < msb) ? shift(*reg, tmp2, 0, <<) : 0; } /* lsl. */ \
+ t(0, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00000000) { tmp = (tmp2 < msb) ? shift(*reg, tmp2, sign, >>) : 0; } /* lsr, asr. */ \
+ t(0, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { rotate(tmp, *reg, tmp2, <<, >>, carry & 1, carry << (tmp2-1)); } /* rol. */ \
+ t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044) { rotate(tmp, *reg, tmp2, >>, <<, carry << (msb-1), carry << (msb-tmp2)); } /* ror. */ \
+ t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000) { tmp *= *reg; } /* mul. */ \
+ t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000) { tmp /= *reg; *reg2 %= tmp2; } /* div. */ \
+ t(0, 0x00220022, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { carry = (*reg >> (msb-(tmp2+!tmp2))) & 1; } /* rol, lsl. */ \
+ t(0, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00440044) { carry = (*reg >> tmp2-(tmp2 != 0)) & 1; } /* ror, lsr, asr. */ \
}
#undef ORTHO_1CC