root / target-microblaze / translate.c @ 5169202b
History | View | Annotate | Download (38.1 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 | 4acb54ba | Edgar E. Iglesias | const static 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 | 4acb54ba | Edgar E. Iglesias | const static 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 | 4acb54ba | Edgar E. Iglesias | mode = dc->opcode & 3;
|
235 | 4acb54ba | Edgar E. Iglesias | switch (mode) {
|
236 | 4acb54ba | Edgar E. Iglesias | case 0: |
237 | 4acb54ba | Edgar E. Iglesias | /* pcmpbf. */
|
238 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
239 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
240 | 4acb54ba | Edgar E. Iglesias | gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); |
241 | 4acb54ba | Edgar E. Iglesias | break;
|
242 | 4acb54ba | Edgar E. Iglesias | case 2: |
243 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
244 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
245 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_local_new(); |
246 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
247 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 1);
|
248 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_EQ, |
249 | 4acb54ba | Edgar E. Iglesias | cpu_R[dc->ra], cpu_R[dc->rb], l1); |
250 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 0);
|
251 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
252 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], t0); |
253 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
254 | 4acb54ba | Edgar E. Iglesias | } |
255 | 4acb54ba | Edgar E. Iglesias | break;
|
256 | 4acb54ba | Edgar E. Iglesias | case 3: |
257 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
258 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
259 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
260 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_local_new(); |
261 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 1);
|
262 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_NE, |
263 | 4acb54ba | Edgar E. Iglesias | cpu_R[dc->ra], cpu_R[dc->rb], l1); |
264 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(t0, 0);
|
265 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
266 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], t0); |
267 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
268 | 4acb54ba | Edgar E. Iglesias | } |
269 | 4acb54ba | Edgar E. Iglesias | break;
|
270 | 4acb54ba | Edgar E. Iglesias | default:
|
271 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, |
272 | 4acb54ba | Edgar E. Iglesias | "unsupported pattern insn opcode=%x\n", dc->opcode);
|
273 | 4acb54ba | Edgar E. Iglesias | break;
|
274 | 4acb54ba | Edgar E. Iglesias | } |
275 | 4acb54ba | Edgar E. Iglesias | } |
276 | 4acb54ba | Edgar E. Iglesias | |
277 | 4acb54ba | Edgar E. Iglesias | static void dec_and(DisasContext *dc) |
278 | 4acb54ba | Edgar E. Iglesias | { |
279 | 4acb54ba | Edgar E. Iglesias | unsigned int not; |
280 | 4acb54ba | Edgar E. Iglesias | |
281 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
282 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
283 | 4acb54ba | Edgar E. Iglesias | return;
|
284 | 4acb54ba | Edgar E. Iglesias | } |
285 | 4acb54ba | Edgar E. Iglesias | |
286 | 4acb54ba | Edgar E. Iglesias | not = dc->opcode & (1 << 1); |
287 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("and%s\n", not ? "n" : ""); |
288 | 4acb54ba | Edgar E. Iglesias | |
289 | 4acb54ba | Edgar E. Iglesias | if (!dc->rd)
|
290 | 4acb54ba | Edgar E. Iglesias | return;
|
291 | 4acb54ba | Edgar E. Iglesias | |
292 | 4acb54ba | Edgar E. Iglesias | if (not) {
|
293 | 4acb54ba | Edgar E. Iglesias | TCGv t = tcg_temp_new(); |
294 | 4acb54ba | Edgar E. Iglesias | tcg_gen_not_tl(t, *(dec_alu_op_b(dc))); |
295 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], t); |
296 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
297 | 4acb54ba | Edgar E. Iglesias | } else
|
298 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
299 | 4acb54ba | Edgar E. Iglesias | } |
300 | 4acb54ba | Edgar E. Iglesias | |
301 | 4acb54ba | Edgar E. Iglesias | static void dec_or(DisasContext *dc) |
302 | 4acb54ba | Edgar E. Iglesias | { |
303 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
304 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
305 | 4acb54ba | Edgar E. Iglesias | return;
|
306 | 4acb54ba | Edgar E. Iglesias | } |
307 | 4acb54ba | Edgar E. Iglesias | |
308 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
|
309 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
310 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
311 | 4acb54ba | Edgar E. Iglesias | } |
312 | 4acb54ba | Edgar E. Iglesias | |
313 | 4acb54ba | Edgar E. Iglesias | static void dec_xor(DisasContext *dc) |
314 | 4acb54ba | Edgar E. Iglesias | { |
315 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b && (dc->imm & (1 << 10))) { |
316 | 4acb54ba | Edgar E. Iglesias | dec_pattern(dc); |
317 | 4acb54ba | Edgar E. Iglesias | return;
|
318 | 4acb54ba | Edgar E. Iglesias | } |
319 | 4acb54ba | Edgar E. Iglesias | |
320 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("xor r%d\n", dc->rd);
|
321 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
322 | 4acb54ba | Edgar E. Iglesias | tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
323 | 4acb54ba | Edgar E. Iglesias | } |
324 | 4acb54ba | Edgar E. Iglesias | |
325 | 4acb54ba | Edgar E. Iglesias | static void read_carry(DisasContext *dc, TCGv d) |
326 | 4acb54ba | Edgar E. Iglesias | { |
327 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
|
328 | 4acb54ba | Edgar E. Iglesias | } |
329 | 4acb54ba | Edgar E. Iglesias | |
330 | 4acb54ba | Edgar E. Iglesias | static void write_carry(DisasContext *dc, TCGv v) |
331 | 4acb54ba | Edgar E. Iglesias | { |
332 | 4acb54ba | Edgar E. Iglesias | TCGv t0 = tcg_temp_new(); |
333 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shli_tl(t0, v, 31);
|
334 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sari_tl(t0, t0, 31);
|
335 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(env_debug, t0); |
336 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC)); |
337 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], |
338 | 4acb54ba | Edgar E. Iglesias | ~(MSR_C | MSR_CC)); |
339 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0); |
340 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
341 | 4acb54ba | Edgar E. Iglesias | } |
342 | 4acb54ba | Edgar E. Iglesias | |
343 | 4acb54ba | Edgar E. Iglesias | |
344 | 4acb54ba | Edgar E. Iglesias | static inline void msr_read(DisasContext *dc, TCGv d) |
345 | 4acb54ba | Edgar E. Iglesias | { |
346 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(d, cpu_SR[SR_MSR]); |
347 | 4acb54ba | Edgar E. Iglesias | } |
348 | 4acb54ba | Edgar E. Iglesias | |
349 | 4acb54ba | Edgar E. Iglesias | static inline void msr_write(DisasContext *dc, TCGv v) |
350 | 4acb54ba | Edgar E. Iglesias | { |
351 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 1;
|
352 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_MSR], v); |
353 | 4acb54ba | Edgar E. Iglesias | /* PVR, we have a processor version register. */
|
354 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10)); |
355 | 4acb54ba | Edgar E. Iglesias | } |
356 | 4acb54ba | Edgar E. Iglesias | |
357 | 4acb54ba | Edgar E. Iglesias | static void dec_msr(DisasContext *dc) |
358 | 4acb54ba | Edgar E. Iglesias | { |
359 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
360 | 4acb54ba | Edgar E. Iglesias | unsigned int sr, to, rn; |
361 | 4acb54ba | Edgar E. Iglesias | |
362 | 4acb54ba | Edgar E. Iglesias | sr = dc->imm & ((1 << 14) - 1); |
363 | 4acb54ba | Edgar E. Iglesias | to = dc->imm & (1 << 14); |
364 | 4acb54ba | Edgar E. Iglesias | dc->type_b = 1;
|
365 | 4acb54ba | Edgar E. Iglesias | if (to)
|
366 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 1;
|
367 | 4acb54ba | Edgar E. Iglesias | |
368 | 4acb54ba | Edgar E. Iglesias | /* msrclr and msrset. */
|
369 | 4acb54ba | Edgar E. Iglesias | if (!(dc->imm & (1 << 15))) { |
370 | 4acb54ba | Edgar E. Iglesias | unsigned int clr = dc->ir & (1 << 16); |
371 | 4acb54ba | Edgar E. Iglesias | |
372 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set", |
373 | 4acb54ba | Edgar E. Iglesias | dc->rd, dc->imm); |
374 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
375 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, cpu_R[dc->rd]); |
376 | 4acb54ba | Edgar E. Iglesias | |
377 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
378 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
379 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, t0); |
380 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc))); |
381 | 4acb54ba | Edgar E. Iglesias | |
382 | 4acb54ba | Edgar E. Iglesias | if (clr) {
|
383 | 4acb54ba | Edgar E. Iglesias | tcg_gen_not_tl(t1, t1); |
384 | 4acb54ba | Edgar E. Iglesias | tcg_gen_and_tl(t0, t0, t1); |
385 | 4acb54ba | Edgar E. Iglesias | } else
|
386 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t0, t0, t1); |
387 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t0); |
388 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
389 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
390 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
|
391 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
392 | 4acb54ba | Edgar E. Iglesias | return;
|
393 | 4acb54ba | Edgar E. Iglesias | } |
394 | 4acb54ba | Edgar E. Iglesias | |
395 | 4acb54ba | Edgar E. Iglesias | #if !defined(CONFIG_USER_ONLY)
|
396 | 4acb54ba | Edgar E. Iglesias | /* Catch read/writes to the mmu block. */
|
397 | 4acb54ba | Edgar E. Iglesias | if ((sr & ~0xff) == 0x1000) { |
398 | 4acb54ba | Edgar E. Iglesias | sr &= 7;
|
399 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm); |
400 | 4acb54ba | Edgar E. Iglesias | if (to)
|
401 | 4acb54ba | Edgar E. Iglesias | gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]); |
402 | 4acb54ba | Edgar E. Iglesias | else
|
403 | 4acb54ba | Edgar E. Iglesias | gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr)); |
404 | 4acb54ba | Edgar E. Iglesias | return;
|
405 | 4acb54ba | Edgar E. Iglesias | } |
406 | 4acb54ba | Edgar E. Iglesias | #endif
|
407 | 4acb54ba | Edgar E. Iglesias | |
408 | 4acb54ba | Edgar E. Iglesias | if (to) {
|
409 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm); |
410 | 4acb54ba | Edgar E. Iglesias | switch (sr) {
|
411 | 4acb54ba | Edgar E. Iglesias | case 0: |
412 | 4acb54ba | Edgar E. Iglesias | break;
|
413 | 4acb54ba | Edgar E. Iglesias | case 1: |
414 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, cpu_R[dc->ra]); |
415 | 4acb54ba | Edgar E. Iglesias | break;
|
416 | 4acb54ba | Edgar E. Iglesias | case 0x3: |
417 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]); |
418 | 4acb54ba | Edgar E. Iglesias | break;
|
419 | 4acb54ba | Edgar E. Iglesias | case 0x5: |
420 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]); |
421 | 4acb54ba | Edgar E. Iglesias | break;
|
422 | 4acb54ba | Edgar E. Iglesias | case 0x7: |
423 | 4acb54ba | Edgar E. Iglesias | /* Ignored at the moment. */
|
424 | 4acb54ba | Edgar E. Iglesias | break;
|
425 | 4acb54ba | Edgar E. Iglesias | default:
|
426 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown mts reg %x\n", sr);
|
427 | 4acb54ba | Edgar E. Iglesias | break;
|
428 | 4acb54ba | Edgar E. Iglesias | } |
429 | 4acb54ba | Edgar E. Iglesias | } else {
|
430 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm); |
431 | 4acb54ba | Edgar E. Iglesias | |
432 | 4acb54ba | Edgar E. Iglesias | switch (sr) {
|
433 | 4acb54ba | Edgar E. Iglesias | case 0: |
434 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc); |
435 | 4acb54ba | Edgar E. Iglesias | break;
|
436 | 4acb54ba | Edgar E. Iglesias | case 1: |
437 | 4acb54ba | Edgar E. Iglesias | msr_read(dc, cpu_R[dc->rd]); |
438 | 4acb54ba | Edgar E. Iglesias | break;
|
439 | 4acb54ba | Edgar E. Iglesias | case 0x3: |
440 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]); |
441 | 4acb54ba | Edgar E. Iglesias | break;
|
442 | 4acb54ba | Edgar E. Iglesias | case 0x5: |
443 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]); |
444 | 4acb54ba | Edgar E. Iglesias | break;
|
445 | 4acb54ba | Edgar E. Iglesias | case 0x7: |
446 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], 0);
|
447 | 4acb54ba | Edgar E. Iglesias | break;
|
448 | 4acb54ba | Edgar E. Iglesias | case 0xb: |
449 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]); |
450 | 4acb54ba | Edgar E. Iglesias | break;
|
451 | 4acb54ba | Edgar E. Iglesias | case 0x2000: |
452 | 4acb54ba | Edgar E. Iglesias | case 0x2001: |
453 | 4acb54ba | Edgar E. Iglesias | case 0x2002: |
454 | 4acb54ba | Edgar E. Iglesias | case 0x2003: |
455 | 4acb54ba | Edgar E. Iglesias | case 0x2004: |
456 | 4acb54ba | Edgar E. Iglesias | case 0x2005: |
457 | 4acb54ba | Edgar E. Iglesias | case 0x2006: |
458 | 4acb54ba | Edgar E. Iglesias | case 0x2007: |
459 | 4acb54ba | Edgar E. Iglesias | case 0x2008: |
460 | 4acb54ba | Edgar E. Iglesias | case 0x2009: |
461 | 4acb54ba | Edgar E. Iglesias | case 0x200a: |
462 | 4acb54ba | Edgar E. Iglesias | case 0x200b: |
463 | 4acb54ba | Edgar E. Iglesias | case 0x200c: |
464 | 4acb54ba | Edgar E. Iglesias | rn = sr & 0xf;
|
465 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ld_tl(cpu_R[dc->rd], |
466 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, pvr.regs[rn])); |
467 | 4acb54ba | Edgar E. Iglesias | break;
|
468 | 4acb54ba | Edgar E. Iglesias | default:
|
469 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown mfs reg %x\n", sr);
|
470 | 4acb54ba | Edgar E. Iglesias | break;
|
471 | 4acb54ba | Edgar E. Iglesias | } |
472 | 4acb54ba | Edgar E. Iglesias | } |
473 | 4acb54ba | Edgar E. Iglesias | } |
474 | 4acb54ba | Edgar E. Iglesias | |
475 | 4acb54ba | Edgar E. Iglesias | /* 64-bit signed mul, lower result in d and upper in d2. */
|
476 | 4acb54ba | Edgar E. Iglesias | static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) |
477 | 4acb54ba | Edgar E. Iglesias | { |
478 | 4acb54ba | Edgar E. Iglesias | TCGv_i64 t0, t1; |
479 | 4acb54ba | Edgar E. Iglesias | |
480 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new_i64(); |
481 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new_i64(); |
482 | 4acb54ba | Edgar E. Iglesias | |
483 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext_i32_i64(t0, a); |
484 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext_i32_i64(t1, b); |
485 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mul_i64(t0, t0, t1); |
486 | 4acb54ba | Edgar E. Iglesias | |
487 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d, t0); |
488 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_i64(t0, t0, 32);
|
489 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d2, t0); |
490 | 4acb54ba | Edgar E. Iglesias | |
491 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t0); |
492 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t1); |
493 | 4acb54ba | Edgar E. Iglesias | } |
494 | 4acb54ba | Edgar E. Iglesias | |
495 | 4acb54ba | Edgar E. Iglesias | /* 64-bit unsigned muls, lower result in d and upper in d2. */
|
496 | 4acb54ba | Edgar E. Iglesias | static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) |
497 | 4acb54ba | Edgar E. Iglesias | { |
498 | 4acb54ba | Edgar E. Iglesias | TCGv_i64 t0, t1; |
499 | 4acb54ba | Edgar E. Iglesias | |
500 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new_i64(); |
501 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new_i64(); |
502 | 4acb54ba | Edgar E. Iglesias | |
503 | 4acb54ba | Edgar E. Iglesias | tcg_gen_extu_i32_i64(t0, a); |
504 | 4acb54ba | Edgar E. Iglesias | tcg_gen_extu_i32_i64(t1, b); |
505 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mul_i64(t0, t0, t1); |
506 | 4acb54ba | Edgar E. Iglesias | |
507 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d, t0); |
508 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_i64(t0, t0, 32);
|
509 | 4acb54ba | Edgar E. Iglesias | tcg_gen_trunc_i64_i32(d2, t0); |
510 | 4acb54ba | Edgar E. Iglesias | |
511 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t0); |
512 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free_i64(t1); |
513 | 4acb54ba | Edgar E. Iglesias | } |
514 | 4acb54ba | Edgar E. Iglesias | |
515 | 4acb54ba | Edgar E. Iglesias | /* Multiplier unit. */
|
516 | 4acb54ba | Edgar E. Iglesias | static void dec_mul(DisasContext *dc) |
517 | 4acb54ba | Edgar E. Iglesias | { |
518 | 4acb54ba | Edgar E. Iglesias | TCGv d[2];
|
519 | 4acb54ba | Edgar E. Iglesias | unsigned int subcode; |
520 | 4acb54ba | Edgar E. Iglesias | |
521 | 4acb54ba | Edgar E. Iglesias | subcode = dc->imm & 3;
|
522 | 4acb54ba | Edgar E. Iglesias | d[0] = tcg_temp_new();
|
523 | 4acb54ba | Edgar E. Iglesias | d[1] = tcg_temp_new();
|
524 | 4acb54ba | Edgar E. Iglesias | |
525 | 4acb54ba | Edgar E. Iglesias | if (dc->type_b) {
|
526 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
|
527 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
528 | 4acb54ba | Edgar E. Iglesias | goto done;
|
529 | 4acb54ba | Edgar E. Iglesias | } |
530 | 4acb54ba | Edgar E. Iglesias | |
531 | 4acb54ba | Edgar E. Iglesias | switch (subcode) {
|
532 | 4acb54ba | Edgar E. Iglesias | case 0: |
533 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
534 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
|
535 | 4acb54ba | Edgar E. Iglesias | break;
|
536 | 4acb54ba | Edgar E. Iglesias | case 1: |
537 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
538 | 4acb54ba | Edgar E. Iglesias | t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
539 | 4acb54ba | Edgar E. Iglesias | break;
|
540 | 4acb54ba | Edgar E. Iglesias | case 2: |
541 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
542 | 4acb54ba | Edgar E. Iglesias | t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
543 | 4acb54ba | Edgar E. Iglesias | break;
|
544 | 4acb54ba | Edgar E. Iglesias | case 3: |
545 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
|
546 | 4acb54ba | Edgar E. Iglesias | t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
547 | 4acb54ba | Edgar E. Iglesias | break;
|
548 | 4acb54ba | Edgar E. Iglesias | default:
|
549 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown MUL insn %x\n", subcode);
|
550 | 4acb54ba | Edgar E. Iglesias | break;
|
551 | 4acb54ba | Edgar E. Iglesias | } |
552 | 4acb54ba | Edgar E. Iglesias | done:
|
553 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(d[0]);
|
554 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(d[1]);
|
555 | 4acb54ba | Edgar E. Iglesias | } |
556 | 4acb54ba | Edgar E. Iglesias | |
557 | 4acb54ba | Edgar E. Iglesias | /* Div unit. */
|
558 | 4acb54ba | Edgar E. Iglesias | static void dec_div(DisasContext *dc) |
559 | 4acb54ba | Edgar E. Iglesias | { |
560 | 4acb54ba | Edgar E. Iglesias | unsigned int u; |
561 | 4acb54ba | Edgar E. Iglesias | |
562 | 4acb54ba | Edgar E. Iglesias | u = dc->imm & 2;
|
563 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("div\n");
|
564 | 4acb54ba | Edgar E. Iglesias | |
565 | 4acb54ba | Edgar E. Iglesias | /* FIXME: support div by zero exceptions. */
|
566 | 4acb54ba | Edgar E. Iglesias | if (u)
|
567 | 4acb54ba | Edgar E. Iglesias | gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]); |
568 | 4acb54ba | Edgar E. Iglesias | else
|
569 | 4acb54ba | Edgar E. Iglesias | gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]); |
570 | 4acb54ba | Edgar E. Iglesias | if (!dc->rd)
|
571 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], 0);
|
572 | 4acb54ba | Edgar E. Iglesias | } |
573 | 4acb54ba | Edgar E. Iglesias | |
574 | 4acb54ba | Edgar E. Iglesias | static void dec_barrel(DisasContext *dc) |
575 | 4acb54ba | Edgar E. Iglesias | { |
576 | 4acb54ba | Edgar E. Iglesias | TCGv t0; |
577 | 4acb54ba | Edgar E. Iglesias | unsigned int s, t; |
578 | 4acb54ba | Edgar E. Iglesias | |
579 | 4acb54ba | Edgar E. Iglesias | s = dc->imm & (1 << 10); |
580 | 4acb54ba | Edgar E. Iglesias | t = dc->imm & (1 << 9); |
581 | 4acb54ba | Edgar E. Iglesias | |
582 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("bs%s%s r%d r%d r%d\n",
|
583 | 4acb54ba | Edgar E. Iglesias | s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb); |
584 | 4acb54ba | Edgar E. Iglesias | |
585 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
586 | 4acb54ba | Edgar E. Iglesias | |
587 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc))); |
588 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, 31);
|
589 | 4acb54ba | Edgar E. Iglesias | |
590 | 4acb54ba | Edgar E. Iglesias | if (s)
|
591 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
592 | 4acb54ba | Edgar E. Iglesias | else {
|
593 | 4acb54ba | Edgar E. Iglesias | if (t)
|
594 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
595 | 4acb54ba | Edgar E. Iglesias | else
|
596 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); |
597 | 4acb54ba | Edgar E. Iglesias | } |
598 | 4acb54ba | Edgar E. Iglesias | } |
599 | 4acb54ba | Edgar E. Iglesias | |
600 | 4acb54ba | Edgar E. Iglesias | static void dec_bit(DisasContext *dc) |
601 | 4acb54ba | Edgar E. Iglesias | { |
602 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
603 | 4acb54ba | Edgar E. Iglesias | unsigned int op; |
604 | 4acb54ba | Edgar E. Iglesias | |
605 | 4acb54ba | Edgar E. Iglesias | op = dc->ir & ((1 << 8) - 1); |
606 | 4acb54ba | Edgar E. Iglesias | switch (op) {
|
607 | 4acb54ba | Edgar E. Iglesias | case 0x21: |
608 | 4acb54ba | Edgar E. Iglesias | /* src. */
|
609 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
610 | 4acb54ba | Edgar E. Iglesias | |
611 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
|
612 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
|
613 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
614 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
615 | 4acb54ba | Edgar E. Iglesias | read_carry(dc, t1); |
616 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shli_tl(t1, t1, 31);
|
617 | 4acb54ba | Edgar E. Iglesias | |
618 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
619 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t1); |
620 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
621 | 4acb54ba | Edgar E. Iglesias | } |
622 | 4acb54ba | Edgar E. Iglesias | |
623 | 4acb54ba | Edgar E. Iglesias | /* Update carry. */
|
624 | 4acb54ba | Edgar E. Iglesias | write_carry(dc, t0); |
625 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
626 | 4acb54ba | Edgar E. Iglesias | break;
|
627 | 4acb54ba | Edgar E. Iglesias | |
628 | 4acb54ba | Edgar E. Iglesias | case 0x1: |
629 | 4acb54ba | Edgar E. Iglesias | case 0x41: |
630 | 4acb54ba | Edgar E. Iglesias | /* srl. */
|
631 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
632 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
|
633 | 4acb54ba | Edgar E. Iglesias | |
634 | 4acb54ba | Edgar E. Iglesias | /* Update carry. */
|
635 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
|
636 | 4acb54ba | Edgar E. Iglesias | write_carry(dc, t0); |
637 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
638 | 4acb54ba | Edgar E. Iglesias | if (dc->rd) {
|
639 | 4acb54ba | Edgar E. Iglesias | if (op == 0x41) |
640 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
641 | 4acb54ba | Edgar E. Iglesias | else
|
642 | 4acb54ba | Edgar E. Iglesias | tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
|
643 | 4acb54ba | Edgar E. Iglesias | } |
644 | 4acb54ba | Edgar E. Iglesias | break;
|
645 | 4acb54ba | Edgar E. Iglesias | case 0x60: |
646 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
|
647 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]); |
648 | 4acb54ba | Edgar E. Iglesias | break;
|
649 | 4acb54ba | Edgar E. Iglesias | case 0x61: |
650 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
|
651 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]); |
652 | 4acb54ba | Edgar E. Iglesias | break;
|
653 | 4acb54ba | Edgar E. Iglesias | case 0x64: |
654 | 4acb54ba | Edgar E. Iglesias | /* wdc. */
|
655 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("wdc r%d\n", dc->ra);
|
656 | 4acb54ba | Edgar E. Iglesias | break;
|
657 | 4acb54ba | Edgar E. Iglesias | case 0x68: |
658 | 4acb54ba | Edgar E. Iglesias | /* wic. */
|
659 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("wic r%d\n", dc->ra);
|
660 | 4acb54ba | Edgar E. Iglesias | break;
|
661 | 4acb54ba | Edgar E. Iglesias | default:
|
662 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
|
663 | 4acb54ba | Edgar E. Iglesias | dc->pc, op, dc->rd, dc->ra, dc->rb); |
664 | 4acb54ba | Edgar E. Iglesias | break;
|
665 | 4acb54ba | Edgar E. Iglesias | } |
666 | 4acb54ba | Edgar E. Iglesias | } |
667 | 4acb54ba | Edgar E. Iglesias | |
668 | 4acb54ba | Edgar E. Iglesias | static inline void sync_jmpstate(DisasContext *dc) |
669 | 4acb54ba | Edgar E. Iglesias | { |
670 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp == JMP_DIRECT) {
|
671 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
672 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
673 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->jmp_pc); |
674 | 4acb54ba | Edgar E. Iglesias | } |
675 | 4acb54ba | Edgar E. Iglesias | } |
676 | 4acb54ba | Edgar E. Iglesias | |
677 | 4acb54ba | Edgar E. Iglesias | static void dec_imm(DisasContext *dc) |
678 | 4acb54ba | Edgar E. Iglesias | { |
679 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("imm %x\n", dc->imm << 16); |
680 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_imm, (dc->imm << 16));
|
681 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= IMM_FLAG; |
682 | 4acb54ba | Edgar E. Iglesias | dc->clear_imm = 0;
|
683 | 4acb54ba | Edgar E. Iglesias | } |
684 | 4acb54ba | Edgar E. Iglesias | |
685 | 4acb54ba | Edgar E. Iglesias | static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr, |
686 | 4acb54ba | Edgar E. Iglesias | unsigned int size) |
687 | 4acb54ba | Edgar E. Iglesias | { |
688 | 4acb54ba | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
689 | 4acb54ba | Edgar E. Iglesias | |
690 | 4acb54ba | Edgar E. Iglesias | if (size == 1) { |
691 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld8u(dst, addr, mem_index); |
692 | 4acb54ba | Edgar E. Iglesias | } else if (size == 2) { |
693 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld16u(dst, addr, mem_index); |
694 | 4acb54ba | Edgar E. Iglesias | } else if (size == 4) { |
695 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_ld32u(dst, addr, mem_index); |
696 | 4acb54ba | Edgar E. Iglesias | } else
|
697 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Incorrect load size %d\n", size);
|
698 | 4acb54ba | Edgar E. Iglesias | } |
699 | 4acb54ba | Edgar E. Iglesias | |
700 | 4acb54ba | Edgar E. Iglesias | static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t) |
701 | 4acb54ba | Edgar E. Iglesias | { |
702 | 4acb54ba | Edgar E. Iglesias | unsigned int extimm = dc->tb_flags & IMM_FLAG; |
703 | 4acb54ba | Edgar E. Iglesias | |
704 | 4acb54ba | Edgar E. Iglesias | /* Treat the fast cases first. */
|
705 | 4acb54ba | Edgar E. Iglesias | if (!dc->type_b) {
|
706 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
707 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]); |
708 | 4acb54ba | Edgar E. Iglesias | return t;
|
709 | 4acb54ba | Edgar E. Iglesias | } |
710 | 4acb54ba | Edgar E. Iglesias | /* Immediate. */
|
711 | 4acb54ba | Edgar E. Iglesias | if (!extimm) {
|
712 | 4acb54ba | Edgar E. Iglesias | if (dc->imm == 0) { |
713 | 4acb54ba | Edgar E. Iglesias | return &cpu_R[dc->ra];
|
714 | 4acb54ba | Edgar E. Iglesias | } |
715 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
716 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm)); |
717 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], *t); |
718 | 4acb54ba | Edgar E. Iglesias | } else {
|
719 | 4acb54ba | Edgar E. Iglesias | *t = tcg_temp_new(); |
720 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
721 | 4acb54ba | Edgar E. Iglesias | } |
722 | 4acb54ba | Edgar E. Iglesias | |
723 | 4acb54ba | Edgar E. Iglesias | return t;
|
724 | 4acb54ba | Edgar E. Iglesias | } |
725 | 4acb54ba | Edgar E. Iglesias | |
726 | 4acb54ba | Edgar E. Iglesias | static void dec_load(DisasContext *dc) |
727 | 4acb54ba | Edgar E. Iglesias | { |
728 | 4acb54ba | Edgar E. Iglesias | TCGv t, *addr; |
729 | 4acb54ba | Edgar E. Iglesias | unsigned int size; |
730 | 4acb54ba | Edgar E. Iglesias | |
731 | 4acb54ba | Edgar E. Iglesias | size = 1 << (dc->opcode & 3); |
732 | 4acb54ba | Edgar E. Iglesias | |
733 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("l %x %d\n", dc->opcode, size);
|
734 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
735 | 4acb54ba | Edgar E. Iglesias | addr = compute_ldst_addr(dc, &t); |
736 | 4acb54ba | Edgar E. Iglesias | |
737 | 4acb54ba | Edgar E. Iglesias | /* If we get a fault on a dslot, the jmpstate better be in sync. */
|
738 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
739 | 4acb54ba | Edgar E. Iglesias | if (dc->rd)
|
740 | 4acb54ba | Edgar E. Iglesias | gen_load(dc, cpu_R[dc->rd], *addr, size); |
741 | 4acb54ba | Edgar E. Iglesias | else {
|
742 | 4acb54ba | Edgar E. Iglesias | gen_load(dc, env_imm, *addr, size); |
743 | 4acb54ba | Edgar E. Iglesias | } |
744 | 4acb54ba | Edgar E. Iglesias | |
745 | 4acb54ba | Edgar E. Iglesias | if (addr == &t)
|
746 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
747 | 4acb54ba | Edgar E. Iglesias | } |
748 | 4acb54ba | Edgar E. Iglesias | |
749 | 4acb54ba | Edgar E. Iglesias | static void gen_store(DisasContext *dc, TCGv addr, TCGv val, |
750 | 4acb54ba | Edgar E. Iglesias | unsigned int size) |
751 | 4acb54ba | Edgar E. Iglesias | { |
752 | 4acb54ba | Edgar E. Iglesias | int mem_index = cpu_mmu_index(dc->env);
|
753 | 4acb54ba | Edgar E. Iglesias | |
754 | 4acb54ba | Edgar E. Iglesias | if (size == 1) |
755 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st8(val, addr, mem_index); |
756 | 4acb54ba | Edgar E. Iglesias | else if (size == 2) { |
757 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st16(val, addr, mem_index); |
758 | 4acb54ba | Edgar E. Iglesias | } else if (size == 4) { |
759 | 4acb54ba | Edgar E. Iglesias | tcg_gen_qemu_st32(val, addr, mem_index); |
760 | 4acb54ba | Edgar E. Iglesias | } else
|
761 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Incorrect store size %d\n", size);
|
762 | 4acb54ba | Edgar E. Iglesias | } |
763 | 4acb54ba | Edgar E. Iglesias | |
764 | 4acb54ba | Edgar E. Iglesias | static void dec_store(DisasContext *dc) |
765 | 4acb54ba | Edgar E. Iglesias | { |
766 | 4acb54ba | Edgar E. Iglesias | TCGv t, *addr; |
767 | 4acb54ba | Edgar E. Iglesias | unsigned int size; |
768 | 4acb54ba | Edgar E. Iglesias | |
769 | 4acb54ba | Edgar E. Iglesias | size = 1 << (dc->opcode & 3); |
770 | 4acb54ba | Edgar E. Iglesias | |
771 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("s%d%s\n", size, dc->type_b ? "i" : ""); |
772 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
773 | 4acb54ba | Edgar E. Iglesias | /* If we get a fault on a dslot, the jmpstate better be in sync. */
|
774 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
775 | 4acb54ba | Edgar E. Iglesias | addr = compute_ldst_addr(dc, &t); |
776 | 4acb54ba | Edgar E. Iglesias | gen_store(dc, *addr, cpu_R[dc->rd], size); |
777 | 4acb54ba | Edgar E. Iglesias | if (addr == &t)
|
778 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t); |
779 | 4acb54ba | Edgar E. Iglesias | } |
780 | 4acb54ba | Edgar E. Iglesias | |
781 | 4acb54ba | Edgar E. Iglesias | static inline void eval_cc(DisasContext *dc, unsigned int cc, |
782 | 4acb54ba | Edgar E. Iglesias | TCGv d, TCGv a, TCGv b) |
783 | 4acb54ba | Edgar E. Iglesias | { |
784 | 4acb54ba | Edgar E. Iglesias | int l1;
|
785 | 4acb54ba | Edgar E. Iglesias | |
786 | 4acb54ba | Edgar E. Iglesias | switch (cc) {
|
787 | 4acb54ba | Edgar E. Iglesias | case CC_EQ:
|
788 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
789 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
790 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_EQ, a, b, l1); |
791 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
792 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
793 | 4acb54ba | Edgar E. Iglesias | break;
|
794 | 4acb54ba | Edgar E. Iglesias | case CC_NE:
|
795 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
796 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
797 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_NE, a, b, l1); |
798 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
799 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
800 | 4acb54ba | Edgar E. Iglesias | break;
|
801 | 4acb54ba | Edgar E. Iglesias | case CC_LT:
|
802 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
803 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
804 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_LT, a, b, l1); |
805 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
806 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
807 | 4acb54ba | Edgar E. Iglesias | break;
|
808 | 4acb54ba | Edgar E. Iglesias | case CC_LE:
|
809 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
810 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
811 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_LE, a, b, l1); |
812 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
813 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
814 | 4acb54ba | Edgar E. Iglesias | break;
|
815 | 4acb54ba | Edgar E. Iglesias | case CC_GE:
|
816 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
817 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
818 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_GE, a, b, l1); |
819 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
820 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
821 | 4acb54ba | Edgar E. Iglesias | break;
|
822 | 4acb54ba | Edgar E. Iglesias | case CC_GT:
|
823 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
824 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
825 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcond_tl(TCG_COND_GT, a, b, l1); |
826 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 0);
|
827 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
828 | 4acb54ba | Edgar E. Iglesias | break;
|
829 | 4acb54ba | Edgar E. Iglesias | default:
|
830 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "Unknown condition code %x.\n", cc);
|
831 | 4acb54ba | Edgar E. Iglesias | break;
|
832 | 4acb54ba | Edgar E. Iglesias | } |
833 | 4acb54ba | Edgar E. Iglesias | } |
834 | 4acb54ba | Edgar E. Iglesias | |
835 | 4acb54ba | Edgar E. Iglesias | static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false) |
836 | 4acb54ba | Edgar E. Iglesias | { |
837 | 4acb54ba | Edgar E. Iglesias | int l1;
|
838 | 4acb54ba | Edgar E. Iglesias | |
839 | 4acb54ba | Edgar E. Iglesias | l1 = gen_new_label(); |
840 | 4acb54ba | Edgar E. Iglesias | /* Conditional jmp. */
|
841 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false); |
842 | 4acb54ba | Edgar E. Iglesias | tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
|
843 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true); |
844 | 4acb54ba | Edgar E. Iglesias | gen_set_label(l1); |
845 | 4acb54ba | Edgar E. Iglesias | } |
846 | 4acb54ba | Edgar E. Iglesias | |
847 | 4acb54ba | Edgar E. Iglesias | static void dec_bcc(DisasContext *dc) |
848 | 4acb54ba | Edgar E. Iglesias | { |
849 | 4acb54ba | Edgar E. Iglesias | unsigned int cc; |
850 | 4acb54ba | Edgar E. Iglesias | unsigned int dslot; |
851 | 4acb54ba | Edgar E. Iglesias | |
852 | 4acb54ba | Edgar E. Iglesias | cc = EXTRACT_FIELD(dc->ir, 21, 23); |
853 | 4acb54ba | Edgar E. Iglesias | dslot = dc->ir & (1 << 25); |
854 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm); |
855 | 4acb54ba | Edgar E. Iglesias | |
856 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 1;
|
857 | 4acb54ba | Edgar E. Iglesias | if (dslot) {
|
858 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
859 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
860 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
861 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
862 | 4acb54ba | Edgar E. Iglesias | } |
863 | 4acb54ba | Edgar E. Iglesias | |
864 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->pc); |
865 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc))); |
866 | 4acb54ba | Edgar E. Iglesias | eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
|
867 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
868 | 4acb54ba | Edgar E. Iglesias | } |
869 | 4acb54ba | Edgar E. Iglesias | |
870 | 4acb54ba | Edgar E. Iglesias | static void dec_br(DisasContext *dc) |
871 | 4acb54ba | Edgar E. Iglesias | { |
872 | 4acb54ba | Edgar E. Iglesias | unsigned int dslot, link, abs; |
873 | 4acb54ba | Edgar E. Iglesias | |
874 | 4acb54ba | Edgar E. Iglesias | dslot = dc->ir & (1 << 20); |
875 | 4acb54ba | Edgar E. Iglesias | abs = dc->ir & (1 << 19); |
876 | 4acb54ba | Edgar E. Iglesias | link = dc->ir & (1 << 18); |
877 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("br%s%s%s%s imm=%x\n",
|
878 | 4acb54ba | Edgar E. Iglesias | abs ? "a" : "", link ? "l" : "", |
879 | 4acb54ba | Edgar E. Iglesias | dc->type_b ? "i" : "", dslot ? "d" : "", |
880 | 4acb54ba | Edgar E. Iglesias | dc->imm); |
881 | 4acb54ba | Edgar E. Iglesias | |
882 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 1;
|
883 | 4acb54ba | Edgar E. Iglesias | if (dslot) {
|
884 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
885 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
886 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
887 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
888 | 4acb54ba | Edgar E. Iglesias | } |
889 | 4acb54ba | Edgar E. Iglesias | if (link && dc->rd)
|
890 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc); |
891 | 4acb54ba | Edgar E. Iglesias | |
892 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_INDIRECT; |
893 | 4acb54ba | Edgar E. Iglesias | if (abs) {
|
894 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
895 | 4acb54ba | Edgar E. Iglesias | tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc))); |
896 | 4acb54ba | Edgar E. Iglesias | if (link && !(dc->tb_flags & IMM_FLAG)
|
897 | 4acb54ba | Edgar E. Iglesias | && (dc->imm == 8 || dc->imm == 0x18)) |
898 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_BREAK); |
899 | 4acb54ba | Edgar E. Iglesias | if (dc->imm == 0) |
900 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
901 | 4acb54ba | Edgar E. Iglesias | } else {
|
902 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & IMM_FLAG) {
|
903 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
904 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btarget, dc->pc); |
905 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc))); |
906 | 4acb54ba | Edgar E. Iglesias | } else {
|
907 | 4acb54ba | Edgar E. Iglesias | dc->jmp = JMP_DIRECT; |
908 | 4acb54ba | Edgar E. Iglesias | dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm); |
909 | 4acb54ba | Edgar E. Iglesias | } |
910 | 4acb54ba | Edgar E. Iglesias | } |
911 | 4acb54ba | Edgar E. Iglesias | } |
912 | 4acb54ba | Edgar E. Iglesias | |
913 | 4acb54ba | Edgar E. Iglesias | static inline void do_rti(DisasContext *dc) |
914 | 4acb54ba | Edgar E. Iglesias | { |
915 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
916 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
917 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
918 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
|
919 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE); |
920 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
921 | 4acb54ba | Edgar E. Iglesias | |
922 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
923 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
924 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
925 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
926 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
927 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTI_FLAG; |
928 | 4acb54ba | Edgar E. Iglesias | } |
929 | 4acb54ba | Edgar E. Iglesias | |
930 | 4acb54ba | Edgar E. Iglesias | static inline void do_rtb(DisasContext *dc) |
931 | 4acb54ba | Edgar E. Iglesias | { |
932 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
933 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
934 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
935 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP); |
936 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, t1, 1);
|
937 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
938 | 4acb54ba | Edgar E. Iglesias | |
939 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
940 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
941 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
942 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
943 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
944 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTB_FLAG; |
945 | 4acb54ba | Edgar E. Iglesias | } |
946 | 4acb54ba | Edgar E. Iglesias | |
947 | 4acb54ba | Edgar E. Iglesias | static inline void do_rte(DisasContext *dc) |
948 | 4acb54ba | Edgar E. Iglesias | { |
949 | 4acb54ba | Edgar E. Iglesias | TCGv t0, t1; |
950 | 4acb54ba | Edgar E. Iglesias | t0 = tcg_temp_new(); |
951 | 4acb54ba | Edgar E. Iglesias | t1 = tcg_temp_new(); |
952 | 4acb54ba | Edgar E. Iglesias | |
953 | 4acb54ba | Edgar E. Iglesias | tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE); |
954 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~MSR_EIP); |
955 | 4acb54ba | Edgar E. Iglesias | tcg_gen_shri_tl(t0, t1, 1);
|
956 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM)); |
957 | 4acb54ba | Edgar E. Iglesias | |
958 | 4acb54ba | Edgar E. Iglesias | tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM)); |
959 | 4acb54ba | Edgar E. Iglesias | tcg_gen_or_tl(t1, t1, t0); |
960 | 4acb54ba | Edgar E. Iglesias | msr_write(dc, t1); |
961 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t1); |
962 | 4acb54ba | Edgar E. Iglesias | tcg_temp_free(t0); |
963 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~DRTE_FLAG; |
964 | 4acb54ba | Edgar E. Iglesias | } |
965 | 4acb54ba | Edgar E. Iglesias | |
966 | 4acb54ba | Edgar E. Iglesias | static void dec_rts(DisasContext *dc) |
967 | 4acb54ba | Edgar E. Iglesias | { |
968 | 4acb54ba | Edgar E. Iglesias | unsigned int b_bit, i_bit, e_bit; |
969 | 4acb54ba | Edgar E. Iglesias | |
970 | 4acb54ba | Edgar E. Iglesias | i_bit = dc->ir & (1 << 21); |
971 | 4acb54ba | Edgar E. Iglesias | b_bit = dc->ir & (1 << 22); |
972 | 4acb54ba | Edgar E. Iglesias | e_bit = dc->ir & (1 << 23); |
973 | 4acb54ba | Edgar E. Iglesias | |
974 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = 2;
|
975 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= D_FLAG; |
976 | 4acb54ba | Edgar E. Iglesias | tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)), |
977 | 4acb54ba | Edgar E. Iglesias | cpu_env, offsetof(CPUState, bimm)); |
978 | 4acb54ba | Edgar E. Iglesias | |
979 | 4acb54ba | Edgar E. Iglesias | if (i_bit) {
|
980 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rtid ir=%x\n", dc->ir);
|
981 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTI_FLAG; |
982 | 4acb54ba | Edgar E. Iglesias | } else if (b_bit) { |
983 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rtbd ir=%x\n", dc->ir);
|
984 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTB_FLAG; |
985 | 4acb54ba | Edgar E. Iglesias | } else if (e_bit) { |
986 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rted ir=%x\n", dc->ir);
|
987 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags |= DRTE_FLAG; |
988 | 4acb54ba | Edgar E. Iglesias | } else
|
989 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("rts ir=%x\n", dc->ir);
|
990 | 4acb54ba | Edgar E. Iglesias | |
991 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(env_btaken, 1);
|
992 | 4acb54ba | Edgar E. Iglesias | tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc))); |
993 | 4acb54ba | Edgar E. Iglesias | } |
994 | 4acb54ba | Edgar E. Iglesias | |
995 | 4acb54ba | Edgar E. Iglesias | static void dec_null(DisasContext *dc) |
996 | 4acb54ba | Edgar E. Iglesias | { |
997 | 4acb54ba | Edgar E. Iglesias | qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
|
998 | 4acb54ba | Edgar E. Iglesias | dc->abort_at_next_insn = 1;
|
999 | 4acb54ba | Edgar E. Iglesias | } |
1000 | 4acb54ba | Edgar E. Iglesias | |
1001 | 4acb54ba | Edgar E. Iglesias | static struct decoder_info { |
1002 | 4acb54ba | Edgar E. Iglesias | struct {
|
1003 | 4acb54ba | Edgar E. Iglesias | uint32_t bits; |
1004 | 4acb54ba | Edgar E. Iglesias | uint32_t mask; |
1005 | 4acb54ba | Edgar E. Iglesias | }; |
1006 | 4acb54ba | Edgar E. Iglesias | void (*dec)(DisasContext *dc);
|
1007 | 4acb54ba | Edgar E. Iglesias | } decinfo[] = { |
1008 | 4acb54ba | Edgar E. Iglesias | {DEC_ADD, dec_add}, |
1009 | 4acb54ba | Edgar E. Iglesias | {DEC_SUB, dec_sub}, |
1010 | 4acb54ba | Edgar E. Iglesias | {DEC_AND, dec_and}, |
1011 | 4acb54ba | Edgar E. Iglesias | {DEC_XOR, dec_xor}, |
1012 | 4acb54ba | Edgar E. Iglesias | {DEC_OR, dec_or}, |
1013 | 4acb54ba | Edgar E. Iglesias | {DEC_BIT, dec_bit}, |
1014 | 4acb54ba | Edgar E. Iglesias | {DEC_BARREL, dec_barrel}, |
1015 | 4acb54ba | Edgar E. Iglesias | {DEC_LD, dec_load}, |
1016 | 4acb54ba | Edgar E. Iglesias | {DEC_ST, dec_store}, |
1017 | 4acb54ba | Edgar E. Iglesias | {DEC_IMM, dec_imm}, |
1018 | 4acb54ba | Edgar E. Iglesias | {DEC_BR, dec_br}, |
1019 | 4acb54ba | Edgar E. Iglesias | {DEC_BCC, dec_bcc}, |
1020 | 4acb54ba | Edgar E. Iglesias | {DEC_RTS, dec_rts}, |
1021 | 4acb54ba | Edgar E. Iglesias | {DEC_MUL, dec_mul}, |
1022 | 4acb54ba | Edgar E. Iglesias | {DEC_DIV, dec_div}, |
1023 | 4acb54ba | Edgar E. Iglesias | {DEC_MSR, dec_msr}, |
1024 | 4acb54ba | Edgar E. Iglesias | {{0, 0}, dec_null} |
1025 | 4acb54ba | Edgar E. Iglesias | }; |
1026 | 4acb54ba | Edgar E. Iglesias | |
1027 | 4acb54ba | Edgar E. Iglesias | static inline void decode(DisasContext *dc) |
1028 | 4acb54ba | Edgar E. Iglesias | { |
1029 | 4acb54ba | Edgar E. Iglesias | uint32_t ir; |
1030 | 4acb54ba | Edgar E. Iglesias | int i;
|
1031 | 4acb54ba | Edgar E. Iglesias | |
1032 | 4acb54ba | Edgar E. Iglesias | if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
|
1033 | 4acb54ba | Edgar E. Iglesias | tcg_gen_debug_insn_start(dc->pc); |
1034 | 4acb54ba | Edgar E. Iglesias | |
1035 | 4acb54ba | Edgar E. Iglesias | dc->ir = ir = ldl_code(dc->pc); |
1036 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("%8.8x\t", dc->ir);
|
1037 | 4acb54ba | Edgar E. Iglesias | |
1038 | 4acb54ba | Edgar E. Iglesias | if (dc->ir)
|
1039 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops = 0;
|
1040 | 4acb54ba | Edgar E. Iglesias | else {
|
1041 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("nr_nops=%d\t", dc->nr_nops);
|
1042 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops++; |
1043 | 4acb54ba | Edgar E. Iglesias | if (dc->nr_nops > 4) |
1044 | 4acb54ba | Edgar E. Iglesias | cpu_abort(dc->env, "fetching nop sequence\n");
|
1045 | 4acb54ba | Edgar E. Iglesias | } |
1046 | 4acb54ba | Edgar E. Iglesias | /* bit 2 seems to indicate insn type. */
|
1047 | 4acb54ba | Edgar E. Iglesias | dc->type_b = ir & (1 << 29); |
1048 | 4acb54ba | Edgar E. Iglesias | |
1049 | 4acb54ba | Edgar E. Iglesias | dc->opcode = EXTRACT_FIELD(ir, 26, 31); |
1050 | 4acb54ba | Edgar E. Iglesias | dc->rd = EXTRACT_FIELD(ir, 21, 25); |
1051 | 4acb54ba | Edgar E. Iglesias | dc->ra = EXTRACT_FIELD(ir, 16, 20); |
1052 | 4acb54ba | Edgar E. Iglesias | dc->rb = EXTRACT_FIELD(ir, 11, 15); |
1053 | 4acb54ba | Edgar E. Iglesias | dc->imm = EXTRACT_FIELD(ir, 0, 15); |
1054 | 4acb54ba | Edgar E. Iglesias | |
1055 | 4acb54ba | Edgar E. Iglesias | /* Large switch for all insns. */
|
1056 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(decinfo); i++) { |
1057 | 4acb54ba | Edgar E. Iglesias | if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
|
1058 | 4acb54ba | Edgar E. Iglesias | decinfo[i].dec(dc); |
1059 | 4acb54ba | Edgar E. Iglesias | break;
|
1060 | 4acb54ba | Edgar E. Iglesias | } |
1061 | 4acb54ba | Edgar E. Iglesias | } |
1062 | 4acb54ba | Edgar E. Iglesias | } |
1063 | 4acb54ba | Edgar E. Iglesias | |
1064 | 4acb54ba | Edgar E. Iglesias | |
1065 | 4acb54ba | Edgar E. Iglesias | static void check_breakpoint(CPUState *env, DisasContext *dc) |
1066 | 4acb54ba | Edgar E. Iglesias | { |
1067 | 4acb54ba | Edgar E. Iglesias | CPUBreakpoint *bp; |
1068 | 4acb54ba | Edgar E. Iglesias | |
1069 | 4acb54ba | Edgar E. Iglesias | if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
|
1070 | 4acb54ba | Edgar E. Iglesias | TAILQ_FOREACH(bp, &env->breakpoints, entry) { |
1071 | 4acb54ba | Edgar E. Iglesias | if (bp->pc == dc->pc) {
|
1072 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
1073 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1074 | 4acb54ba | Edgar E. Iglesias | } |
1075 | 4acb54ba | Edgar E. Iglesias | } |
1076 | 4acb54ba | Edgar E. Iglesias | } |
1077 | 4acb54ba | Edgar E. Iglesias | } |
1078 | 4acb54ba | Edgar E. Iglesias | |
1079 | 4acb54ba | Edgar E. Iglesias | /* generate intermediate code for basic block 'tb'. */
|
1080 | 4acb54ba | Edgar E. Iglesias | static void |
1081 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
1082 | 4acb54ba | Edgar E. Iglesias | int search_pc)
|
1083 | 4acb54ba | Edgar E. Iglesias | { |
1084 | 4acb54ba | Edgar E. Iglesias | uint16_t *gen_opc_end; |
1085 | 4acb54ba | Edgar E. Iglesias | uint32_t pc_start; |
1086 | 4acb54ba | Edgar E. Iglesias | int j, lj;
|
1087 | 4acb54ba | Edgar E. Iglesias | struct DisasContext ctx;
|
1088 | 4acb54ba | Edgar E. Iglesias | struct DisasContext *dc = &ctx;
|
1089 | 4acb54ba | Edgar E. Iglesias | uint32_t next_page_start, org_flags; |
1090 | 4acb54ba | Edgar E. Iglesias | target_ulong npc; |
1091 | 4acb54ba | Edgar E. Iglesias | int num_insns;
|
1092 | 4acb54ba | Edgar E. Iglesias | int max_insns;
|
1093 | 4acb54ba | Edgar E. Iglesias | |
1094 | 4acb54ba | Edgar E. Iglesias | qemu_log_try_set_file(stderr); |
1095 | 4acb54ba | Edgar E. Iglesias | |
1096 | 4acb54ba | Edgar E. Iglesias | pc_start = tb->pc; |
1097 | 4acb54ba | Edgar E. Iglesias | dc->env = env; |
1098 | 4acb54ba | Edgar E. Iglesias | dc->tb = tb; |
1099 | 4acb54ba | Edgar E. Iglesias | org_flags = dc->synced_flags = dc->tb_flags = tb->flags; |
1100 | 4acb54ba | Edgar E. Iglesias | |
1101 | 4acb54ba | Edgar E. Iglesias | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
1102 | 4acb54ba | Edgar E. Iglesias | |
1103 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_NEXT; |
1104 | 4acb54ba | Edgar E. Iglesias | dc->jmp = 0;
|
1105 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch = !!(dc->tb_flags & D_FLAG); |
1106 | 4acb54ba | Edgar E. Iglesias | dc->ppc = pc_start; |
1107 | 4acb54ba | Edgar E. Iglesias | dc->pc = pc_start; |
1108 | 4acb54ba | Edgar E. Iglesias | dc->cache_pc = -1;
|
1109 | 4acb54ba | Edgar E. Iglesias | dc->singlestep_enabled = env->singlestep_enabled; |
1110 | 4acb54ba | Edgar E. Iglesias | dc->cpustate_changed = 0;
|
1111 | 4acb54ba | Edgar E. Iglesias | dc->abort_at_next_insn = 0;
|
1112 | 4acb54ba | Edgar E. Iglesias | dc->nr_nops = 0;
|
1113 | 4acb54ba | Edgar E. Iglesias | |
1114 | 4acb54ba | Edgar E. Iglesias | if (pc_start & 3) |
1115 | 4acb54ba | Edgar E. Iglesias | cpu_abort(env, "Microblaze: unaligned PC=%x\n", pc_start);
|
1116 | 4acb54ba | Edgar E. Iglesias | |
1117 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1118 | 4acb54ba | Edgar E. Iglesias | #if !SIM_COMPAT
|
1119 | 4acb54ba | Edgar E. Iglesias | qemu_log("--------------\n");
|
1120 | 4acb54ba | Edgar E. Iglesias | log_cpu_state(env, 0);
|
1121 | 4acb54ba | Edgar E. Iglesias | #endif
|
1122 | 4acb54ba | Edgar E. Iglesias | } |
1123 | 4acb54ba | Edgar E. Iglesias | |
1124 | 4acb54ba | Edgar E. Iglesias | next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; |
1125 | 4acb54ba | Edgar E. Iglesias | lj = -1;
|
1126 | 4acb54ba | Edgar E. Iglesias | num_insns = 0;
|
1127 | 4acb54ba | Edgar E. Iglesias | max_insns = tb->cflags & CF_COUNT_MASK; |
1128 | 4acb54ba | Edgar E. Iglesias | if (max_insns == 0) |
1129 | 4acb54ba | Edgar E. Iglesias | max_insns = CF_COUNT_MASK; |
1130 | 4acb54ba | Edgar E. Iglesias | |
1131 | 4acb54ba | Edgar E. Iglesias | gen_icount_start(); |
1132 | 4acb54ba | Edgar E. Iglesias | do
|
1133 | 4acb54ba | Edgar E. Iglesias | { |
1134 | 4acb54ba | Edgar E. Iglesias | #if SIM_COMPAT
|
1135 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1136 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); |
1137 | 4acb54ba | Edgar E. Iglesias | gen_helper_debug(); |
1138 | 4acb54ba | Edgar E. Iglesias | } |
1139 | 4acb54ba | Edgar E. Iglesias | #endif
|
1140 | 4acb54ba | Edgar E. Iglesias | check_breakpoint(env, dc); |
1141 | 4acb54ba | Edgar E. Iglesias | |
1142 | 4acb54ba | Edgar E. Iglesias | if (search_pc) {
|
1143 | 4acb54ba | Edgar E. Iglesias | j = gen_opc_ptr - gen_opc_buf; |
1144 | 4acb54ba | Edgar E. Iglesias | if (lj < j) {
|
1145 | 4acb54ba | Edgar E. Iglesias | lj++; |
1146 | 4acb54ba | Edgar E. Iglesias | while (lj < j)
|
1147 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj++] = 0;
|
1148 | 4acb54ba | Edgar E. Iglesias | } |
1149 | 4acb54ba | Edgar E. Iglesias | gen_opc_pc[lj] = dc->pc; |
1150 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj] = 1;
|
1151 | 4acb54ba | Edgar E. Iglesias | gen_opc_icount[lj] = num_insns; |
1152 | 4acb54ba | Edgar E. Iglesias | } |
1153 | 4acb54ba | Edgar E. Iglesias | |
1154 | 4acb54ba | Edgar E. Iglesias | /* Pretty disas. */
|
1155 | 4acb54ba | Edgar E. Iglesias | LOG_DIS("%8.8x:\t", dc->pc);
|
1156 | 4acb54ba | Edgar E. Iglesias | |
1157 | 4acb54ba | Edgar E. Iglesias | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
1158 | 4acb54ba | Edgar E. Iglesias | gen_io_start(); |
1159 | 4acb54ba | Edgar E. Iglesias | |
1160 | 4acb54ba | Edgar E. Iglesias | dc->clear_imm = 1;
|
1161 | 4acb54ba | Edgar E. Iglesias | decode(dc); |
1162 | 4acb54ba | Edgar E. Iglesias | if (dc->clear_imm)
|
1163 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~IMM_FLAG; |
1164 | 4acb54ba | Edgar E. Iglesias | dc->ppc = dc->pc; |
1165 | 4acb54ba | Edgar E. Iglesias | dc->pc += 4;
|
1166 | 4acb54ba | Edgar E. Iglesias | num_insns++; |
1167 | 4acb54ba | Edgar E. Iglesias | |
1168 | 4acb54ba | Edgar E. Iglesias | if (dc->delayed_branch) {
|
1169 | 4acb54ba | Edgar E. Iglesias | dc->delayed_branch--; |
1170 | 4acb54ba | Edgar E. Iglesias | if (!dc->delayed_branch) {
|
1171 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTI_FLAG)
|
1172 | 4acb54ba | Edgar E. Iglesias | do_rti(dc); |
1173 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTB_FLAG)
|
1174 | 4acb54ba | Edgar E. Iglesias | do_rtb(dc); |
1175 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & DRTE_FLAG)
|
1176 | 4acb54ba | Edgar E. Iglesias | do_rte(dc); |
1177 | 4acb54ba | Edgar E. Iglesias | /* Clear the delay slot flag. */
|
1178 | 4acb54ba | Edgar E. Iglesias | dc->tb_flags &= ~D_FLAG; |
1179 | 4acb54ba | Edgar E. Iglesias | /* If it is a direct jump, try direct chaining. */
|
1180 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp != JMP_DIRECT) {
|
1181 | 4acb54ba | Edgar E. Iglesias | eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc)); |
1182 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_JUMP; |
1183 | 4acb54ba | Edgar E. Iglesias | } |
1184 | 4acb54ba | Edgar E. Iglesias | break;
|
1185 | 4acb54ba | Edgar E. Iglesias | } |
1186 | 4acb54ba | Edgar E. Iglesias | } |
1187 | 4acb54ba | Edgar E. Iglesias | if (env->singlestep_enabled)
|
1188 | 4acb54ba | Edgar E. Iglesias | break;
|
1189 | 4acb54ba | Edgar E. Iglesias | } while (!dc->is_jmp && !dc->cpustate_changed
|
1190 | 4acb54ba | Edgar E. Iglesias | && gen_opc_ptr < gen_opc_end |
1191 | 4acb54ba | Edgar E. Iglesias | && !singlestep |
1192 | 4acb54ba | Edgar E. Iglesias | && (dc->pc < next_page_start) |
1193 | 4acb54ba | Edgar E. Iglesias | && num_insns < max_insns); |
1194 | 4acb54ba | Edgar E. Iglesias | |
1195 | 4acb54ba | Edgar E. Iglesias | npc = dc->pc; |
1196 | 4acb54ba | Edgar E. Iglesias | if (dc->jmp == JMP_DIRECT) {
|
1197 | 4acb54ba | Edgar E. Iglesias | if (dc->tb_flags & D_FLAG) {
|
1198 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1199 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1200 | 4acb54ba | Edgar E. Iglesias | sync_jmpstate(dc); |
1201 | 4acb54ba | Edgar E. Iglesias | } else
|
1202 | 4acb54ba | Edgar E. Iglesias | npc = dc->jmp_pc; |
1203 | 4acb54ba | Edgar E. Iglesias | } |
1204 | 4acb54ba | Edgar E. Iglesias | |
1205 | 4acb54ba | Edgar E. Iglesias | if (tb->cflags & CF_LAST_IO)
|
1206 | 4acb54ba | Edgar E. Iglesias | gen_io_end(); |
1207 | 4acb54ba | Edgar E. Iglesias | /* Force an update if the per-tb cpu state has changed. */
|
1208 | 4acb54ba | Edgar E. Iglesias | if (dc->is_jmp == DISAS_NEXT
|
1209 | 4acb54ba | Edgar E. Iglesias | && (dc->cpustate_changed || org_flags != dc->tb_flags)) { |
1210 | 4acb54ba | Edgar E. Iglesias | dc->is_jmp = DISAS_UPDATE; |
1211 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1212 | 4acb54ba | Edgar E. Iglesias | } |
1213 | 4acb54ba | Edgar E. Iglesias | t_sync_flags(dc); |
1214 | 4acb54ba | Edgar E. Iglesias | |
1215 | 4acb54ba | Edgar E. Iglesias | if (unlikely(env->singlestep_enabled)) {
|
1216 | 4acb54ba | Edgar E. Iglesias | t_gen_raise_exception(dc, EXCP_DEBUG); |
1217 | 4acb54ba | Edgar E. Iglesias | if (dc->is_jmp == DISAS_NEXT)
|
1218 | 4acb54ba | Edgar E. Iglesias | tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |
1219 | 4acb54ba | Edgar E. Iglesias | } else {
|
1220 | 4acb54ba | Edgar E. Iglesias | switch(dc->is_jmp) {
|
1221 | 4acb54ba | Edgar E. Iglesias | case DISAS_NEXT:
|
1222 | 4acb54ba | Edgar E. Iglesias | gen_goto_tb(dc, 1, npc);
|
1223 | 4acb54ba | Edgar E. Iglesias | break;
|
1224 | 4acb54ba | Edgar E. Iglesias | default:
|
1225 | 4acb54ba | Edgar E. Iglesias | case DISAS_JUMP:
|
1226 | 4acb54ba | Edgar E. Iglesias | case DISAS_UPDATE:
|
1227 | 4acb54ba | Edgar E. Iglesias | /* indicate that the hash table must be used
|
1228 | 4acb54ba | Edgar E. Iglesias | to find the next TB */
|
1229 | 4acb54ba | Edgar E. Iglesias | tcg_gen_exit_tb(0);
|
1230 | 4acb54ba | Edgar E. Iglesias | break;
|
1231 | 4acb54ba | Edgar E. Iglesias | case DISAS_TB_JUMP:
|
1232 | 4acb54ba | Edgar E. Iglesias | /* nothing more to generate */
|
1233 | 4acb54ba | Edgar E. Iglesias | break;
|
1234 | 4acb54ba | Edgar E. Iglesias | } |
1235 | 4acb54ba | Edgar E. Iglesias | } |
1236 | 4acb54ba | Edgar E. Iglesias | gen_icount_end(tb, num_insns); |
1237 | 4acb54ba | Edgar E. Iglesias | *gen_opc_ptr = INDEX_op_end; |
1238 | 4acb54ba | Edgar E. Iglesias | if (search_pc) {
|
1239 | 4acb54ba | Edgar E. Iglesias | j = gen_opc_ptr - gen_opc_buf; |
1240 | 4acb54ba | Edgar E. Iglesias | lj++; |
1241 | 4acb54ba | Edgar E. Iglesias | while (lj <= j)
|
1242 | 4acb54ba | Edgar E. Iglesias | gen_opc_instr_start[lj++] = 0;
|
1243 | 4acb54ba | Edgar E. Iglesias | } else {
|
1244 | 4acb54ba | Edgar E. Iglesias | tb->size = dc->pc - pc_start; |
1245 | 4acb54ba | Edgar E. Iglesias | tb->icount = num_insns; |
1246 | 4acb54ba | Edgar E. Iglesias | } |
1247 | 4acb54ba | Edgar E. Iglesias | |
1248 | 4acb54ba | Edgar E. Iglesias | #ifdef DEBUG_DISAS
|
1249 | 4acb54ba | Edgar E. Iglesias | #if !SIM_COMPAT
|
1250 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
1251 | 4acb54ba | Edgar E. Iglesias | qemu_log("\n");
|
1252 | 4acb54ba | Edgar E. Iglesias | #if DISAS_GNU
|
1253 | 4acb54ba | Edgar E. Iglesias | log_target_disas(pc_start, dc->pc - pc_start, 0);
|
1254 | 4acb54ba | Edgar E. Iglesias | #endif
|
1255 | 4acb54ba | Edgar E. Iglesias | qemu_log("\nisize=%d osize=%zd\n",
|
1256 | 4acb54ba | Edgar E. Iglesias | dc->pc - pc_start, gen_opc_ptr - gen_opc_buf); |
1257 | 4acb54ba | Edgar E. Iglesias | } |
1258 | 4acb54ba | Edgar E. Iglesias | #endif
|
1259 | 4acb54ba | Edgar E. Iglesias | #endif
|
1260 | 4acb54ba | Edgar E. Iglesias | assert(!dc->abort_at_next_insn); |
1261 | 4acb54ba | Edgar E. Iglesias | } |
1262 | 4acb54ba | Edgar E. Iglesias | |
1263 | 4acb54ba | Edgar E. Iglesias | void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) |
1264 | 4acb54ba | Edgar E. Iglesias | { |
1265 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(env, tb, 0);
|
1266 | 4acb54ba | Edgar E. Iglesias | } |
1267 | 4acb54ba | Edgar E. Iglesias | |
1268 | 4acb54ba | Edgar E. Iglesias | void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) |
1269 | 4acb54ba | Edgar E. Iglesias | { |
1270 | 4acb54ba | Edgar E. Iglesias | gen_intermediate_code_internal(env, tb, 1);
|
1271 | 4acb54ba | Edgar E. Iglesias | } |
1272 | 4acb54ba | Edgar E. Iglesias | |
1273 | 4acb54ba | Edgar E. Iglesias | void cpu_dump_state (CPUState *env, FILE *f,
|
1274 | 4acb54ba | Edgar E. Iglesias | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), |
1275 | 4acb54ba | Edgar E. Iglesias | int flags)
|
1276 | 4acb54ba | Edgar E. Iglesias | { |
1277 | 4acb54ba | Edgar E. Iglesias | int i;
|
1278 | 4acb54ba | Edgar E. Iglesias | |
1279 | 4acb54ba | Edgar E. Iglesias | if (!env || !f)
|
1280 | 4acb54ba | Edgar E. Iglesias | return;
|
1281 | 4acb54ba | Edgar E. Iglesias | |
1282 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "IN: PC=%x %s\n",
|
1283 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC])); |
1284 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "rmsr=%x resr=%x debug[%x] imm=%x iflags=%x\n",
|
1285 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_MSR], env->sregs[SR_ESR], |
1286 | 4acb54ba | Edgar E. Iglesias | env->debug, env->imm, env->iflags); |
1287 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s)\n",
|
1288 | 4acb54ba | Edgar E. Iglesias | env->btaken, env->btarget, |
1289 | 4acb54ba | Edgar E. Iglesias | (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel", |
1290 | 4acb54ba | Edgar E. Iglesias | (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel"); |
1291 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < 32; i++) { |
1292 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
|
1293 | 4acb54ba | Edgar E. Iglesias | if ((i + 1) % 4 == 0) |
1294 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "\n");
|
1295 | 4acb54ba | Edgar E. Iglesias | } |
1296 | 4acb54ba | Edgar E. Iglesias | cpu_fprintf(f, "\n\n");
|
1297 | 4acb54ba | Edgar E. Iglesias | } |
1298 | 4acb54ba | Edgar E. Iglesias | |
1299 | 4acb54ba | Edgar E. Iglesias | CPUState *cpu_mb_init (const char *cpu_model) |
1300 | 4acb54ba | Edgar E. Iglesias | { |
1301 | 4acb54ba | Edgar E. Iglesias | CPUState *env; |
1302 | 4acb54ba | Edgar E. Iglesias | static int tcg_initialized = 0; |
1303 | 4acb54ba | Edgar E. Iglesias | int i;
|
1304 | 4acb54ba | Edgar E. Iglesias | |
1305 | 4acb54ba | Edgar E. Iglesias | env = qemu_mallocz(sizeof(CPUState));
|
1306 | 4acb54ba | Edgar E. Iglesias | |
1307 | 4acb54ba | Edgar E. Iglesias | cpu_exec_init(env); |
1308 | 4acb54ba | Edgar E. Iglesias | cpu_reset(env); |
1309 | 4acb54ba | Edgar E. Iglesias | |
1310 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
|
1311 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_BARREL_MASK \ |
1312 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_DIV_MASK \ |
1313 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_HW_MUL_MASK \ |
1314 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_EXC_MASK \ |
1315 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_ICACHE_MASK \ |
1316 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_DCACHE_MASK \ |
1317 | 4acb54ba | Edgar E. Iglesias | | PVR0_USE_MMU \ |
1318 | 4acb54ba | Edgar E. Iglesias | | (0xb << 8); |
1319 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[2] = PVR2_D_OPB_MASK \
|
1320 | 4acb54ba | Edgar E. Iglesias | | PVR2_D_LMB_MASK \ |
1321 | 4acb54ba | Edgar E. Iglesias | | PVR2_I_OPB_MASK \ |
1322 | 4acb54ba | Edgar E. Iglesias | | PVR2_I_LMB_MASK \ |
1323 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_MSR_INSTR \ |
1324 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_PCMP_INSTR \ |
1325 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_BARREL_MASK \ |
1326 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_DIV_MASK \ |
1327 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_HW_MUL_MASK \ |
1328 | 4acb54ba | Edgar E. Iglesias | | PVR2_USE_MUL64_MASK \ |
1329 | 4acb54ba | Edgar E. Iglesias | | 0;
|
1330 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family. */ |
1331 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[11] = PVR11_USE_MMU;
|
1332 | 4acb54ba | Edgar E. Iglesias | |
1333 | 4acb54ba | Edgar E. Iglesias | if (tcg_initialized)
|
1334 | 4acb54ba | Edgar E. Iglesias | return env;
|
1335 | 4acb54ba | Edgar E. Iglesias | |
1336 | 4acb54ba | Edgar E. Iglesias | tcg_initialized = 1;
|
1337 | 4acb54ba | Edgar E. Iglesias | |
1338 | 4acb54ba | Edgar E. Iglesias | cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
|
1339 | 4acb54ba | Edgar E. Iglesias | |
1340 | 4acb54ba | Edgar E. Iglesias | env_debug = tcg_global_mem_new(TCG_AREG0, |
1341 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, debug), |
1342 | 4acb54ba | Edgar E. Iglesias | "debug0");
|
1343 | 4acb54ba | Edgar E. Iglesias | env_iflags = tcg_global_mem_new(TCG_AREG0, |
1344 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, iflags), |
1345 | 4acb54ba | Edgar E. Iglesias | "iflags");
|
1346 | 4acb54ba | Edgar E. Iglesias | env_imm = tcg_global_mem_new(TCG_AREG0, |
1347 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, imm), |
1348 | 4acb54ba | Edgar E. Iglesias | "imm");
|
1349 | 4acb54ba | Edgar E. Iglesias | env_btarget = tcg_global_mem_new(TCG_AREG0, |
1350 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, btarget), |
1351 | 4acb54ba | Edgar E. Iglesias | "btarget");
|
1352 | 4acb54ba | Edgar E. Iglesias | env_btaken = tcg_global_mem_new(TCG_AREG0, |
1353 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, btaken), |
1354 | 4acb54ba | Edgar E. Iglesias | "btaken");
|
1355 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(cpu_R); i++) { |
1356 | 4acb54ba | Edgar E. Iglesias | cpu_R[i] = tcg_global_mem_new(TCG_AREG0, |
1357 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, regs[i]), |
1358 | 4acb54ba | Edgar E. Iglesias | regnames[i]); |
1359 | 4acb54ba | Edgar E. Iglesias | } |
1360 | 4acb54ba | Edgar E. Iglesias | for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) { |
1361 | 4acb54ba | Edgar E. Iglesias | cpu_SR[i] = tcg_global_mem_new(TCG_AREG0, |
1362 | 4acb54ba | Edgar E. Iglesias | offsetof(CPUState, sregs[i]), |
1363 | 4acb54ba | Edgar E. Iglesias | special_regnames[i]); |
1364 | 4acb54ba | Edgar E. Iglesias | } |
1365 | 4acb54ba | Edgar E. Iglesias | #define GEN_HELPER 2 |
1366 | 4acb54ba | Edgar E. Iglesias | #include "helper.h" |
1367 | 4acb54ba | Edgar E. Iglesias | |
1368 | 4acb54ba | Edgar E. Iglesias | return env;
|
1369 | 4acb54ba | Edgar E. Iglesias | } |
1370 | 4acb54ba | Edgar E. Iglesias | |
1371 | 4acb54ba | Edgar E. Iglesias | void cpu_reset (CPUState *env)
|
1372 | 4acb54ba | Edgar E. Iglesias | { |
1373 | 4acb54ba | Edgar E. Iglesias | if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
1374 | 4acb54ba | Edgar E. Iglesias | qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
1375 | 4acb54ba | Edgar E. Iglesias | log_cpu_state(env, 0);
|
1376 | 4acb54ba | Edgar E. Iglesias | } |
1377 | 4acb54ba | Edgar E. Iglesias | |
1378 | 4acb54ba | Edgar E. Iglesias | memset(env, 0, offsetof(CPUMBState, breakpoints));
|
1379 | 4acb54ba | Edgar E. Iglesias | tlb_flush(env, 1);
|
1380 | 4acb54ba | Edgar E. Iglesias | |
1381 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_MSR] = 0;
|
1382 | 4acb54ba | Edgar E. Iglesias | #if defined(CONFIG_USER_ONLY)
|
1383 | 4acb54ba | Edgar E. Iglesias | /* start in user mode with interrupts enabled. */
|
1384 | 4acb54ba | Edgar E. Iglesias | env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp. */ |
1385 | 4acb54ba | Edgar E. Iglesias | #else
|
1386 | 4acb54ba | Edgar E. Iglesias | mmu_init(&env->mmu); |
1387 | 4acb54ba | Edgar E. Iglesias | #endif
|
1388 | 4acb54ba | Edgar E. Iglesias | } |
1389 | 4acb54ba | Edgar E. Iglesias | |
1390 | 4acb54ba | Edgar E. Iglesias | void gen_pc_load(CPUState *env, struct TranslationBlock *tb, |
1391 | 4acb54ba | Edgar E. Iglesias | unsigned long searched_pc, int pc_pos, void *puc) |
1392 | 4acb54ba | Edgar E. Iglesias | { |
1393 | 4acb54ba | Edgar E. Iglesias | env->sregs[SR_PC] = gen_opc_pc[pc_pos]; |
1394 | 4acb54ba | Edgar E. Iglesias | } |