diff options
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 43 |
1 files changed, 40 insertions, 3 deletions
@@ -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; |