summaryrefslogtreecommitdiff
path: root/sux.h
diff options
context:
space:
mode:
Diffstat (limited to 'sux.h')
-rw-r--r--sux.h43
1 files changed, 40 insertions, 3 deletions
diff --git a/sux.h b/sux.h
index c028b84..44794f8 100644
--- a/sux.h
+++ b/sux.h
@@ -119,6 +119,38 @@ static /*inline*/ uint8_t get_ortho_addrsize(uint8_t prefix, uint8_t addrmode) {
return get_addrsize(prefix, type);
}
+static int is_1op(uint8_t opcode) {
+ switch (opcode) {
+ case ORTHO_1OP(JMP):
+ case ORTHO_1OP(JSR):
+ case ORTHO_1OP(PSH):
+ case ORTHO_1OP(PEA):
+ case ORTHO_1OP(PUL):
+ case ORTHO_1OP(SWP):
+ case ORTHO_1OP(NOT):
+ case ORTHO_1OP(NEG):
+ case ORTHO_1OP(DEC):
+ case ORTHO_1OP(INC):
+ case ORTHO_1OP(CLZ):
+ case ORTHO_1OP(CLO): return 1;
+ }
+ return 0;
+}
+
+static int is_1cc(uint8_t opcode) {
+ switch (opcode) {
+ case ORTHO_1CC(SET, NG):
+ case ORTHO_1CC(SET, PO):
+ case ORTHO_1CC(SET, CS):
+ case ORTHO_1CC(SET, CC):
+ case ORTHO_1CC(SET, EQ):
+ case ORTHO_1CC(SET, NE):
+ case ORTHO_1CC(SET, VS):
+ case ORTHO_1CC(SET, VC): return 1;
+ }
+ return 0;
+}
+
static /*inline*/ uint8_t isrw(uint8_t opcode, uint8_t ext_prefix) {
if ((ext_prefix & 0xD) == 0xD) {
switch (ext_prefix >> 4) {
@@ -535,9 +567,12 @@ static /*inline*/ uint64_t ortho_ind_idx_addr(struct sux *cpu, uint8_t prefix, u
}
}
-static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t prefix, uint64_t address, operand *op, uint64_t *value, uint8_t *op_type, uint8_t *op_id, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) {
+static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t address, operand *op, uint64_t *value, uint8_t *op_type, uint8_t *op_id, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) {
uint64_t tmp_addr = address;
- for (int i = 0; i < 2; i++) {
+
+ int num_ops = 1 + !(is_1op(opcode) || is_1cc(opcode));
+
+ for (int i = 0; i < num_ops; i++) {
union reg tmp;
tmp.u64 = 0;
op[i].type = op_type[i];
@@ -963,7 +998,7 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t
int is_lea = ((opcode & ~0x18) == LEA_RR);
int is_write = 1;
operand op[2];
- cpu->pc = get_ortho_addr(cpu, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread);
+ cpu->pc = get_ortho_addr(cpu, opcode, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread);
for (int i = 0; i < 2; i++) {
if (op[i].type) {
if (is_lea) {
@@ -1077,6 +1112,8 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t
is_write = 0;
} while (0);
break;
+ case ORTHO_1OP(JSR): push(cpu, cpu->pc, (size) ? size : 7, thread); /* Falls Through. */
+ case ORTHO_1OP(JMP): cpu->pc = (op[0].type) ? address[0] : dst; break;
case ORTHO_1OP(INC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 1, thread); break;
case ORTHO_1OP(DEC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 0, thread); break;
case ORTHO_1OP(PSH): push(cpu, dst, size, thread); is_write = 0; break;