root / target-microblaze / translate.c @ 658788c5
History | View | Annotate | Download (44 kB)
1 | 4acb54ba | Edgar E. Iglesias | /*
|
---|---|---|---|
2 | 4acb54ba | Edgar E. Iglesias | * Xilinx MicroBlaze emulation for qemu: main translation routines.
|
3 | 4acb54ba | Edgar E. Iglesias | *
|
4 | 4acb54ba | Edgar E. Iglesias | * Copyright (c) 2009 Edgar E. Iglesias.
|
5 | 4acb54ba | Edgar E. Iglesias | *
|
6 | 4acb54ba | Edgar E. Iglesias | * This library is free software; you can redistribute it and/or
|
7 | 4acb54ba | Edgar E. Iglesias | * modify it under the terms of the GNU Lesser General Public
|
8 | 4acb54ba | Edgar E. Iglesias | * License as published by the Free Software Foundation; either
|
9 | 4acb54ba | Edgar E. Iglesias | * version 2 of the License, or (at your option) any later version.
|
10 | 4acb54ba | Edgar E. Iglesias | *
|
11 | 4acb54ba | Edgar E. Iglesias | * This library is distributed in the hope that it will be useful,
|
12 | 4acb54ba | Edgar E. Iglesias | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 4acb54ba | Edgar E. Iglesias | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 4acb54ba | Edgar E. Iglesias | * Lesser General Public License for more details.
|
15 | 4acb54ba | Edgar E. Iglesias | *
|
16 | 4acb54ba | Edgar E. Iglesias | * You should have received a copy of the GNU Lesser General Public
|
17 | 8167ee88 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | 4acb54ba | Edgar E. Iglesias | */
|
19 | 4acb54ba | Edgar E. Iglesias | |
20 | 4acb54ba | Edgar E. Iglesias | #include <stdarg.h> |
21 | 4acb54ba | Edgar E. Iglesias | #include <stdlib.h> |
22 | 4acb54ba | Edgar E. Iglesias | #include <stdio.h> |
23 | 4acb54ba | Edgar E. Iglesias | #include <string.h> |
24 | 4acb54ba | Edgar E. Iglesias | #include <inttypes.h> |
25 | 4acb54ba | Edgar E. Iglesias | #include <assert.h> |
26 | 4acb54ba | Edgar E. Iglesias | |
27 | 4acb54ba | Edgar E. Iglesias | #include "cpu.h" |
28 | 4acb54ba | Edgar E. Iglesias | #include "exec-all.h" |
29 | 4acb54ba | Edgar E. Iglesias | #include "disas.h" |
30 | 4acb54ba | Edgar E. Iglesias | #include "tcg-op.h" |
31 | 4acb54ba | Edgar E. Iglesias | #include "helper.h" |
32 | 4acb54ba | Edgar E. Iglesias | #include "microblaze-decode.h" |
33 | 4acb54ba | Edgar E. Iglesias | #include "qemu-common.h" |
34 | 4acb54ba | Edgar E. Iglesias | |
35 | 4acb54ba | Edgar E. Iglesias | #define GEN_HELPER 1 |
36 | 4acb54ba | Edgar E. Iglesias | #include "helper.h" |
37 | 4acb54ba | Edgar E. Iglesias | |
38 | 4acb54ba | Edgar E. Iglesias | #define SIM_COMPAT 0 |
39 | 4acb54ba | Edgar E. Iglesias | #define DISAS_GNU 1 |
40 | 4acb54ba | Edgar E. Iglesias | #define DISAS_MB 1 |
41 | 4acb54ba | Edgar E. Iglesias | #if DISAS_MB && !SIM_COMPAT
|
42 | 4acb54ba | Edgar E. Iglesias | # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) |
43 | 4acb54ba | Edgar E. Iglesias | #else
|
44 | 4acb54ba | Edgar E. Iglesias | # define LOG_DIS(...) do { } while (0) |
45 | 4acb54ba | Edgar E. Iglesias | #endif
|
46 | 4acb54ba | Edgar E. Iglesias | |
47 | 4acb54ba | Edgar E. Iglesias | #define D(x)
|
48 | 4acb54ba | Edgar E. Iglesias | |
49 | 4acb54ba | Edgar E. Iglesias | #define EXTRACT_FIELD(src, start, end) \
|
50 | 4acb54ba | Edgar E. Iglesias | (((src) >> start) & ((1 << (end - start + 1)) - 1)) |
51 | 4acb54ba | Edgar E. Iglesias | |
52 | 4acb54ba | Edgar E. Iglesias | static TCGv env_debug;
|
53 | 4acb54ba | Edgar E. Iglesias | static TCGv_ptr cpu_env;
|
54 | 4acb54ba | Edgar E. Iglesias | static TCGv cpu_R[32]; |
55 | 4acb54ba | Edgar E. Iglesias | static TCGv cpu_SR[18]; |
56 | 4acb54ba | Edgar E. Iglesias | static TCGv env_imm;
|
57 | 4acb54ba | Edgar E. Iglesias | static TCGv env_btaken;
|
58 | 4acb54ba | Edgar E. Iglesias | static TCGv env_btarget;
|
59 | 4acb54ba | Edgar E. Iglesias | static TCGv env_iflags;
|
60 | 4acb54ba | Edgar E. Iglesias | |
61 | 4acb54ba | Edgar E. Iglesias | #include "gen-icount.h" |
62 | 4acb54ba | Edgar E. Iglesias | |
63 | 4acb54ba | Edgar E. Iglesias | /* This is the state at translation time. */
|
64 | 4acb54ba | Edgar E. Iglesias | typedef struct DisasContext { |
65 | 4acb54ba | Edgar E. Iglesias | CPUState *env; |
66 | 4acb54ba | Edgar E. Iglesias | target_ulong pc, ppc; |
67 | 4acb54ba | Edgar E. Iglesias | target_ulong cache_pc; |
68 | 4acb54ba | Edgar E. Iglesias | |
69 | 4acb54ba | Edgar E. Iglesias | /* Decoder. */
|
70 | 4acb54ba | Edgar E. Iglesias | int type_b;
|
71 | 4acb54ba | Edgar E. Iglesias | uint32_t ir; |
72 | 4acb54ba | Edgar E. Iglesias | uint8_t opcode; |
73 | 4acb54ba | Edgar E. Iglesias | uint8_t rd, ra, rb; |
74 | 4acb54ba | Edgar E. Iglesias | uint16_t imm; |
75 | 4acb54ba | Edgar E. Iglesias | |
76 | 4acb54ba | Edgar E. Iglesias | unsigned int cpustate_changed; |
77 | 4acb54ba | Edgar E. Iglesias | unsigned int delayed_branch; |
78 | 4acb54ba | Edgar E. Iglesias | unsigned int tb_flags, synced_flags; /* tb dependent flags. */ |
79 | 4acb54ba | Edgar E. Iglesias | unsigned int clear_imm; |
80 | 4acb54ba | Edgar E. Iglesias | int is_jmp;
|
81 | 4acb54ba | Edgar E. Iglesias | |
82 | 4acb54ba | Edgar E. Iglesias | #define JMP_NOJMP 0 |
83 | 4acb54ba | Edgar E. Iglesias | #define JMP_DIRECT 1 |
84 | 4acb54ba | Edgar E. Iglesias | #define JMP_INDIRECT 2 |
85 | 4acb54ba | Edgar E. Iglesias | unsigned int jmp; |
86 | 4acb54ba | Edgar E. Iglesias | uint32_t jmp_pc; |
87 | 4acb54ba | Edgar E. Iglesias | |
88 | 4acb54ba | Edgar E. Iglesias | int abort_at_next_insn;
|
89 | 4acb54ba | Edgar E. Iglesias | int nr_nops;
|
90 | 4acb54ba | Edgar E. Iglesias | struct TranslationBlock *tb;
|
91 | 4acb54ba | Edgar E. Iglesias | int singlestep_enabled;
|
92 | 4acb54ba | Edgar E. Iglesias | } DisasContext; |
93 | 4acb54ba | Edgar E. Iglesias | |
94 | 38972938 | Juan Quintela | static const char *regnames[] = |
95 | 4acb54ba | Edgar E. Iglesias | { |
96 | 4acb54ba | Edgar E. Iglesias | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
97 | 4acb54ba | Edgar E. Iglesias | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", |
98 | 4acb54ba | Edgar E. Iglesias | "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", |
99 | 4acb54ba | Edgar E. Iglesias | "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", |
100 | 4acb54ba | Edgar E. Iglesias | }; |
101 | 4acb54ba | Edgar E. Iglesias | |
102 | 38972938 | Juan Quintela | static const char *special_regnames[] = |
103 | 4acb54ba | Edgar E. Iglesias | { |
104 | 4acb54ba | Edgar E. Iglesias | "rpc", "rmsr", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7", |
105 | 4acb54ba | Edgar E. Iglesias | "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15", |
106 | 4acb54ba | Edgar E. Iglesias | "sr16", "sr17", "sr18" |
107 | 4acb54ba | Edgar E. Iglesias | }; |
108 | 4acb54ba | Edgar E. Iglesias | |
109 | 4acb54ba | Edgar E. Iglesias | /* Sign extend at translation time. */
|
110 | 4acb54ba | Edgar E. Iglesias | static inline int sign_extend(unsigned int val, unsigned int width) |
111 | 4acb54ba | Edgar E. Iglesias | { |
112 | 4acb54ba | Edgar E. Iglesias | int sval;
|
113 | 4acb54ba | Edgar E. Iglesias | |
114 | 4acb54ba | Edgar E. Iglesias | /* LSL. */
|
115 | 4acb54ba | Edgar E. Iglesias | val <<= 31 - width;
|
116 | 4acb54ba | Edgar E. Iglesias | sval = val; |
117 | 4acb54ba | Edgar E. Iglesias | /* ASR. */
|
118 | 4acb54ba | Edgar E. Iglesias | sval >>= 31 - width;
|
119 | 4acb54ba | Edgar E. Iglesias | return sval;
|
120 | 4acb54ba | Edgar E. Iglesias | } |
121 | 4acb54ba | Edgar E. Iglesias | |
122 | 4acb54ba | Edgar E. Iglesias | static inline void t_sync_flags(DisasContext *dc) |
123 | 4acb54ba | Edgar E. Iglesias | { |
124 | 4acb54ba | Edgar E. Iglesias | /* Synch the tb dependant flags between translator and runtime. */
|
125 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags != dc->synced_flags) {
|
126 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_iflags, dc->tb_flags); |
127 | 4acb54ba | Edgar E. Iglesias | dc->synced_flags = dc->tb_flags; |
128 | 4acb54ba | Edgar E. Iglesias | } |
129 | 4acb54ba | Edgar E. Iglesias | } |
130 | 4acb54ba | Edgar E. Iglesias | |
131 | 4acb54ba | Edgar E. Iglesias | static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index) |
132 | 4acb54ba | Edgar E. Iglesias | { |
133 | 4acb54ba | Edgar E. Iglesias | TCGv_i32 tmp = tcg_const_i32(index); |
134 | 4acb54ba | Edgar E. Iglesias | |
135 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
136 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); |
137 | 4acb54ba | Edgar E. Iglesias | gen_helper_raise_exception(tmp); |
138 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i32(tmp); |
139 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
140 | 4acb54ba | Edgar E. Iglesias | } |
141 | 4acb54ba | Edgar E. Iglesias | |
142 | 4acb54ba | Edgar E. Iglesias | static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) |
143 | 4acb54ba | Edgar E. Iglesias | { |
144 | 4acb54ba | Edgar E. Iglesias | TranslationBlock *tb; |
145 | 4acb54ba | Edgar E. Iglesias | tb = dc->tb; |
146 | 4acb54ba | Edgar E. Iglesias | if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
|
147 | 4acb54ba | Edgar E. Iglesias | tcg_gen_goto_tb(n); |
148 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dest); |
149 | 4acb54ba | Edgar E. Iglesias | tcg_gen_exit_tb((long)tb + n);
|
150 | 4acb54ba | Edgar E. Iglesias | } else {
|
151 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dest); |
152 | 4acb54ba | Edgar E. Iglesias | tcg_gen_exit_tb(0);
|
153 | 4acb54ba | Edgar E. Iglesias | } |
154 | 4acb54ba | Edgar E. Iglesias | } |
155 | 4acb54ba | Edgar E. Iglesias | |
156 | 4acb54ba | Edgar E. Iglesias | static inline TCGv *dec_alu_op_b(DisasContext *dc) |
157 | 4acb54ba | Edgar E. Iglesias | { |
158 | 4acb54ba | Edgar E. Iglesias | if (dc->type_b) {
|
159 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & IMM_FLAG)
|
160 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(env_imm, env_imm, dc->imm); |
161 | 4acb54ba | Edgar E. Iglesias | else
|
162 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_imm, (int32_t)((int16_t)dc->imm)); |
163 | 4acb54ba | Edgar E. Iglesias | return &env_imm;
|
164 | 4acb54ba | Edgar E. Iglesias | } else
|
165 | 4acb54ba | Edgar E. Iglesias | return &cpu_R[dc->rb];
|
166 | 4acb54ba | Edgar E. Iglesias | } |
167 | 4acb54ba | Edgar E. Iglesias | |
168 | 4acb54ba | Edgar E. Iglesias | static void dec_add(DisasContext *dc) |
169 | 4acb54ba | Edgar E. Iglesias | { |
170 | 4acb54ba | Edgar E. Iglesias | unsigned int k, c; |
171 | 4acb54ba | Edgar E. Iglesias | |
172 | 4acb54ba | Edgar E. Iglesias | k = dc->opcode & 4;
|
173 | 4acb54ba | Edgar E. Iglesias | c = dc->opcode & 2;
|
174 | 4acb54ba | Edgar E. Iglesias | |
175 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("add%s%s%s r%d r%d r%d\n",
|
176 | 4acb54ba | Edgar E. Iglesias | dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "", |
177 | 4acb54ba | Edgar E. Iglesias | dc->rd, dc->ra, dc->rb); |
178 | 4acb54ba | Edgar E. Iglesias | |
179 | 4acb54ba | Edgar E. Iglesias | if (k && !c && dc->rd)
|
180 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
181 | 4acb54ba | Edgar E. Iglesias | else if (dc->rd) |
182 | 4acb54ba | Edgar E. Iglesias | gen_helper_addkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)), |
183 | 4acb54ba | Edgar E. Iglesias | tcg_const_tl(k), tcg_const_tl(c)); |
184 | 4acb54ba | Edgar E. Iglesias | else {
|
185 | 4acb54ba | Edgar E. Iglesias | TCGv d = tcg_temp_new(); |
186 | 4acb54ba | Edgar E. Iglesias | gen_helper_addkc(d, cpu_R[dc->ra], *(dec_alu_op_b(dc)), |
187 | 4acb54ba | Edgar E. Iglesias | tcg_const_tl(k), tcg_const_tl(c)); |
188 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(d); |
189 | 4acb54ba | Edgar E. Iglesias | } |
190 | 4acb54ba | Edgar E. Iglesias | } |
191 | 4acb54ba | Edgar E. Iglesias | |
192 | 4acb54ba | Edgar E. Iglesias | static void dec_sub(DisasContext *dc) |
193 | 4acb54ba | Edgar E. Iglesias | { |
194 | 4acb54ba | Edgar E. Iglesias | unsigned int u, cmp, k, c; |
195 | 4acb54ba | Edgar E. Iglesias | |
196 | 4acb54ba | Edgar E. Iglesias | u = dc->imm & 2;
|
197 | 4acb54ba | Edgar E. Iglesias | k = dc->opcode & 4;
|
198 | 4acb54ba | Edgar E. Iglesias | c = dc->opcode & 2;
|
199 | 4acb54ba | Edgar E. Iglesias | cmp = (dc->imm & 1) && (!dc->type_b) && k;
|
200 | 4acb54ba | Edgar E. Iglesias | |
201 | 4acb54ba | Edgar E. Iglesias | if (cmp) {
|
202 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir); |
203 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
204 | 4acb54ba | Edgar E. Iglesias | if (u)
|
205 | 4acb54ba | Edgar E. Iglesias | gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); |
206 | 4acb54ba | Edgar E. Iglesias | else
|
207 | 4acb54ba | Edgar E. Iglesias | gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); |
208 | 4acb54ba | Edgar E. Iglesias | } |
209 | 4acb54ba | Edgar E. Iglesias | } else {
|
210 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("sub%s%s r%d, r%d r%d\n",
|
211 | 4acb54ba | Edgar E. Iglesias | k ? "k" : "", c ? "c" : "", dc->rd, dc->ra, dc->rb); |
212 | 4acb54ba | Edgar E. Iglesias | |
213 | 4acb54ba | Edgar E. Iglesias | if (!k || c) {
|
214 | 4acb54ba | Edgar E. Iglesias | TCGv t; |
215 | 4acb54ba | Edgar E. Iglesias | t = tcg_temp_new(); |
216 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
217 | 4acb54ba | Edgar E. Iglesias | gen_helper_subkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)), |
218 | 4acb54ba | Edgar E. Iglesias | tcg_const_tl(k), tcg_const_tl(c)); |
219 | 4acb54ba | Edgar E. Iglesias | else
|
220 | 4acb54ba | Edgar E. Iglesias | gen_helper_subkc(t, cpu_R[dc->ra], *(dec_alu_op_b(dc)), |
221 | 4acb54ba | Edgar E. Iglesias | tcg_const_tl(k), tcg_const_tl(c)); |
222 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
223 | 4acb54ba | Edgar E. Iglesias | } |
224 | 4acb54ba | Edgar E. Iglesias | else if (dc->rd) |
225 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sub_tl(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]); |
226 | 4acb54ba | Edgar E. Iglesias | } |
227 | 4acb54ba | Edgar E. Iglesias | } |
228 | 4acb54ba | Edgar E. Iglesias | |
229 | 4acb54ba | Edgar E. Iglesias | static void dec_pattern(DisasContext *dc) |
230 | 4acb54ba | Edgar E. Iglesias | { |
231 | 4acb54ba | Edgar E. Iglesias | unsigned int mode; |
232 | 4acb54ba | Edgar E. Iglesias | int l1;
|
233 | 4acb54ba | Edgar E. Iglesias | |
234 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
235 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
236 | 1567a005 | Edgar E. Iglesias | && !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
|
237 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
238 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
239 | 1567a005 | Edgar E. Iglesias | } |
240 | 1567a005 | Edgar E. Iglesias | |
241 | 4acb54ba | Edgar E. Iglesias | mode = dc->opcode & 3;
|
242 | 4acb54ba | Edgar E. Iglesias | switch (mode) {
|
243 | 4acb54ba | Edgar E. Iglesias | case 0: |
244 | 4acb54ba | Edgar E. Iglesias | /* pcmpbf. */
|
245 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
246 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
247 | 4acb54ba | Edgar E. Iglesias | gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); |
248 | 4acb54ba | Edgar E. Iglesias | break;
|
249 | 4acb54ba | Edgar E. Iglesias | case 2: |
250 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
251 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
252 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_local_new(); |
253 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
254 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 1);
|
255 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_EQ, |
256 | 4acb54ba | Edgar E. Iglesias | cpu_R[dc->ra], cpu_R[dc->rb], l1); |
257 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 0);
|
258 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
259 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], t0); |
260 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
261 | 4acb54ba | Edgar E. Iglesias | } |
262 | 4acb54ba | Edgar E. Iglesias | break;
|
263 | 4acb54ba | Edgar E. Iglesias | case 3: |
264 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
265 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
266 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
267 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_local_new(); |
268 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 1);
|
269 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_NE, |
270 | 4acb54ba | Edgar E. Iglesias | cpu_R[dc->ra], cpu_R[dc->rb], l1); |
271 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 0);
|
272 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
273 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], t0); |
274 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
275 | 4acb54ba | Edgar E. Iglesias | } |
276 | 4acb54ba | Edgar E. Iglesias | break;
|
277 | 4acb54ba | Edgar E. Iglesias | default:
|
278 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, |
279 | 4acb54ba | Edgar E. Iglesias | "unsupported pattern insn opcode=%x\n", dc->opcode);
|
280 | 4acb54ba | Edgar E. Iglesias | break;
|
281 | 4acb54ba | Edgar E. Iglesias | } |
282 | 4acb54ba | Edgar E. Iglesias | } |
283 | 4acb54ba | Edgar E. Iglesias | |
284 | 4acb54ba | Edgar E. Iglesias | static void dec_and(DisasContext *dc) |
285 | 4acb54ba | Edgar E. Iglesias | { |
286 | 4acb54ba | Edgar E. Iglesias | unsigned int not; |
287 | 4acb54ba | Edgar E. Iglesias | |
288 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
289 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
290 | 4acb54ba | Edgar E. Iglesias | return;
|
291 | 4acb54ba | Edgar E. Iglesias | } |
292 | 4acb54ba | Edgar E. Iglesias | |
293 | 4acb54ba | Edgar E. Iglesias | not = dc->opcode & (1 << 1); |
294 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("and%s\n", not ? "n" : ""); |
295 | 4acb54ba | Edgar E. Iglesias | |
296 | 4acb54ba | Edgar E. Iglesias | if (!dc->rd)
|
297 | 4acb54ba | Edgar E. Iglesias | return;
|
298 | 4acb54ba | Edgar E. Iglesias | |
299 | 4acb54ba | Edgar E. Iglesias | if (not) {
|
300 | 4acb54ba | Edgar E. Iglesias | TCGv t = tcg_temp_new(); |
301 | 4acb54ba | Edgar E. Iglesias | tcg_gen_not_tl(t, *(dec_alu_op_b(dc))); |
302 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], t); |
303 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
304 | 4acb54ba | Edgar E. Iglesias | } else
|
305 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
306 | 4acb54ba | Edgar E. Iglesias | } |
307 | 4acb54ba | Edgar E. Iglesias | |
308 | 4acb54ba | Edgar E. Iglesias | static void dec_or(DisasContext *dc) |
309 | 4acb54ba | Edgar E. Iglesias | { |
310 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
311 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
312 | 4acb54ba | Edgar E. Iglesias | return;
|
313 | 4acb54ba | Edgar E. Iglesias | } |
314 | 4acb54ba | Edgar E. Iglesias | |
315 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
|
316 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
317 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
318 | 4acb54ba | Edgar E. Iglesias | } |
319 | 4acb54ba | Edgar E. Iglesias | |
320 | 4acb54ba | Edgar E. Iglesias | static void dec_xor(DisasContext *dc) |
321 | 4acb54ba | Edgar E. Iglesias | { |
322 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
323 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
324 | 4acb54ba | Edgar E. Iglesias | return;
|
325 | 4acb54ba | Edgar E. Iglesias | } |
326 | 4acb54ba | Edgar E. Iglesias | |
327 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("xor r%d\n", dc->rd);
|
328 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
329 | 4acb54ba | Edgar E. Iglesias | tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
330 | 4acb54ba | Edgar E. Iglesias | } |
331 | 4acb54ba | Edgar E. Iglesias | |
332 | 4acb54ba | Edgar E. Iglesias | static void read_carry(DisasContext *dc, TCGv d) |
333 | 4acb54ba | Edgar E. Iglesias | { |
334 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
|
335 | 4acb54ba | Edgar E. Iglesias | } |
336 | 4acb54ba | Edgar E. Iglesias | |
337 | 4acb54ba | Edgar E. Iglesias | static void write_carry(DisasContext *dc, TCGv v) |
338 | 4acb54ba | Edgar E. Iglesias | { |
339 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_new(); |
340 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shli_tl(t0, v, 31);
|
341 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sari_tl(t0, t0, 31);
|
342 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(env_debug, t0); |
343 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC)); |
344 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], |
345 | 4acb54ba | Edgar E. Iglesias | ~(MSR_C | MSR_CC)); |
346 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0); |
347 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
348 | 4acb54ba | Edgar E. Iglesias | } |
349 | 4acb54ba | Edgar E. Iglesias | |
350 | 4acb54ba | Edgar E. Iglesias | |
351 | 4acb54ba | Edgar E. Iglesias | static inline void msr_read(DisasContext *dc, TCGv d) |
352 | 4acb54ba | Edgar E. Iglesias | { |
353 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(d, cpu_SR[SR_MSR]); |
354 | 4acb54ba | Edgar E. Iglesias | } |
355 | 4acb54ba | Edgar E. Iglesias | |
356 | 4acb54ba | Edgar E. Iglesias | static inline void msr_write(DisasContext *dc, TCGv v) |
357 | 4acb54ba | Edgar E. Iglesias | { |
358 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 1;
|
359 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_MSR], v); |
360 | 4acb54ba | Edgar E. Iglesias | /* PVR, we have a processor version register. */
|
361 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10)); |
362 | 4acb54ba | Edgar E. Iglesias | } |
363 | 4acb54ba | Edgar E. Iglesias | |
364 | 4acb54ba | Edgar E. Iglesias | static void dec_msr(DisasContext *dc) |
365 | 4acb54ba | Edgar E. Iglesias | { |
366 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
367 | 4acb54ba | Edgar E. Iglesias | unsigned int sr, to, rn; |
368 | 1567a005 | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
369 | 4acb54ba | Edgar E. Iglesias | |
370 | 4acb54ba | Edgar E. Iglesias | sr = dc->imm & ((1 << 14) - 1); |
371 | 4acb54ba | Edgar E. Iglesias | to = dc->imm & (1 << 14); |
372 | 4acb54ba | Edgar E. Iglesias | dc->type_b = 1;
|
373 | 4acb54ba | Edgar E. Iglesias | if (to)
|
374 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 1;
|
375 | 4acb54ba | Edgar E. Iglesias | |
376 | 4acb54ba | Edgar E. Iglesias | /* msrclr and msrset. */
|
377 | 4acb54ba | Edgar E. Iglesias | if (!(dc->imm & (1 << 15))) { |
378 | 4acb54ba | Edgar E. Iglesias | unsigned int clr = dc->ir & (1 << 16); |
379 | 4acb54ba | Edgar E. Iglesias | |
380 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set", |
381 | 4acb54ba | Edgar E. Iglesias | dc->rd, dc->imm); |
382 | 1567a005 | Edgar E. Iglesias | |
383 | 1567a005 | Edgar E. Iglesias | if (!(dc->env->pvr.regs[2] & PVR2_USE_MSR_INSTR)) { |
384 | 1567a005 | Edgar E. Iglesias | /* nop??? */
|
385 | 1567a005 | Edgar E. Iglesias | return;
|
386 | 1567a005 | Edgar E. Iglesias | } |
387 | 1567a005 | Edgar E. Iglesias | |
388 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
389 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) { |
390 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
391 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
392 | 1567a005 | Edgar E. Iglesias | return;
|
393 | 1567a005 | Edgar E. Iglesias | } |
394 | 1567a005 | Edgar E. Iglesias | |
395 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
396 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, cpu_R[dc->rd]); |
397 | 4acb54ba | Edgar E. Iglesias | |
398 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
399 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
400 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, t0); |
401 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc))); |
402 | 4acb54ba | Edgar E. Iglesias | |
403 | 4acb54ba | Edgar E. Iglesias | if (clr) {
|
404 | 4acb54ba | Edgar E. Iglesias | tcg_gen_not_tl(t1, t1); |
405 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(t0, t0, t1); |
406 | 4acb54ba | Edgar E. Iglesias | } else
|
407 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t0, t0, t1); |
408 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t0); |
409 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
410 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
411 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
|
412 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
413 | 4acb54ba | Edgar E. Iglesias | return;
|
414 | 4acb54ba | Edgar E. Iglesias | } |
415 | 4acb54ba | Edgar E. Iglesias | |
416 | 1567a005 | Edgar E. Iglesias | if (to) {
|
417 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
418 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
419 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
420 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
421 | 1567a005 | Edgar E. Iglesias | return;
|
422 | 1567a005 | Edgar E. Iglesias | } |
423 | 1567a005 | Edgar E. Iglesias | } |
424 | 1567a005 | Edgar E. Iglesias | |
425 | 4acb54ba | Edgar E. Iglesias | #if !defined(CONFIG_USER_ONLY)
|
426 | 4acb54ba | Edgar E. Iglesias | /* Catch read/writes to the mmu block. */
|
427 | 4acb54ba | Edgar E. Iglesias | if ((sr & ~0xff) == 0x1000) { |
428 | 4acb54ba | Edgar E. Iglesias | sr &= 7;
|
429 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm); |
430 | 4acb54ba | Edgar E. Iglesias | if (to)
|
431 | 4acb54ba | Edgar E. Iglesias | gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]); |
432 | 4acb54ba | Edgar E. Iglesias | else
|
433 | 4acb54ba | Edgar E. Iglesias | gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr)); |
434 | 4acb54ba | Edgar E. Iglesias | return;
|
435 | 4acb54ba | Edgar E. Iglesias | } |
436 | 4acb54ba | Edgar E. Iglesias | #endif
|
437 | 4acb54ba | Edgar E. Iglesias | |
438 | 4acb54ba | Edgar E. Iglesias | if (to) {
|
439 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm); |
440 | 4acb54ba | Edgar E. Iglesias | switch (sr) {
|
441 | 4acb54ba | Edgar E. Iglesias | case 0: |
442 | 4acb54ba | Edgar E. Iglesias | break;
|
443 | 4acb54ba | Edgar E. Iglesias | case 1: |
444 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, cpu_R[dc->ra]); |
445 | 4acb54ba | Edgar E. Iglesias | break;
|
446 | 4acb54ba | Edgar E. Iglesias | case 0x3: |
447 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]); |
448 | 4acb54ba | Edgar E. Iglesias | break;
|
449 | 4acb54ba | Edgar E. Iglesias | case 0x5: |
450 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]); |
451 | 4acb54ba | Edgar E. Iglesias | break;
|
452 | 4acb54ba | Edgar E. Iglesias | case 0x7: |
453 | 4acb54ba | Edgar E. Iglesias | /* Ignored at the moment. */
|
454 | 4acb54ba | Edgar E. Iglesias | break;
|
455 | 4acb54ba | Edgar E. Iglesias | default:
|
456 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown mts reg %x\n", sr);
|
457 | 4acb54ba | Edgar E. Iglesias | break;
|
458 | 4acb54ba | Edgar E. Iglesias | } |
459 | 4acb54ba | Edgar E. Iglesias | } else {
|
460 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm); |
461 | 4acb54ba | Edgar E. Iglesias | |
462 | 4acb54ba | Edgar E. Iglesias | switch (sr) {
|
463 | 4acb54ba | Edgar E. Iglesias | case 0: |
464 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc); |
465 | 4acb54ba | Edgar E. Iglesias | break;
|
466 | 4acb54ba | Edgar E. Iglesias | case 1: |
467 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, cpu_R[dc->rd]); |
468 | 4acb54ba | Edgar E. Iglesias | break;
|
469 | 4acb54ba | Edgar E. Iglesias | case 0x3: |
470 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]); |
471 | 4acb54ba | Edgar E. Iglesias | break;
|
472 | 4acb54ba | Edgar E. Iglesias | case 0x5: |
473 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]); |
474 | 4acb54ba | Edgar E. Iglesias | break;
|
475 | 4acb54ba | Edgar E. Iglesias | case 0x7: |
476 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], 0);
|
477 | 4acb54ba | Edgar E. Iglesias | break;
|
478 | 4acb54ba | Edgar E. Iglesias | case 0xb: |
479 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]); |
480 | 4acb54ba | Edgar E. Iglesias | break;
|
481 | 4acb54ba | Edgar E. Iglesias | case 0x2000: |
482 | 4acb54ba | Edgar E. Iglesias | case 0x2001: |
483 | 4acb54ba | Edgar E. Iglesias | case 0x2002: |
484 | 4acb54ba | Edgar E. Iglesias | case 0x2003: |
485 | 4acb54ba | Edgar E. Iglesias | case 0x2004: |
486 | 4acb54ba | Edgar E. Iglesias | case 0x2005: |
487 | 4acb54ba | Edgar E. Iglesias | case 0x2006: |
488 | 4acb54ba | Edgar E. Iglesias | case 0x2007: |
489 | 4acb54ba | Edgar E. Iglesias | case 0x2008: |
490 | 4acb54ba | Edgar E. Iglesias | case 0x2009: |
491 | 4acb54ba | Edgar E. Iglesias | case 0x200a: |
492 | 4acb54ba | Edgar E. Iglesias | case 0x200b: |
493 | 4acb54ba | Edgar E. Iglesias | case 0x200c: |
494 | 4acb54ba | Edgar E. Iglesias | rn = sr & 0xf;
|
495 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ld_tl(cpu_R[dc->rd], |
496 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, pvr.regs[rn])); |
497 | 4acb54ba | Edgar E. Iglesias | break;
|
498 | 4acb54ba | Edgar E. Iglesias | default:
|
499 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown mfs reg %x\n", sr);
|
500 | 4acb54ba | Edgar E. Iglesias | break;
|
501 | 4acb54ba | Edgar E. Iglesias | } |
502 | 4acb54ba | Edgar E. Iglesias | } |
503 | ee7dbcf8 | Edgar E. Iglesias | |
504 | ee7dbcf8 | Edgar E. Iglesias | if (dc->rd == 0) { |
505 | ee7dbcf8 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[0], 0); |
506 | ee7dbcf8 | Edgar E. Iglesias | } |
507 | 4acb54ba | Edgar E. Iglesias | } |
508 | 4acb54ba | Edgar E. Iglesias | |
509 | 4acb54ba | Edgar E. Iglesias | /* 64-bit signed mul, lower result in d and upper in d2. */
|
510 | 4acb54ba | Edgar E. Iglesias | static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) |
511 | 4acb54ba | Edgar E. Iglesias | { |
512 | 4acb54ba | Edgar E. Iglesias | TCGv_i64 t0, t1; |
513 | 4acb54ba | Edgar E. Iglesias | |
514 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new_i64(); |
515 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new_i64(); |
516 | 4acb54ba | Edgar E. Iglesias | |
517 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext_i32_i64(t0, a); |
518 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext_i32_i64(t1, b); |
519 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mul_i64(t0, t0, t1); |
520 | 4acb54ba | Edgar E. Iglesias | |
521 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d, t0); |
522 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_i64(t0, t0, 32);
|
523 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d2, t0); |
524 | 4acb54ba | Edgar E. Iglesias | |
525 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t0); |
526 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t1); |
527 | 4acb54ba | Edgar E. Iglesias | } |
528 | 4acb54ba | Edgar E. Iglesias | |
529 | 4acb54ba | Edgar E. Iglesias | /* 64-bit unsigned muls, lower result in d and upper in d2. */
|
530 | 4acb54ba | Edgar E. Iglesias | static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) |
531 | 4acb54ba | Edgar E. Iglesias | { |
532 | 4acb54ba | Edgar E. Iglesias | TCGv_i64 t0, t1; |
533 | 4acb54ba | Edgar E. Iglesias | |
534 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new_i64(); |
535 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new_i64(); |
536 | 4acb54ba | Edgar E. Iglesias | |
537 | 4acb54ba | Edgar E. Iglesias | tcg_gen_extu_i32_i64(t0, a); |
538 | 4acb54ba | Edgar E. Iglesias | tcg_gen_extu_i32_i64(t1, b); |
539 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mul_i64(t0, t0, t1); |
540 | 4acb54ba | Edgar E. Iglesias | |
541 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d, t0); |
542 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_i64(t0, t0, 32);
|
543 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d2, t0); |
544 | 4acb54ba | Edgar E. Iglesias | |
545 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t0); |
546 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t1); |
547 | 4acb54ba | Edgar E. Iglesias | } |
548 | 4acb54ba | Edgar E. Iglesias | |
549 | 4acb54ba | Edgar E. Iglesias | /* Multiplier unit. */
|
550 | 4acb54ba | Edgar E. Iglesias | static void dec_mul(DisasContext *dc) |
551 | 4acb54ba | Edgar E. Iglesias | { |
552 | 4acb54ba | Edgar E. Iglesias | TCGv d[2];
|
553 | 4acb54ba | Edgar E. Iglesias | unsigned int subcode; |
554 | 4acb54ba | Edgar E. Iglesias | |
555 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
556 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
557 | 1567a005 | Edgar E. Iglesias | && !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
|
558 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
559 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
560 | 1567a005 | Edgar E. Iglesias | return;
|
561 | 1567a005 | Edgar E. Iglesias | } |
562 | 1567a005 | Edgar E. Iglesias | |
563 | 4acb54ba | Edgar E. Iglesias | subcode = dc->imm & 3;
|
564 | 4acb54ba | Edgar E. Iglesias | d[0] = tcg_temp_new();
|
565 | 4acb54ba | Edgar E. Iglesias | d[1] = tcg_temp_new();
|
566 | 4acb54ba | Edgar E. Iglesias | |
567 | 4acb54ba | Edgar E. Iglesias | if (dc->type_b) {
|
568 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
|
569 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
570 | 4acb54ba | Edgar E. Iglesias | goto done;
|
571 | 4acb54ba | Edgar E. Iglesias | } |
572 | 4acb54ba | Edgar E. Iglesias | |
573 | 1567a005 | Edgar E. Iglesias | /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2. */
|
574 | 1567a005 | Edgar E. Iglesias | if (subcode >= 1 && subcode <= 3 |
575 | 1567a005 | Edgar E. Iglesias | && !((dc->env->pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
|
576 | 1567a005 | Edgar E. Iglesias | /* nop??? */
|
577 | 1567a005 | Edgar E. Iglesias | } |
578 | 1567a005 | Edgar E. Iglesias | |
579 | 4acb54ba | Edgar E. Iglesias | switch (subcode) {
|
580 | 4acb54ba | Edgar E. Iglesias | case 0: |
581 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
582 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
|
583 | 4acb54ba | Edgar E. Iglesias | break;
|
584 | 4acb54ba | Edgar E. Iglesias | case 1: |
585 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
586 | 4acb54ba | Edgar E. Iglesias | t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
587 | 4acb54ba | Edgar E. Iglesias | break;
|
588 | 4acb54ba | Edgar E. Iglesias | case 2: |
589 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
590 | 4acb54ba | Edgar E. Iglesias | t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
591 | 4acb54ba | Edgar E. Iglesias | break;
|
592 | 4acb54ba | Edgar E. Iglesias | case 3: |
593 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
594 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
595 | 4acb54ba | Edgar E. Iglesias | break;
|
596 | 4acb54ba | Edgar E. Iglesias | default:
|
597 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown MUL insn %x\n", subcode);
|
598 | 4acb54ba | Edgar E. Iglesias | break;
|
599 | 4acb54ba | Edgar E. Iglesias | } |
600 | 4acb54ba | Edgar E. Iglesias | done:
|
601 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(d[0]);
|
602 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(d[1]);
|
603 | 4acb54ba | Edgar E. Iglesias | } |
604 | 4acb54ba | Edgar E. Iglesias | |
605 | 4acb54ba | Edgar E. Iglesias | /* Div unit. */
|
606 | 4acb54ba | Edgar E. Iglesias | static void dec_div(DisasContext *dc) |
607 | 4acb54ba | Edgar E. Iglesias | { |
608 | 4acb54ba | Edgar E. Iglesias | unsigned int u; |
609 | 4acb54ba | Edgar E. Iglesias | |
610 | 4acb54ba | Edgar E. Iglesias | u = dc->imm & 2;
|
611 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("div\n");
|
612 | 4acb54ba | Edgar E. Iglesias | |
613 | 97f90cbf | Edgar E. Iglesias | if ((dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) |
614 | 1567a005 | Edgar E. Iglesias | && !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) {
|
615 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
616 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
617 | 1567a005 | Edgar E. Iglesias | } |
618 | 1567a005 | Edgar E. Iglesias | |
619 | 4acb54ba | Edgar E. Iglesias | if (u)
|
620 | 4acb54ba | Edgar E. Iglesias | gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]); |
621 | 4acb54ba | Edgar E. Iglesias | else
|
622 | 4acb54ba | Edgar E. Iglesias | gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]); |
623 | 4acb54ba | Edgar E. Iglesias | if (!dc->rd)
|
624 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], 0);
|
625 | 4acb54ba | Edgar E. Iglesias | } |
626 | 4acb54ba | Edgar E. Iglesias | |
627 | 4acb54ba | Edgar E. Iglesias | static void dec_barrel(DisasContext *dc) |
628 | 4acb54ba | Edgar E. Iglesias | { |
629 | 4acb54ba | Edgar E. Iglesias | TCGv t0; |
630 | 4acb54ba | Edgar E. Iglesias | unsigned int s, t; |
631 | 4acb54ba | Edgar E. Iglesias | |
632 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
633 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
634 | 1567a005 | Edgar E. Iglesias | && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
|
635 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
636 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
637 | 1567a005 | Edgar E. Iglesias | return;
|
638 | 1567a005 | Edgar E. Iglesias | } |
639 | 1567a005 | Edgar E. Iglesias | |
640 | 4acb54ba | Edgar E. Iglesias | s = dc->imm & (1 << 10); |
641 | 4acb54ba | Edgar E. Iglesias | t = dc->imm & (1 << 9); |
642 | 4acb54ba | Edgar E. Iglesias | |
643 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("bs%s%s r%d r%d r%d\n",
|
644 | 4acb54ba | Edgar E. Iglesias | s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb); |
645 | 4acb54ba | Edgar E. Iglesias | |
646 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
647 | 4acb54ba | Edgar E. Iglesias | |
648 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc))); |
649 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, 31);
|
650 | 4acb54ba | Edgar E. Iglesias | |
651 | 4acb54ba | Edgar E. Iglesias | if (s)
|
652 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
653 | 4acb54ba | Edgar E. Iglesias | else {
|
654 | 4acb54ba | Edgar E. Iglesias | if (t)
|
655 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
656 | 4acb54ba | Edgar E. Iglesias | else
|
657 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
658 | 4acb54ba | Edgar E. Iglesias | } |
659 | 4acb54ba | Edgar E. Iglesias | } |
660 | 4acb54ba | Edgar E. Iglesias | |
661 | 4acb54ba | Edgar E. Iglesias | static void dec_bit(DisasContext *dc) |
662 | 4acb54ba | Edgar E. Iglesias | { |
663 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
664 | 4acb54ba | Edgar E. Iglesias | unsigned int op; |
665 | 1567a005 | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
666 | 4acb54ba | Edgar E. Iglesias | |
667 | 4acb54ba | Edgar E. Iglesias | op = dc->ir & ((1 << 8) - 1); |
668 | 4acb54ba | Edgar E. Iglesias | switch (op) {
|
669 | 4acb54ba | Edgar E. Iglesias | case 0x21: |
670 | 4acb54ba | Edgar E. Iglesias | /* src. */
|
671 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
672 | 4acb54ba | Edgar E. Iglesias | |
673 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
|
674 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
|
675 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
676 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
677 | 4acb54ba | Edgar E. Iglesias | read_carry(dc, t1); |
678 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shli_tl(t1, t1, 31);
|
679 | 4acb54ba | Edgar E. Iglesias | |
680 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
681 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t1); |
682 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
683 | 4acb54ba | Edgar E. Iglesias | } |
684 | 4acb54ba | Edgar E. Iglesias | |
685 | 4acb54ba | Edgar E. Iglesias | /* Update carry. */
|
686 | 4acb54ba | Edgar E. Iglesias | write_carry(dc, t0); |
687 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
688 | 4acb54ba | Edgar E. Iglesias | break;
|
689 | 4acb54ba | Edgar E. Iglesias | |
690 | 4acb54ba | Edgar E. Iglesias | case 0x1: |
691 | 4acb54ba | Edgar E. Iglesias | case 0x41: |
692 | 4acb54ba | Edgar E. Iglesias | /* srl. */
|
693 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
694 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
|
695 | 4acb54ba | Edgar E. Iglesias | |
696 | 4acb54ba | Edgar E. Iglesias | /* Update carry. */
|
697 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
|
698 | 4acb54ba | Edgar E. Iglesias | write_carry(dc, t0); |
699 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
700 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
701 | 4acb54ba | Edgar E. Iglesias | if (op == 0x41) |
702 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
703 | 4acb54ba | Edgar E. Iglesias | else
|
704 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
705 | 4acb54ba | Edgar E. Iglesias | } |
706 | 4acb54ba | Edgar E. Iglesias | break;
|
707 | 4acb54ba | Edgar E. Iglesias | case 0x60: |
708 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
|
709 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]); |
710 | 4acb54ba | Edgar E. Iglesias | break;
|
711 | 4acb54ba | Edgar E. Iglesias | case 0x61: |
712 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
|
713 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]); |
714 | 4acb54ba | Edgar E. Iglesias | break;
|
715 | 4acb54ba | Edgar E. Iglesias | case 0x64: |
716 | 4acb54ba | Edgar E. Iglesias | /* wdc. */
|
717 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("wdc r%d\n", dc->ra);
|
718 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
719 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
720 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
721 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
722 | 1567a005 | Edgar E. Iglesias | return;
|
723 | 1567a005 | Edgar E. Iglesias | } |
724 | 4acb54ba | Edgar E. Iglesias | break;
|
725 | 4acb54ba | Edgar E. Iglesias | case 0x68: |
726 | 4acb54ba | Edgar E. Iglesias | /* wic. */
|
727 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("wic r%d\n", dc->ra);
|
728 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
729 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
730 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
731 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
732 | 1567a005 | Edgar E. Iglesias | return;
|
733 | 1567a005 | Edgar E. Iglesias | } |
734 | 4acb54ba | Edgar E. Iglesias | break;
|
735 | 4acb54ba | Edgar E. Iglesias | default:
|
736 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
|
737 | 4acb54ba | Edgar E. Iglesias | dc->pc, op, dc->rd, dc->ra, dc->rb); |
738 | 4acb54ba | Edgar E. Iglesias | break;
|
739 | 4acb54ba | Edgar E. Iglesias | } |
740 | 4acb54ba | Edgar E. Iglesias | } |
741 | 4acb54ba | Edgar E. Iglesias | |
742 | 4acb54ba | Edgar E. Iglesias | static inline void sync_jmpstate(DisasContext *dc) |
743 | 4acb54ba | Edgar E. Iglesias | { |
744 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp == JMP_DIRECT) {
|
745 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
746 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
747 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->jmp_pc); |
748 | 4acb54ba | Edgar E. Iglesias | } |
749 | 4acb54ba | Edgar E. Iglesias | } |
750 | 4acb54ba | Edgar E. Iglesias | |
751 | 4acb54ba | Edgar E. Iglesias | static void dec_imm(DisasContext *dc) |
752 | 4acb54ba | Edgar E. Iglesias | { |
753 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("imm %x\n", dc->imm << 16); |
754 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_imm, (dc->imm << 16));
|
755 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= IMM_FLAG; |
756 | 4acb54ba | Edgar E. Iglesias | dc->clear_imm = 0;
|
757 | 4acb54ba | Edgar E. Iglesias | } |
758 | 4acb54ba | Edgar E. Iglesias | |
759 | 4acb54ba | Edgar E. Iglesias | static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr, |
760 | 4acb54ba | Edgar E. Iglesias | unsigned int size) |
761 | 4acb54ba | Edgar E. Iglesias | { |
762 | 4acb54ba | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
763 | 4acb54ba | Edgar E. Iglesias | |
764 | 4acb54ba | Edgar E. Iglesias | if (size == 1) { |
765 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld8u(dst, addr, mem_index); |
766 | 4acb54ba | Edgar E. Iglesias | } else if (size == 2) { |
767 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld16u(dst, addr, mem_index); |
768 | 4acb54ba | Edgar E. Iglesias | } else if (size == 4) { |
769 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld32u(dst, addr, mem_index); |
770 | 4acb54ba | Edgar E. Iglesias | } else
|
771 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Incorrect load size %d\n", size);
|
772 | 4acb54ba | Edgar E. Iglesias | } |
773 | 4acb54ba | Edgar E. Iglesias | |
774 | 4acb54ba | Edgar E. Iglesias | static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t) |
775 | 4acb54ba | Edgar E. Iglesias | { |
776 | 4acb54ba | Edgar E. Iglesias | unsigned int extimm = dc->tb_flags & IMM_FLAG; |
777 | 4acb54ba | Edgar E. Iglesias | |
778 | 4acb54ba | Edgar E. Iglesias | /* Treat the fast cases first. */
|
779 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b) {
|
780 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
781 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]); |
782 | 4acb54ba | Edgar E. Iglesias | return t;
|
783 | 4acb54ba | Edgar E. Iglesias | } |
784 | 4acb54ba | Edgar E. Iglesias | /* Immediate. */
|
785 | 4acb54ba | Edgar E. Iglesias | if (!extimm) {
|
786 | 4acb54ba | Edgar E. Iglesias | if (dc->imm == 0) { |
787 | 4acb54ba | Edgar E. Iglesias | return &cpu_R[dc->ra];
|
788 | 4acb54ba | Edgar E. Iglesias | } |
789 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
790 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm)); |
791 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], *t); |
792 | 4acb54ba | Edgar E. Iglesias | } else {
|
793 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
794 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
795 | 4acb54ba | Edgar E. Iglesias | } |
796 | 4acb54ba | Edgar E. Iglesias | |
797 | 4acb54ba | Edgar E. Iglesias | return t;
|
798 | 4acb54ba | Edgar E. Iglesias | } |
799 | 4acb54ba | Edgar E. Iglesias | |
800 | 4acb54ba | Edgar E. Iglesias | static void dec_load(DisasContext *dc) |
801 | 4acb54ba | Edgar E. Iglesias | { |
802 | 4acb54ba | Edgar E. Iglesias | TCGv t, *addr; |
803 | 4acb54ba | Edgar E. Iglesias | unsigned int size; |
804 | 4acb54ba | Edgar E. Iglesias | |
805 | 4acb54ba | Edgar E. Iglesias | size = 1 << (dc->opcode & 3); |
806 | 0187688f | Edgar E. Iglesias | if (size > 4 && (dc->tb_flags & MSR_EE_FLAG) |
807 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
808 | 0187688f | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
809 | 0187688f | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
810 | 0187688f | Edgar E. Iglesias | return;
|
811 | 0187688f | Edgar E. Iglesias | } |
812 | 4acb54ba | Edgar E. Iglesias | |
813 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("l %x %d\n", dc->opcode, size);
|
814 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
815 | 4acb54ba | Edgar E. Iglesias | addr = compute_ldst_addr(dc, &t); |
816 | 4acb54ba | Edgar E. Iglesias | |
817 | 4acb54ba | Edgar E. Iglesias | /* If we get a fault on a dslot, the jmpstate better be in sync. */
|
818 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
819 | 968a40f6 | Edgar E. Iglesias | |
820 | 968a40f6 | Edgar E. Iglesias | /* Verify alignment if needed. */
|
821 | 968a40f6 | Edgar E. Iglesias | if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) { |
822 | a12f6507 | Edgar E. Iglesias | TCGv v = tcg_temp_new(); |
823 | a12f6507 | Edgar E. Iglesias | |
824 | a12f6507 | Edgar E. Iglesias | /*
|
825 | a12f6507 | Edgar E. Iglesias | * Microblaze gives MMU faults priority over faults due to
|
826 | a12f6507 | Edgar E. Iglesias | * unaligned addresses. That's why we speculatively do the load
|
827 | a12f6507 | Edgar E. Iglesias | * into v. If the load succeeds, we verify alignment of the
|
828 | a12f6507 | Edgar E. Iglesias | * address and if that succeeds we write into the destination reg.
|
829 | a12f6507 | Edgar E. Iglesias | */
|
830 | a12f6507 | Edgar E. Iglesias | gen_load(dc, v, *addr, size); |
831 | a12f6507 | Edgar E. Iglesias | |
832 | a12f6507 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); |
833 | 968a40f6 | Edgar E. Iglesias | gen_helper_memalign(*addr, tcg_const_tl(dc->rd), |
834 | 3aa80988 | Edgar E. Iglesias | tcg_const_tl(0), tcg_const_tl(size - 1)); |
835 | a12f6507 | Edgar E. Iglesias | if (dc->rd)
|
836 | a12f6507 | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], v); |
837 | a12f6507 | Edgar E. Iglesias | tcg_temp_free(v); |
838 | 968a40f6 | Edgar E. Iglesias | } else {
|
839 | a12f6507 | Edgar E. Iglesias | if (dc->rd) {
|
840 | a12f6507 | Edgar E. Iglesias | gen_load(dc, cpu_R[dc->rd], *addr, size); |
841 | a12f6507 | Edgar E. Iglesias | } else {
|
842 | a12f6507 | Edgar E. Iglesias | gen_load(dc, env_imm, *addr, size); |
843 | a12f6507 | Edgar E. Iglesias | } |
844 | 4acb54ba | Edgar E. Iglesias | } |
845 | 4acb54ba | Edgar E. Iglesias | |
846 | 4acb54ba | Edgar E. Iglesias | if (addr == &t)
|
847 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
848 | 4acb54ba | Edgar E. Iglesias | } |
849 | 4acb54ba | Edgar E. Iglesias | |
850 | 4acb54ba | Edgar E. Iglesias | static void gen_store(DisasContext *dc, TCGv addr, TCGv val, |
851 | 4acb54ba | Edgar E. Iglesias | unsigned int size) |
852 | 4acb54ba | Edgar E. Iglesias | { |
853 | 4acb54ba | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
854 | 4acb54ba | Edgar E. Iglesias | |
855 | 4acb54ba | Edgar E. Iglesias | if (size == 1) |
856 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st8(val, addr, mem_index); |
857 | 4acb54ba | Edgar E. Iglesias | else if (size == 2) { |
858 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st16(val, addr, mem_index); |
859 | 4acb54ba | Edgar E. Iglesias | } else if (size == 4) { |
860 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st32(val, addr, mem_index); |
861 | 4acb54ba | Edgar E. Iglesias | } else
|
862 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Incorrect store size %d\n", size);
|
863 | 4acb54ba | Edgar E. Iglesias | } |
864 | 4acb54ba | Edgar E. Iglesias | |
865 | 4acb54ba | Edgar E. Iglesias | static void dec_store(DisasContext *dc) |
866 | 4acb54ba | Edgar E. Iglesias | { |
867 | 4acb54ba | Edgar E. Iglesias | TCGv t, *addr; |
868 | 4acb54ba | Edgar E. Iglesias | unsigned int size; |
869 | 4acb54ba | Edgar E. Iglesias | |
870 | 4acb54ba | Edgar E. Iglesias | size = 1 << (dc->opcode & 3); |
871 | 4acb54ba | Edgar E. Iglesias | |
872 | 0187688f | Edgar E. Iglesias | if (size > 4 && (dc->tb_flags & MSR_EE_FLAG) |
873 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
874 | 0187688f | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
875 | 0187688f | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
876 | 0187688f | Edgar E. Iglesias | return;
|
877 | 0187688f | Edgar E. Iglesias | } |
878 | 0187688f | Edgar E. Iglesias | |
879 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("s%d%s\n", size, dc->type_b ? "i" : ""); |
880 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
881 | 4acb54ba | Edgar E. Iglesias | /* If we get a fault on a dslot, the jmpstate better be in sync. */
|
882 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
883 | 4acb54ba | Edgar E. Iglesias | addr = compute_ldst_addr(dc, &t); |
884 | 968a40f6 | Edgar E. Iglesias | |
885 | a12f6507 | Edgar E. Iglesias | gen_store(dc, *addr, cpu_R[dc->rd], size); |
886 | a12f6507 | Edgar E. Iglesias | |
887 | 968a40f6 | Edgar E. Iglesias | /* Verify alignment if needed. */
|
888 | 968a40f6 | Edgar E. Iglesias | if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) { |
889 | a12f6507 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); |
890 | a12f6507 | Edgar E. Iglesias | /* FIXME: if the alignment is wrong, we should restore the value
|
891 | a12f6507 | Edgar E. Iglesias | * in memory.
|
892 | a12f6507 | Edgar E. Iglesias | */
|
893 | 968a40f6 | Edgar E. Iglesias | gen_helper_memalign(*addr, tcg_const_tl(dc->rd), |
894 | 3aa80988 | Edgar E. Iglesias | tcg_const_tl(1), tcg_const_tl(size - 1)); |
895 | 968a40f6 | Edgar E. Iglesias | } |
896 | 968a40f6 | Edgar E. Iglesias | |
897 | 4acb54ba | Edgar E. Iglesias | if (addr == &t)
|
898 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
899 | 4acb54ba | Edgar E. Iglesias | } |
900 | 4acb54ba | Edgar E. Iglesias | |
901 | 4acb54ba | Edgar E. Iglesias | static inline void eval_cc(DisasContext *dc, unsigned int cc, |
902 | 4acb54ba | Edgar E. Iglesias | TCGv d, TCGv a, TCGv b) |
903 | 4acb54ba | Edgar E. Iglesias | { |
904 | 4acb54ba | Edgar E. Iglesias | int l1;
|
905 | 4acb54ba | Edgar E. Iglesias | |
906 | 4acb54ba | Edgar E. Iglesias | switch (cc) {
|
907 | 4acb54ba | Edgar E. Iglesias | case CC_EQ:
|
908 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
909 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
910 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_EQ, a, b, l1); |
911 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
912 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
913 | 4acb54ba | Edgar E. Iglesias | break;
|
914 | 4acb54ba | Edgar E. Iglesias | case CC_NE:
|
915 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
916 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
917 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_NE, a, b, l1); |
918 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
919 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
920 | 4acb54ba | Edgar E. Iglesias | break;
|
921 | 4acb54ba | Edgar E. Iglesias | case CC_LT:
|
922 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
923 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
924 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_LT, a, b, l1); |
925 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
926 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
927 | 4acb54ba | Edgar E. Iglesias | break;
|
928 | 4acb54ba | Edgar E. Iglesias | case CC_LE:
|
929 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
930 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
931 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_LE, a, b, l1); |
932 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
933 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
934 | 4acb54ba | Edgar E. Iglesias | break;
|
935 | 4acb54ba | Edgar E. Iglesias | case CC_GE:
|
936 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
937 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
938 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_GE, a, b, l1); |
939 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
940 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
941 | 4acb54ba | Edgar E. Iglesias | break;
|
942 | 4acb54ba | Edgar E. Iglesias | case CC_GT:
|
943 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
944 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
945 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_GT, a, b, l1); |
946 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
947 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
948 | 4acb54ba | Edgar E. Iglesias | break;
|
949 | 4acb54ba | Edgar E. Iglesias | default:
|
950 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Unknown condition code %x.\n", cc);
|
951 | 4acb54ba | Edgar E. Iglesias | break;
|
952 | 4acb54ba | Edgar E. Iglesias | } |
953 | 4acb54ba | Edgar E. Iglesias | } |
954 | 4acb54ba | Edgar E. Iglesias | |
955 | 4acb54ba | Edgar E. Iglesias | static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false) |
956 | 4acb54ba | Edgar E. Iglesias | { |
957 | 4acb54ba | Edgar E. Iglesias | int l1;
|
958 | 4acb54ba | Edgar E. Iglesias | |
959 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
960 | 4acb54ba | Edgar E. Iglesias | /* Conditional jmp. */
|
961 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false); |
962 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
|
963 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true); |
964 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
965 | 4acb54ba | Edgar E. Iglesias | } |
966 | 4acb54ba | Edgar E. Iglesias | |
967 | 4acb54ba | Edgar E. Iglesias | static void dec_bcc(DisasContext *dc) |
968 | 4acb54ba | Edgar E. Iglesias | { |
969 | 4acb54ba | Edgar E. Iglesias | unsigned int cc; |
970 | 4acb54ba | Edgar E. Iglesias | unsigned int dslot; |
971 | 4acb54ba | Edgar E. Iglesias | |
972 | 4acb54ba | Edgar E. Iglesias | cc = EXTRACT_FIELD(dc->ir, 21, 23); |
973 | 4acb54ba | Edgar E. Iglesias | dslot = dc->ir & (1 << 25); |
974 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm); |
975 | 4acb54ba | Edgar E. Iglesias | |
976 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 1;
|
977 | 4acb54ba | Edgar E. Iglesias | if (dslot) {
|
978 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
979 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
980 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
981 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
982 | 4acb54ba | Edgar E. Iglesias | } |
983 | 4acb54ba | Edgar E. Iglesias | |
984 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->pc); |
985 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc))); |
986 | 4acb54ba | Edgar E. Iglesias | eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
|
987 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
988 | 4acb54ba | Edgar E. Iglesias | } |
989 | 4acb54ba | Edgar E. Iglesias | |
990 | 4acb54ba | Edgar E. Iglesias | static void dec_br(DisasContext *dc) |
991 | 4acb54ba | Edgar E. Iglesias | { |
992 | 4acb54ba | Edgar E. Iglesias | unsigned int dslot, link, abs; |
993 | 4acb54ba | Edgar E. Iglesias | |
994 | 4acb54ba | Edgar E. Iglesias | dslot = dc->ir & (1 << 20); |
995 | 4acb54ba | Edgar E. Iglesias | abs = dc->ir & (1 << 19); |
996 | 4acb54ba | Edgar E. Iglesias | link = dc->ir & (1 << 18); |
997 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("br%s%s%s%s imm=%x\n",
|
998 | 4acb54ba | Edgar E. Iglesias | abs ? "a" : "", link ? "l" : "", |
999 | 4acb54ba | Edgar E. Iglesias | dc->type_b ? "i" : "", dslot ? "d" : "", |
1000 | 4acb54ba | Edgar E. Iglesias | dc->imm); |
1001 | 4acb54ba | Edgar E. Iglesias | |
1002 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 1;
|
1003 | 4acb54ba | Edgar E. Iglesias | if (dslot) {
|
1004 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
1005 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
1006 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
1007 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
1008 | 4acb54ba | Edgar E. Iglesias | } |
1009 | 4acb54ba | Edgar E. Iglesias | if (link && dc->rd)
|
1010 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc); |
1011 | 4acb54ba | Edgar E. Iglesias | |
1012 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
1013 | 4acb54ba | Edgar E. Iglesias | if (abs) {
|
1014 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
1015 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc))); |
1016 | 4acb54ba | Edgar E. Iglesias | if (link && !(dc->tb_flags & IMM_FLAG)
|
1017 | 4acb54ba | Edgar E. Iglesias | && (dc->imm == 8 || dc->imm == 0x18)) |
1018 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_BREAK); |
1019 | 4acb54ba | Edgar E. Iglesias | if (dc->imm == 0) |
1020 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
1021 | 4acb54ba | Edgar E. Iglesias | } else {
|
1022 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & IMM_FLAG) {
|
1023 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
1024 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->pc); |
1025 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc))); |
1026 | 4acb54ba | Edgar E. Iglesias | } else {
|
1027 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_DIRECT; |
1028 | 4acb54ba | Edgar E. Iglesias | dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm); |
1029 | 4acb54ba | Edgar E. Iglesias | } |
1030 | 4acb54ba | Edgar E. Iglesias | } |
1031 | 4acb54ba | Edgar E. Iglesias | } |
1032 | 4acb54ba | Edgar E. Iglesias | |
1033 | 4acb54ba | Edgar E. Iglesias | static inline void do_rti(DisasContext *dc) |
1034 | 4acb54ba | Edgar E. Iglesias | { |
1035 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
1036 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
1037 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
1038 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
|
1039 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE); |
1040 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
1041 | 4acb54ba | Edgar E. Iglesias | |
1042 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
1043 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
1044 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
1045 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
1046 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
1047 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTI_FLAG; |
1048 | 4acb54ba | Edgar E. Iglesias | } |
1049 | 4acb54ba | Edgar E. Iglesias | |
1050 | 4acb54ba | Edgar E. Iglesias | static inline void do_rtb(DisasContext *dc) |
1051 | 4acb54ba | Edgar E. Iglesias | { |
1052 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
1053 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
1054 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
1055 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP); |
1056 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, t1, 1);
|
1057 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
1058 | 4acb54ba | Edgar E. Iglesias | |
1059 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
1060 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
1061 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
1062 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
1063 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
1064 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTB_FLAG; |
1065 | 4acb54ba | Edgar E. Iglesias | } |
1066 | 4acb54ba | Edgar E. Iglesias | |
1067 | 4acb54ba | Edgar E. Iglesias | static inline void do_rte(DisasContext *dc) |
1068 | 4acb54ba | Edgar E. Iglesias | { |
1069 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
1070 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
1071 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
1072 | 4acb54ba | Edgar E. Iglesias | |
1073 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE); |
1074 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~MSR_EIP); |
1075 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, t1, 1);
|
1076 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
1077 | 4acb54ba | Edgar E. Iglesias | |
1078 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
1079 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
1080 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
1081 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
1082 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
1083 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTE_FLAG; |
1084 | 4acb54ba | Edgar E. Iglesias | } |
1085 | 4acb54ba | Edgar E. Iglesias | |
1086 | 4acb54ba | Edgar E. Iglesias | static void dec_rts(DisasContext *dc) |
1087 | 4acb54ba | Edgar E. Iglesias | { |
1088 | 4acb54ba | Edgar E. Iglesias | unsigned int b_bit, i_bit, e_bit; |
1089 | 1567a005 | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
1090 | 4acb54ba | Edgar E. Iglesias | |
1091 | 4acb54ba | Edgar E. Iglesias | i_bit = dc->ir & (1 << 21); |
1092 | 4acb54ba | Edgar E. Iglesias | b_bit = dc->ir & (1 << 22); |
1093 | 4acb54ba | Edgar E. Iglesias | e_bit = dc->ir & (1 << 23); |
1094 | 4acb54ba | Edgar E. Iglesias | |
1095 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
1096 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
1097 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
1098 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
1099 | 4acb54ba | Edgar E. Iglesias | |
1100 | 4acb54ba | Edgar E. Iglesias | if (i_bit) {
|
1101 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rtid ir=%x\n", dc->ir);
|
1102 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1103 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
1104 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
1105 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1106 | 1567a005 | Edgar E. Iglesias | } |
1107 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTI_FLAG; |
1108 | 4acb54ba | Edgar E. Iglesias | } else if (b_bit) { |
1109 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rtbd ir=%x\n", dc->ir);
|
1110 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1111 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
1112 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
1113 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1114 | 1567a005 | Edgar E. Iglesias | } |
1115 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTB_FLAG; |
1116 | 4acb54ba | Edgar E. Iglesias | } else if (e_bit) { |
1117 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rted ir=%x\n", dc->ir);
|
1118 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1119 | 1567a005 | Edgar E. Iglesias | && mem_index == MMU_USER_IDX) { |
1120 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); |
1121 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1122 | 1567a005 | Edgar E. Iglesias | } |
1123 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTE_FLAG; |
1124 | 4acb54ba | Edgar E. Iglesias | } else
|
1125 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rts ir=%x\n", dc->ir);
|
1126 | 4acb54ba | Edgar E. Iglesias | |
1127 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
1128 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
1129 | 4acb54ba | Edgar E. Iglesias | } |
1130 | 4acb54ba | Edgar E. Iglesias | |
1131 | 1567a005 | Edgar E. Iglesias | static void dec_fpu(DisasContext *dc) |
1132 | 1567a005 | Edgar E. Iglesias | { |
1133 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1134 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
1135 | 1567a005 | Edgar E. Iglesias | && !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) {
|
1136 | 97f90cbf | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU); |
1137 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1138 | 1567a005 | Edgar E. Iglesias | return;
|
1139 | 1567a005 | Edgar E. Iglesias | } |
1140 | 1567a005 | Edgar E. Iglesias | |
1141 | 1567a005 | Edgar E. Iglesias | qemu_log ("unimplemented FPU insn pc=%x opc=%x\n", dc->pc, dc->opcode);
|
1142 | 1567a005 | Edgar E. Iglesias | dc->abort_at_next_insn = 1;
|
1143 | 1567a005 | Edgar E. Iglesias | } |
1144 | 1567a005 | Edgar E. Iglesias | |
1145 | 4acb54ba | Edgar E. Iglesias | static void dec_null(DisasContext *dc) |
1146 | 4acb54ba | Edgar E. Iglesias | { |
1147 | 02b33596 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1148 | 02b33596 | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
|
1149 | 02b33596 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
1150 | 02b33596 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1151 | 02b33596 | Edgar E. Iglesias | return;
|
1152 | 02b33596 | Edgar E. Iglesias | } |
1153 | 4acb54ba | Edgar E. Iglesias | qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
|
1154 | 4acb54ba | Edgar E. Iglesias | dc->abort_at_next_insn = 1;
|
1155 | 4acb54ba | Edgar E. Iglesias | } |
1156 | 4acb54ba | Edgar E. Iglesias | |
1157 | 4acb54ba | Edgar E. Iglesias | static struct decoder_info { |
1158 | 4acb54ba | Edgar E. Iglesias | struct {
|
1159 | 4acb54ba | Edgar E. Iglesias | uint32_t bits; |
1160 | 4acb54ba | Edgar E. Iglesias | uint32_t mask; |
1161 | 4acb54ba | Edgar E. Iglesias | }; |
1162 | 4acb54ba | Edgar E. Iglesias | void (*dec)(DisasContext *dc);
|
1163 | 4acb54ba | Edgar E. Iglesias | } decinfo[] = { |
1164 | 4acb54ba | Edgar E. Iglesias | {DEC_ADD, dec_add}, |
1165 | 4acb54ba | Edgar E. Iglesias | {DEC_SUB, dec_sub}, |
1166 | 4acb54ba | Edgar E. Iglesias | {DEC_AND, dec_and}, |
1167 | 4acb54ba | Edgar E. Iglesias | {DEC_XOR, dec_xor}, |
1168 | 4acb54ba | Edgar E. Iglesias | {DEC_OR, dec_or}, |
1169 | 4acb54ba | Edgar E. Iglesias | {DEC_BIT, dec_bit}, |
1170 | 4acb54ba | Edgar E. Iglesias | {DEC_BARREL, dec_barrel}, |
1171 | 4acb54ba | Edgar E. Iglesias | {DEC_LD, dec_load}, |
1172 | 4acb54ba | Edgar E. Iglesias | {DEC_ST, dec_store}, |
1173 | 4acb54ba | Edgar E. Iglesias | {DEC_IMM, dec_imm}, |
1174 | 4acb54ba | Edgar E. Iglesias | {DEC_BR, dec_br}, |
1175 | 4acb54ba | Edgar E. Iglesias | {DEC_BCC, dec_bcc}, |
1176 | 4acb54ba | Edgar E. Iglesias | {DEC_RTS, dec_rts}, |
1177 | 1567a005 | Edgar E. Iglesias | {DEC_FPU, dec_fpu}, |
1178 | 4acb54ba | Edgar E. Iglesias | {DEC_MUL, dec_mul}, |
1179 | 4acb54ba | Edgar E. Iglesias | {DEC_DIV, dec_div}, |
1180 | 4acb54ba | Edgar E. Iglesias | {DEC_MSR, dec_msr}, |
1181 | 4acb54ba | Edgar E. Iglesias | {{0, 0}, dec_null} |
1182 | 4acb54ba | Edgar E. Iglesias | }; |
1183 | 4acb54ba | Edgar E. Iglesias | |
1184 | 4acb54ba | Edgar E. Iglesias | static inline void decode(DisasContext *dc) |
1185 | 4acb54ba | Edgar E. Iglesias | { |
1186 | 4acb54ba | Edgar E. Iglesias | uint32_t ir; |
1187 | 4acb54ba | Edgar E. Iglesias | int i;
|
1188 | 4acb54ba | Edgar E. Iglesias | |
1189 | 4acb54ba | Edgar E. Iglesias | if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
|
1190 | 4acb54ba | Edgar E. Iglesias | tcg_gen_debug_insn_start(dc->pc); |
1191 | 4acb54ba | Edgar E. Iglesias | |
1192 | 4acb54ba | Edgar E. Iglesias | dc->ir = ir = ldl_code(dc->pc); |
1193 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("%8.8x\t", dc->ir);
|
1194 | 4acb54ba | Edgar E. Iglesias | |
1195 | 4acb54ba | Edgar E. Iglesias | if (dc->ir)
|
1196 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops = 0;
|
1197 | 4acb54ba | Edgar E. Iglesias | else {
|
1198 | 1567a005 | Edgar E. Iglesias | if ((dc->tb_flags & MSR_EE_FLAG)
|
1199 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
|
1200 | 97f90cbf | Edgar E. Iglesias | && (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
|
1201 | 1567a005 | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); |
1202 | 1567a005 | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_HW_EXCP); |
1203 | 1567a005 | Edgar E. Iglesias | return;
|
1204 | 1567a005 | Edgar E. Iglesias | } |
1205 | 1567a005 | Edgar E. Iglesias | |
1206 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("nr_nops=%d\t", dc->nr_nops);
|
1207 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops++; |
1208 | 4acb54ba | Edgar E. Iglesias | if (dc->nr_nops > 4) |
1209 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "fetching nop sequence\n");
|
1210 | 4acb54ba | Edgar E. Iglesias | } |
1211 | 4acb54ba | Edgar E. Iglesias | /* bit 2 seems to indicate insn type. */
|
1212 | 4acb54ba | Edgar E. Iglesias | dc->type_b = ir & (1 << 29); |
1213 | 4acb54ba | Edgar E. Iglesias | |
1214 | 4acb54ba | Edgar E. Iglesias | dc->opcode = EXTRACT_FIELD(ir, 26, 31); |
1215 | 4acb54ba | Edgar E. Iglesias | dc->rd = EXTRACT_FIELD(ir, 21, 25); |
1216 | 4acb54ba | Edgar E. Iglesias | dc->ra = EXTRACT_FIELD(ir, 16, 20); |
1217 | 4acb54ba | Edgar E. Iglesias | dc->rb = EXTRACT_FIELD(ir, 11, 15); |
1218 | 4acb54ba | Edgar E. Iglesias | dc->imm = EXTRACT_FIELD(ir, 0, 15); |
1219 | 4acb54ba | Edgar E. Iglesias | |
1220 | 4acb54ba | Edgar E. Iglesias | /* Large switch for all insns. */
|
1221 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(decinfo); i++) { |
1222 | 4acb54ba | Edgar E. Iglesias | if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
|
1223 | 4acb54ba | Edgar E. Iglesias | decinfo[i].dec(dc); |
1224 | 4acb54ba | Edgar E. Iglesias | break;
|
1225 | 4acb54ba | Edgar E. Iglesias | } |
1226 | 4acb54ba | Edgar E. Iglesias | } |
1227 | 4acb54ba | Edgar E. Iglesias | } |
1228 | 4acb54ba | Edgar E. Iglesias | |
1229 | 4acb54ba | Edgar E. Iglesias | static void check_breakpoint(CPUState *env, DisasContext *dc) |
1230 | 4acb54ba | Edgar E. Iglesias | { |
1231 | 4acb54ba | Edgar E. Iglesias | CPUBreakpoint *bp; |
1232 | 4acb54ba | Edgar E. Iglesias | |
1233 | 72cf2d4f | Blue Swirl | if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
|
1234 | 72cf2d4f | Blue Swirl | QTAILQ_FOREACH(bp, &env->breakpoints, entry) { |
1235 | 4acb54ba | Edgar E. Iglesias | if (bp->pc == dc->pc) {
|
1236 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
1237 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1238 | 4acb54ba | Edgar E. Iglesias | } |
1239 | 4acb54ba | Edgar E. Iglesias | } |
1240 | 4acb54ba | Edgar E. Iglesias | } |
1241 | 4acb54ba | Edgar E. Iglesias | } |
1242 | 4acb54ba | Edgar E. Iglesias | |
1243 | 4acb54ba | Edgar E. Iglesias | /* generate intermediate code for basic block 'tb'. */
|
1244 | 4acb54ba | Edgar E. Iglesias | static void |
1245 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
1246 | 4acb54ba | Edgar E. Iglesias | int search_pc)
|
1247 | 4acb54ba | Edgar E. Iglesias | { |
1248 | 4acb54ba | Edgar E. Iglesias | uint16_t *gen_opc_end; |
1249 | 4acb54ba | Edgar E. Iglesias | uint32_t pc_start; |
1250 | 4acb54ba | Edgar E. Iglesias | int j, lj;
|
1251 | 4acb54ba | Edgar E. Iglesias | struct DisasContext ctx;
|
1252 | 4acb54ba | Edgar E. Iglesias | struct DisasContext *dc = &ctx;
|
1253 | 4acb54ba | Edgar E. Iglesias | uint32_t next_page_start, org_flags; |
1254 | 4acb54ba | Edgar E. Iglesias | target_ulong npc; |
1255 | 4acb54ba | Edgar E. Iglesias | int num_insns;
|
1256 | 4acb54ba | Edgar E. Iglesias | int max_insns;
|
1257 | 4acb54ba | Edgar E. Iglesias | |
1258 | 4acb54ba | Edgar E. Iglesias | qemu_log_try_set_file(stderr); |
1259 | 4acb54ba | Edgar E. Iglesias | |
1260 | 4acb54ba | Edgar E. Iglesias | pc_start = tb->pc; |
1261 | 4acb54ba | Edgar E. Iglesias | dc->env = env; |
1262 | 4acb54ba | Edgar E. Iglesias | dc->tb = tb; |
1263 | 4acb54ba | Edgar E. Iglesias | org_flags = dc->synced_flags = dc->tb_flags = tb->flags; |
1264 | 4acb54ba | Edgar E. Iglesias | |
1265 | 4acb54ba | Edgar E. Iglesias | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
1266 | 4acb54ba | Edgar E. Iglesias | |
1267 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_NEXT; |
1268 | 4acb54ba | Edgar E. Iglesias | dc->jmp = 0;
|
1269 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = !!(dc->tb_flags & D_FLAG); |
1270 | 4acb54ba | Edgar E. Iglesias | dc->ppc = pc_start; |
1271 | 4acb54ba | Edgar E. Iglesias | dc->pc = pc_start; |
1272 | 4acb54ba | Edgar E. Iglesias | dc->cache_pc = -1;
|
1273 | 4acb54ba | Edgar E. Iglesias | dc->singlestep_enabled = env->singlestep_enabled; |
1274 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 0;
|
1275 | 4acb54ba | Edgar E. Iglesias | dc->abort_at_next_insn = 0;
|
1276 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops = 0;
|
1277 | 4acb54ba | Edgar E. Iglesias | |
1278 | 4acb54ba | Edgar E. Iglesias | if (pc_start & 3) |
1279 | 4acb54ba | Edgar E. Iglesias | cpu_abort(env, "Microblaze: unaligned PC=%x\n", pc_start);
|
1280 | 4acb54ba | Edgar E. Iglesias | |
1281 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1282 | 4acb54ba | Edgar E. Iglesias | #if !SIM_COMPAT
|
1283 | 4acb54ba | Edgar E. Iglesias | qemu_log("--------------\n");
|
1284 | 4acb54ba | Edgar E. Iglesias | log_cpu_state(env, 0);
|
1285 | 4acb54ba | Edgar E. Iglesias | #endif
|
1286 | 4acb54ba | Edgar E. Iglesias | } |
1287 | 4acb54ba | Edgar E. Iglesias | |
1288 | 4acb54ba | Edgar E. Iglesias | next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; |
1289 | 4acb54ba | Edgar E. Iglesias | lj = -1;
|
1290 | 4acb54ba | Edgar E. Iglesias | num_insns = 0;
|
1291 | 4acb54ba | Edgar E. Iglesias | max_insns = tb->cflags & CF_COUNT_MASK; |
1292 | 4acb54ba | Edgar E. Iglesias | if (max_insns == 0) |
1293 | 4acb54ba | Edgar E. Iglesias | max_insns = CF_COUNT_MASK; |
1294 | 4acb54ba | Edgar E. Iglesias | |
1295 | 4acb54ba | Edgar E. Iglesias | gen_icount_start(); |
1296 | 4acb54ba | Edgar E. Iglesias | do
|
1297 | 4acb54ba | Edgar E. Iglesias | { |
1298 | 4acb54ba | Edgar E. Iglesias | #if SIM_COMPAT
|
1299 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1300 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); |
1301 | 4acb54ba | Edgar E. Iglesias | gen_helper_debug(); |
1302 | 4acb54ba | Edgar E. Iglesias | } |
1303 | 4acb54ba | Edgar E. Iglesias | #endif
|
1304 | 4acb54ba | Edgar E. Iglesias | check_breakpoint(env, dc); |
1305 | 4acb54ba | Edgar E. Iglesias | |
1306 | 4acb54ba | Edgar E. Iglesias | if (search_pc) {
|
1307 | 4acb54ba | Edgar E. Iglesias | j = gen_opc_ptr - gen_opc_buf; |
1308 | 4acb54ba | Edgar E. Iglesias | if (lj < j) {
|
1309 | 4acb54ba | Edgar E. Iglesias | lj++; |
1310 | 4acb54ba | Edgar E. Iglesias | while (lj < j)
|
1311 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj++] = 0;
|
1312 | 4acb54ba | Edgar E. Iglesias | } |
1313 | 4acb54ba | Edgar E. Iglesias | gen_opc_pc[lj] = dc->pc; |
1314 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj] = 1;
|
1315 | 4acb54ba | Edgar E. Iglesias | gen_opc_icount[lj] = num_insns; |
1316 | 4acb54ba | Edgar E. Iglesias | } |
1317 | 4acb54ba | Edgar E. Iglesias | |
1318 | 4acb54ba | Edgar E. Iglesias | /* Pretty disas. */
|
1319 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("%8.8x:\t", dc->pc);
|
1320 | 4acb54ba | Edgar E. Iglesias | |
1321 | 4acb54ba | Edgar E. Iglesias | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
1322 | 4acb54ba | Edgar E. Iglesias | gen_io_start(); |
1323 | 4acb54ba | Edgar E. Iglesias | |
1324 | 4acb54ba | Edgar E. Iglesias | dc->clear_imm = 1;
|
1325 | 4acb54ba | Edgar E. Iglesias | decode(dc); |
1326 | 4acb54ba | Edgar E. Iglesias | if (dc->clear_imm)
|
1327 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~IMM_FLAG; |
1328 | 4acb54ba | Edgar E. Iglesias | dc->ppc = dc->pc; |
1329 | 4acb54ba | Edgar E. Iglesias | dc->pc += 4;
|
1330 | 4acb54ba | Edgar E. Iglesias | num_insns++; |
1331 | 4acb54ba | Edgar E. Iglesias | |
1332 | 4acb54ba | Edgar E. Iglesias | if (dc->delayed_branch) {
|
1333 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch--; |
1334 | 4acb54ba | Edgar E. Iglesias | if (!dc->delayed_branch) {
|
1335 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTI_FLAG)
|
1336 | 4acb54ba | Edgar E. Iglesias | do_rti(dc); |
1337 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTB_FLAG)
|
1338 | 4acb54ba | Edgar E. Iglesias | do_rtb(dc); |
1339 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTE_FLAG)
|
1340 | 4acb54ba | Edgar E. Iglesias | do_rte(dc); |
1341 | 4acb54ba | Edgar E. Iglesias | /* Clear the delay slot flag. */
|
1342 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~D_FLAG; |
1343 | 4acb54ba | Edgar E. Iglesias | /* If it is a direct jump, try direct chaining. */
|
1344 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp != JMP_DIRECT) {
|
1345 | 4acb54ba | Edgar E. Iglesias | eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc)); |
1346 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_JUMP; |
1347 | 4acb54ba | Edgar E. Iglesias | } |
1348 | 4acb54ba | Edgar E. Iglesias | break;
|
1349 | 4acb54ba | Edgar E. Iglesias | } |
1350 | 4acb54ba | Edgar E. Iglesias | } |
1351 | 4acb54ba | Edgar E. Iglesias | if (env->singlestep_enabled)
|
1352 | 4acb54ba | Edgar E. Iglesias | break;
|
1353 | 4acb54ba | Edgar E. Iglesias | } while (!dc->is_jmp && !dc->cpustate_changed
|
1354 | 4acb54ba | Edgar E. Iglesias | && gen_opc_ptr < gen_opc_end |
1355 | 4acb54ba | Edgar E. Iglesias | && !singlestep |
1356 | 4acb54ba | Edgar E. Iglesias | && (dc->pc < next_page_start) |
1357 | 4acb54ba | Edgar E. Iglesias | && num_insns < max_insns); |
1358 | 4acb54ba | Edgar E. Iglesias | |
1359 | 4acb54ba | Edgar E. Iglesias | npc = dc->pc; |
1360 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp == JMP_DIRECT) {
|
1361 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & D_FLAG) {
|
1362 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1363 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1364 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
1365 | 4acb54ba | Edgar E. Iglesias | } else
|
1366 | 4acb54ba | Edgar E. Iglesias | npc = dc->jmp_pc; |
1367 | 4acb54ba | Edgar E. Iglesias | } |
1368 | 4acb54ba | Edgar E. Iglesias | |
1369 | 4acb54ba | Edgar E. Iglesias | if (tb->cflags & CF_LAST_IO)
|
1370 | 4acb54ba | Edgar E. Iglesias | gen_io_end(); |
1371 | 4acb54ba | Edgar E. Iglesias | /* Force an update if the per-tb cpu state has changed. */
|
1372 | 4acb54ba | Edgar E. Iglesias | if (dc->is_jmp == DISAS_NEXT
|
1373 | 4acb54ba | Edgar E. Iglesias | && (dc->cpustate_changed || org_flags != dc->tb_flags)) { |
1374 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1375 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1376 | 4acb54ba | Edgar E. Iglesias | } |
1377 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
1378 | 4acb54ba | Edgar E. Iglesias | |
1379 | 4acb54ba | Edgar E. Iglesias | if (unlikely(env->singlestep_enabled)) {
|
1380 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
1381 | 4acb54ba | Edgar E. Iglesias | if (dc->is_jmp == DISAS_NEXT)
|
1382 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1383 | 4acb54ba | Edgar E. Iglesias | } else {
|
1384 | 4acb54ba | Edgar E. Iglesias | switch(dc->is_jmp) {
|
1385 | 4acb54ba | Edgar E. Iglesias | case DISAS_NEXT:
|
1386 | 4acb54ba | Edgar E. Iglesias | gen_goto_tb(dc, 1, npc);
|
1387 | 4acb54ba | Edgar E. Iglesias | break;
|
1388 | 4acb54ba | Edgar E. Iglesias | default:
|
1389 | 4acb54ba | Edgar E. Iglesias | case DISAS_JUMP:
|
1390 | 4acb54ba | Edgar E. Iglesias | case DISAS_UPDATE:
|
1391 | 4acb54ba | Edgar E. Iglesias | /* indicate that the hash table must be used
|
1392 | 4acb54ba | Edgar E. Iglesias | to find the next TB */
|
1393 | 4acb54ba | Edgar E. Iglesias | tcg_gen_exit_tb(0);
|
1394 | 4acb54ba | Edgar E. Iglesias | break;
|
1395 | 4acb54ba | Edgar E. Iglesias | case DISAS_TB_JUMP:
|
1396 | 4acb54ba | Edgar E. Iglesias | /* nothing more to generate */
|
1397 | 4acb54ba | Edgar E. Iglesias | break;
|
1398 | 4acb54ba | Edgar E. Iglesias | } |
1399 | 4acb54ba | Edgar E. Iglesias | } |
1400 | 4acb54ba | Edgar E. Iglesias | gen_icount_end(tb, num_insns); |
1401 | 4acb54ba | Edgar E. Iglesias | *gen_opc_ptr = INDEX_op_end; |
1402 | 4acb54ba | Edgar E. Iglesias | if (search_pc) {
|
1403 | 4acb54ba | Edgar E. Iglesias | j = gen_opc_ptr - gen_opc_buf; |
1404 | 4acb54ba | Edgar E. Iglesias | lj++; |
1405 | 4acb54ba | Edgar E. Iglesias | while (lj <= j)
|
1406 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj++] = 0;
|
1407 | 4acb54ba | Edgar E. Iglesias | } else {
|
1408 | 4acb54ba | Edgar E. Iglesias | tb->size = dc->pc - pc_start; |
1409 | 4acb54ba | Edgar E. Iglesias | tb->icount = num_insns; |
1410 | 4acb54ba | Edgar E. Iglesias | } |
1411 | 4acb54ba | Edgar E. Iglesias | |
1412 | 4acb54ba | Edgar E. Iglesias | #ifdef DEBUG_DISAS
|
1413 | 4acb54ba | Edgar E. Iglesias | #if !SIM_COMPAT
|
1414 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1415 | 4acb54ba | Edgar E. Iglesias | qemu_log("\n");
|
1416 | 4acb54ba | Edgar E. Iglesias | #if DISAS_GNU
|
1417 | 4acb54ba | Edgar E. Iglesias | log_target_disas(pc_start, dc->pc - pc_start, 0);
|
1418 | 4acb54ba | Edgar E. Iglesias | #endif
|
1419 | 4acb54ba | Edgar E. Iglesias | qemu_log("\nisize=%d osize=%zd\n",
|
1420 | 4acb54ba | Edgar E. Iglesias | dc->pc - pc_start, gen_opc_ptr - gen_opc_buf); |
1421 | 4acb54ba | Edgar E. Iglesias | } |
1422 | 4acb54ba | Edgar E. Iglesias | #endif
|
1423 | 4acb54ba | Edgar E. Iglesias | #endif
|
1424 | 4acb54ba | Edgar E. Iglesias | assert(!dc->abort_at_next_insn); |
1425 | 4acb54ba | Edgar E. Iglesias | } |
1426 | 4acb54ba | Edgar E. Iglesias | |
1427 | 4acb54ba | Edgar E. Iglesias | void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) |
1428 | 4acb54ba | Edgar E. Iglesias | { |
1429 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(env, tb, 0);
|
1430 | 4acb54ba | Edgar E. Iglesias | } |
1431 | 4acb54ba | Edgar E. Iglesias | |
1432 | 4acb54ba | Edgar E. Iglesias | void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) |
1433 | 4acb54ba | Edgar E. Iglesias | { |
1434 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(env, tb, 1);
|
1435 | 4acb54ba | Edgar E. Iglesias | } |
1436 | 4acb54ba | Edgar E. Iglesias | |
1437 | 4acb54ba | Edgar E. Iglesias | void cpu_dump_state (CPUState *env, FILE *f,
|
1438 | 4acb54ba | Edgar E. Iglesias | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), |
1439 | 4acb54ba | Edgar E. Iglesias | int flags)
|
1440 | 4acb54ba | Edgar E. Iglesias | { |
1441 | 4acb54ba | Edgar E. Iglesias | int i;
|
1442 | 4acb54ba | Edgar E. Iglesias | |
1443 | 4acb54ba | Edgar E. Iglesias | if (!env || !f)
|
1444 | 4acb54ba | Edgar E. Iglesias | return;
|
1445 | 4acb54ba | Edgar E. Iglesias | |
1446 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "IN: PC=%x %s\n",
|
1447 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC])); |
1448 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "rmsr=%x resr=%x debug[%x] imm=%x iflags=%x\n",
|
1449 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_MSR], env->sregs[SR_ESR], |
1450 | 4acb54ba | Edgar E. Iglesias | env->debug, env->imm, env->iflags); |
1451 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s)\n",
|
1452 | 4acb54ba | Edgar E. Iglesias | env->btaken, env->btarget, |
1453 | 4acb54ba | Edgar E. Iglesias | (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel", |
1454 | 4acb54ba | Edgar E. Iglesias | (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel"); |
1455 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < 32; i++) { |
1456 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
|
1457 | 4acb54ba | Edgar E. Iglesias | if ((i + 1) % 4 == 0) |
1458 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "\n");
|
1459 | 4acb54ba | Edgar E. Iglesias | } |
1460 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "\n\n");
|
1461 | 4acb54ba | Edgar E. Iglesias | } |
1462 | 4acb54ba | Edgar E. Iglesias | |
1463 | 4acb54ba | Edgar E. Iglesias | CPUState *cpu_mb_init (const char *cpu_model) |
1464 | 4acb54ba | Edgar E. Iglesias | { |
1465 | 4acb54ba | Edgar E. Iglesias | CPUState *env; |
1466 | 4acb54ba | Edgar E. Iglesias | static int tcg_initialized = 0; |
1467 | 4acb54ba | Edgar E. Iglesias | int i;
|
1468 | 4acb54ba | Edgar E. Iglesias | |
1469 | 4acb54ba | Edgar E. Iglesias | env = qemu_mallocz(sizeof(CPUState));
|
1470 | 4acb54ba | Edgar E. Iglesias | |
1471 | 4acb54ba | Edgar E. Iglesias | cpu_exec_init(env); |
1472 | 4acb54ba | Edgar E. Iglesias | cpu_reset(env); |
1473 | 4acb54ba | Edgar E. Iglesias | |
1474 | 4acb54ba | Edgar E. Iglesias | |
1475 | 4acb54ba | Edgar E. Iglesias | if (tcg_initialized)
|
1476 | 4acb54ba | Edgar E. Iglesias | return env;
|
1477 | 4acb54ba | Edgar E. Iglesias | |
1478 | 4acb54ba | Edgar E. Iglesias | tcg_initialized = 1;
|
1479 | 4acb54ba | Edgar E. Iglesias | |
1480 | 4acb54ba | Edgar E. Iglesias | cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
|
1481 | 4acb54ba | Edgar E. Iglesias | |
1482 | 4acb54ba | Edgar E. Iglesias | env_debug = tcg_global_mem_new(TCG_AREG0, |
1483 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, debug), |
1484 | 4acb54ba | Edgar E. Iglesias | "debug0");
|
1485 | 4acb54ba | Edgar E. Iglesias | env_iflags = tcg_global_mem_new(TCG_AREG0, |
1486 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, iflags), |
1487 | 4acb54ba | Edgar E. Iglesias | "iflags");
|
1488 | 4acb54ba | Edgar E. Iglesias | env_imm = tcg_global_mem_new(TCG_AREG0, |
1489 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, imm), |
1490 | 4acb54ba | Edgar E. Iglesias | "imm");
|
1491 | 4acb54ba | Edgar E. Iglesias | env_btarget = tcg_global_mem_new(TCG_AREG0, |
1492 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, btarget), |
1493 | 4acb54ba | Edgar E. Iglesias | "btarget");
|
1494 | 4acb54ba | Edgar E. Iglesias | env_btaken = tcg_global_mem_new(TCG_AREG0, |
1495 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, btaken), |
1496 | 4acb54ba | Edgar E. Iglesias | "btaken");
|
1497 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(cpu_R); i++) { |
1498 | 4acb54ba | Edgar E. Iglesias | cpu_R[i] = tcg_global_mem_new(TCG_AREG0, |
1499 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, regs[i]), |
1500 | 4acb54ba | Edgar E. Iglesias | regnames[i]); |
1501 | 4acb54ba | Edgar E. Iglesias | } |
1502 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) { |
1503 | 4acb54ba | Edgar E. Iglesias | cpu_SR[i] = tcg_global_mem_new(TCG_AREG0, |
1504 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, sregs[i]), |
1505 | 4acb54ba | Edgar E. Iglesias | special_regnames[i]); |
1506 | 4acb54ba | Edgar E. Iglesias | } |
1507 | 4acb54ba | Edgar E. Iglesias | #define GEN_HELPER 2 |
1508 | 4acb54ba | Edgar E. Iglesias | #include "helper.h" |
1509 | 4acb54ba | Edgar E. Iglesias | |
1510 | 4acb54ba | Edgar E. Iglesias | return env;
|
1511 | 4acb54ba | Edgar E. Iglesias | } |
1512 | 4acb54ba | Edgar E. Iglesias | |
1513 | 4acb54ba | Edgar E. Iglesias | void cpu_reset (CPUState *env)
|
1514 | 4acb54ba | Edgar E. Iglesias | { |
1515 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
1516 | 4acb54ba | Edgar E. Iglesias | qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
1517 | 4acb54ba | Edgar E. Iglesias | log_cpu_state(env, 0);
|
1518 | 4acb54ba | Edgar E. Iglesias | } |
1519 | 4acb54ba | Edgar E. Iglesias | |
1520 | 4acb54ba | Edgar E. Iglesias | memset(env, 0, offsetof(CPUMBState, breakpoints));
|
1521 | 4acb54ba | Edgar E. Iglesias | tlb_flush(env, 1);
|
1522 | 4acb54ba | Edgar E. Iglesias | |
1523 | 4898427e | Edgar E. Iglesias | env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
|
1524 | 4898427e | Edgar E. Iglesias | | PVR0_USE_BARREL_MASK \ |
1525 | 4898427e | Edgar E. Iglesias | | PVR0_USE_DIV_MASK \ |
1526 | 4898427e | Edgar E. Iglesias | | PVR0_USE_HW_MUL_MASK \ |
1527 | 4898427e | Edgar E. Iglesias | | PVR0_USE_EXC_MASK \ |
1528 | 4898427e | Edgar E. Iglesias | | PVR0_USE_ICACHE_MASK \ |
1529 | 4898427e | Edgar E. Iglesias | | PVR0_USE_DCACHE_MASK \ |
1530 | 4898427e | Edgar E. Iglesias | | PVR0_USE_MMU \ |
1531 | 4898427e | Edgar E. Iglesias | | (0xb << 8); |
1532 | 4898427e | Edgar E. Iglesias | env->pvr.regs[2] = PVR2_D_OPB_MASK \
|
1533 | 4898427e | Edgar E. Iglesias | | PVR2_D_LMB_MASK \ |
1534 | 4898427e | Edgar E. Iglesias | | PVR2_I_OPB_MASK \ |
1535 | 4898427e | Edgar E. Iglesias | | PVR2_I_LMB_MASK \ |
1536 | 4898427e | Edgar E. Iglesias | | PVR2_USE_MSR_INSTR \ |
1537 | 4898427e | Edgar E. Iglesias | | PVR2_USE_PCMP_INSTR \ |
1538 | 4898427e | Edgar E. Iglesias | | PVR2_USE_BARREL_MASK \ |
1539 | 4898427e | Edgar E. Iglesias | | PVR2_USE_DIV_MASK \ |
1540 | 4898427e | Edgar E. Iglesias | | PVR2_USE_HW_MUL_MASK \ |
1541 | 4898427e | Edgar E. Iglesias | | PVR2_USE_MUL64_MASK \ |
1542 | 4898427e | Edgar E. Iglesias | | 0;
|
1543 | 4898427e | Edgar E. Iglesias | env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family. */ |
1544 | 4898427e | Edgar E. Iglesias | env->pvr.regs[11] = PVR11_USE_MMU | (16 << 17); |
1545 | 4898427e | Edgar E. Iglesias | |
1546 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_MSR] = 0;
|
1547 | 4acb54ba | Edgar E. Iglesias | #if defined(CONFIG_USER_ONLY)
|
1548 | 4acb54ba | Edgar E. Iglesias | /* start in user mode with interrupts enabled. */
|
1549 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp. */ |
1550 | 4acb54ba | Edgar E. Iglesias | #else
|
1551 | 4acb54ba | Edgar E. Iglesias | mmu_init(&env->mmu); |
1552 | 4898427e | Edgar E. Iglesias | env->mmu.c_mmu = 3;
|
1553 | 4898427e | Edgar E. Iglesias | env->mmu.c_mmu_tlb_access = 3;
|
1554 | 4898427e | Edgar E. Iglesias | env->mmu.c_mmu_zones = 16;
|
1555 | 4acb54ba | Edgar E. Iglesias | #endif
|
1556 | 4acb54ba | Edgar E. Iglesias | } |
1557 | 4acb54ba | Edgar E. Iglesias | |
1558 | 4acb54ba | Edgar E. Iglesias | void gen_pc_load(CPUState *env, struct TranslationBlock *tb, |
1559 | 4acb54ba | Edgar E. Iglesias | unsigned long searched_pc, int pc_pos, void *puc) |
1560 | 4acb54ba | Edgar E. Iglesias | { |
1561 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_PC] = gen_opc_pc[pc_pos]; |
1562 | 4acb54ba | Edgar E. Iglesias | } |