annotate jagcpu_x86.c @ 1691:e96d0d3bec7f

Don't leak a system context when a game is unloaded
author Mike Pavone <pavone@retrodev.com>
date Sun, 20 Jan 2019 22:48:16 -0800
parents 137dbd05ceab
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1115
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <stdint.h>
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include "backend.h"
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #include "jagcpu.h"
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include "gen_x86.h"
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 void jag_check_resultwrite(jag_cpu_options *opts, uint8_t src, uint8_t dst)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 code_info *code = &opts->gen.code;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 code_ptr no_result = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 jcc(code, CC_Z, no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 //save result to current bank
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 code_ptr writeback_penatly;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 if (dst == src) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 //unclear if src and dst read can share a port if it's the same register
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 //assume that is the case for now
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 writeback_penalty = NULL;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 } else {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 cmp_ir(code, JAGCPU_NOREG, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 code_ptr no_writeback_penalty = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 jcc(code, CC_Z, no_writeback_penalty + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 cmp_ir(code, src, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 code_ptr no_writeback_penalty2 = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 jcc(code, CC_Z, no_writeback_penalty2 + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 cmp_ir(code, dst, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 writeback_penalty = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 jcc(code, CC_NZ, writeback_penalty + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 *no_writeback_penalty = code->cur - (no_writeback_penalty + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 *no_writeback_penalty2 = code->cur - (no_writeback_penalty2 + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 cmp_ir(code, src, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 code_ptr no_result_penalty;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 if (dst == src) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 no_result_penalty = code->cur+1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 jcc(code, CC_NZ, no_result_penalty+1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 } else {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 code_ptr result_penalty = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 jcc(code, CC_Z, result_penalty+1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 cmp_ir(code, dst, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 no_result_penalty = code->cur+1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 jcc(code, CC_NZ, no_result_penalty+1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 *result_penalty = code->cur - (result_penalty + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 code_ptr penalty = code->cur;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 cycles(code, 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 *no_result_penalty = code->cur - (no_result_penalty + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 code_ptr end = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 jmp(end + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 //No result to save, but there could still be a writeback, source read conflict
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 code_ptr end2 = NULL;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 cmp_ir(code, JAGCPU_NOREG, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 code_ptr no_resultreg_move = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 jcc(code, CC_Z, no_resultreg_move+1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 if (src != dst) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 //unclear if src and dst read can share a port if it's the same register
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 //assume that is the case for now
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 cmp_ir(code, src, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 end2 = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 jcc(code, CC_Z, end2+1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 cmp_ir(code, src, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 jcc(code, CC_NZ, penalty)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 *end = code->cur - (end + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 if (end2) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 *end2 = code->cur - (end2 + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 *no_result = code->cur - (no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 mov_rr(code, opts->resultreg, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 *no_resultreg_move = code->cur - (no_resultreg_move + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 void jag_check_resultwrite_noread(jag_cpu_options *opts)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 code_info *code = &opts->gen.code;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81 code_ptr no_result = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 jcc(code, CC_Z, no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 //save result to current bank
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 *no_result = code->cur - (no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 mov_rr(code, opts->resultreg, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 void jag_check_resultwrite_singleread(jag_cpu options *opts, uint8_t reg)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 code_info *code = &opts->gen.code;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 cmp_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 code_ptr no_result = code->cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 jcc(code, CC_Z, no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96 //save result to current bank
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 movzx_rr(code, opts->resultreg, opts->scratch1, SZ_B, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98 mov_rrindex(code, opts->result, opts->bankptr, opts->scratch1, 4, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100 //check for a scoreboard delay
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 cmp_ir(code, reg, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 code_ptr no_delay = code-.cur + 1;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 jcc(code, CC_NZ, no_delay + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 ccylces(code, 1);
1594
137dbd05ceab Fix some issues identified by cppcheck
Michael Pavone <pavone@retrodev.com>
parents: 1115
diff changeset
105 *no_delay = code->cur - (no_delay + 1);
1115
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 *no_result = code->cur - (no_result + 1);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 mov_rr(code, opts->resultreg, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 void translate_jag_quickimmed(jag_cpu_options *opts, uint32_t address, uint16_t opcode, uint32_t value, uint16_t dest)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 jag_check_resultwrite_singleread(opts, dest);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 switch (opcode)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 case ADDQ:
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 case ADDQT:
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 uint16_t *translate_jag_inst(uint16_t *stream, jag_cpu_options *opts, uint32_t address)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124 {
1594
137dbd05ceab Fix some issues identified by cppcheck
Michael Pavone <pavone@retrodev.com>
parents: 1115
diff changeset
125 uint16_t inst = *stream;
1115
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 ++stream;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 uint16_t opcode = jag_opcode(inst, opts->is_gpu);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 check_cycles_int(&opts->gen, address);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 code_info *code = &opts->gen.code;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 switch (opcode)
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 case JAG_MOVEI: {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 uint32_t value = *stream;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 ++stream;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 value |= *stream << 16;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 ++stream;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 jag_check_resultwrite_noread(opts);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139 mov_ir(code, value, opts->result, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 mov_ir(code, jag_reg2(inst), opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 case JAG_MOVE: {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144 uint8_t src = jag_reg1(inst), dst = jag_reg2(inst);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 jag_check_resultwrite_singleread(opts, src);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 //move has a shorter pipeline than normal instructions
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 if (src != dst) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 mov_rdispr(code, opts->bankptr, src * 4, opts->gen.scratch1, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 mov_rrdisp(code, opts->gen.scratch1, opts->bankptr, dst * 4, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 mov_ir(code, dst, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152 mov_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 case JAG_MOVEQ: {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 uint8_t dst = jag_reg2(inst);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 jag_check_resultwrite_noread(opts);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 //moveq has a shorter pipeline than normal instructions
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 mov_irdisp(code, jag_quick(inst), opts->bankptr, dst * 4, SZ_D);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 mov_ir(code, dst, opts->writeback, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 mov_ir(code, JAGCPU_NOREG, opts->resultreg, SZ_B);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
164 case JAG_JR: {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 jag_check_resultwrite_noread(opts);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 //TODO: Pipeline stalls on flag readiness
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 uint16_t cond = jag_reg2(inst);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 if (jag_is_always_false(cond)) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 } else {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
170 int32_t offset = jag_quick(inst);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 if (offset & 0x10) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 offset = -16 + (offset & 0xF);
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177 break;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 default:
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 if (is_quick_1_32_opcode(opcode, opts->is_gpu)) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180 translate_jag_quickimmed(opts, address, jag_quick(inst), jag_reg2(inst));
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 } else if (is_quick_0_31_opcode(opcode)) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182 translate_jag_quickimmed(opts, address, jag_reg1(inst), jag_reg2(inst));
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 } else if (is_single_source(opcode, opts->is_gpu)) {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184 translate_jag_single_source(opts, address, jag_reg2(isnt));
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 } else {
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 translate_jag_normal(opts, address, jag_reg1(inst), jag_reg2(inst));
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 }
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189 return stream;
c1e78a101912 WIP Jaguar GPU/DSP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 }