]> Git Repo - qemu.git/blame - target/openrisc/translate.c
target/openrisc: Tidy ppc/npc implementation
[qemu.git] / target / openrisc / translate.c
CommitLineData
e67db06e
JL
1/*
2 * OpenRISC translation
3 *
4 * Copyright (c) 2011-2012 Jia Liu <[email protected]>
5 * Feng Gao <[email protected]>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
ed2decc6 21#include "qemu/osdep.h"
e67db06e 22#include "cpu.h"
022c62cb 23#include "exec/exec-all.h"
76cad711 24#include "disas/disas.h"
e67db06e
JL
25#include "tcg-op.h"
26#include "qemu-common.h"
1de7afc9 27#include "qemu/log.h"
1de7afc9 28#include "qemu/bitops.h"
f08b6170 29#include "exec/cpu_ldst.h"
bbe418f2 30
2ef6175a
RH
31#include "exec/helper-proto.h"
32#include "exec/helper-gen.h"
e67db06e 33
a7e30d84 34#include "trace-tcg.h"
508127e2 35#include "exec/log.h"
a7e30d84 36
111ece51
RH
37#define LOG_DIS(str, ...) \
38 qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->pc, ## __VA_ARGS__)
e67db06e 39
bbe418f2
JL
40typedef struct DisasContext {
41 TranslationBlock *tb;
24c32852 42 target_ulong pc;
bbe418f2
JL
43 uint32_t tb_flags, synced_flags, flags;
44 uint32_t is_jmp;
45 uint32_t mem_idx;
46 int singlestep_enabled;
47 uint32_t delayed_branch;
48} DisasContext;
49
1bcea73e 50static TCGv_env cpu_env;
bbe418f2
JL
51static TCGv cpu_sr;
52static TCGv cpu_R[32];
53static TCGv cpu_pc;
54static TCGv jmp_pc; /* l.jr/l.jalr temp pc */
bbe418f2 55static TCGv cpu_ppc;
84775c43 56static TCGv cpu_sr_f; /* bf/bnf, F flag taken */
97458071
RH
57static TCGv cpu_sr_cy; /* carry (unsigned overflow) */
58static TCGv cpu_sr_ov; /* signed overflow */
930c3d00
RH
59static TCGv cpu_lock_addr;
60static TCGv cpu_lock_value;
bbe418f2 61static TCGv_i32 fpcsr;
6f7332ba 62static TCGv_i64 cpu_mac; /* MACHI:MACLO */
bbe418f2 63static TCGv_i32 env_flags;
022c62cb 64#include "exec/gen-icount.h"
bbe418f2 65
e67db06e
JL
66void openrisc_translate_init(void)
67{
bbe418f2
JL
68 static const char * const regnames[] = {
69 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
70 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
71 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
72 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
73 };
74 int i;
75
76 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7c255043 77 tcg_ctx.tcg_env = cpu_env;
e1ccc054 78 cpu_sr = tcg_global_mem_new(cpu_env,
bbe418f2 79 offsetof(CPUOpenRISCState, sr), "sr");
e1ccc054 80 env_flags = tcg_global_mem_new_i32(cpu_env,
bbe418f2
JL
81 offsetof(CPUOpenRISCState, flags),
82 "flags");
e1ccc054 83 cpu_pc = tcg_global_mem_new(cpu_env,
bbe418f2 84 offsetof(CPUOpenRISCState, pc), "pc");
e1ccc054 85 cpu_ppc = tcg_global_mem_new(cpu_env,
bbe418f2 86 offsetof(CPUOpenRISCState, ppc), "ppc");
e1ccc054 87 jmp_pc = tcg_global_mem_new(cpu_env,
bbe418f2 88 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
84775c43
RH
89 cpu_sr_f = tcg_global_mem_new(cpu_env,
90 offsetof(CPUOpenRISCState, sr_f), "sr_f");
97458071
RH
91 cpu_sr_cy = tcg_global_mem_new(cpu_env,
92 offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
93 cpu_sr_ov = tcg_global_mem_new(cpu_env,
94 offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
930c3d00
RH
95 cpu_lock_addr = tcg_global_mem_new(cpu_env,
96 offsetof(CPUOpenRISCState, lock_addr),
97 "lock_addr");
98 cpu_lock_value = tcg_global_mem_new(cpu_env,
99 offsetof(CPUOpenRISCState, lock_value),
100 "lock_value");
e1ccc054 101 fpcsr = tcg_global_mem_new_i32(cpu_env,
bbe418f2
JL
102 offsetof(CPUOpenRISCState, fpcsr),
103 "fpcsr");
6f7332ba
RH
104 cpu_mac = tcg_global_mem_new_i64(cpu_env,
105 offsetof(CPUOpenRISCState, mac),
106 "mac");
bbe418f2 107 for (i = 0; i < 32; i++) {
e1ccc054 108 cpu_R[i] = tcg_global_mem_new(cpu_env,
bbe418f2
JL
109 offsetof(CPUOpenRISCState, gpr[i]),
110 regnames[i]);
111 }
bbe418f2
JL
112}
113
bbe418f2
JL
114static inline void gen_sync_flags(DisasContext *dc)
115{
116 /* Sync the tb dependent flag between translate and runtime. */
0c53d734
RH
117 if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
118 tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
bbe418f2
JL
119 dc->synced_flags = dc->tb_flags;
120 }
121}
122
123static void gen_exception(DisasContext *dc, unsigned int excp)
124{
125 TCGv_i32 tmp = tcg_const_i32(excp);
126 gen_helper_exception(cpu_env, tmp);
127 tcg_temp_free_i32(tmp);
128}
129
130static void gen_illegal_exception(DisasContext *dc)
131{
132 tcg_gen_movi_tl(cpu_pc, dc->pc);
133 gen_exception(dc, EXCP_ILLEGAL);
134 dc->is_jmp = DISAS_UPDATE;
135}
136
137/* not used yet, open it when we need or64. */
138/*#ifdef TARGET_OPENRISC64
139static void check_ob64s(DisasContext *dc)
140{
141 if (!(dc->flags & CPUCFGR_OB64S)) {
142 gen_illegal_exception(dc);
143 }
144}
145
146static void check_of64s(DisasContext *dc)
147{
148 if (!(dc->flags & CPUCFGR_OF64S)) {
149 gen_illegal_exception(dc);
150 }
151}
152
153static void check_ov64s(DisasContext *dc)
154{
155 if (!(dc->flags & CPUCFGR_OV64S)) {
156 gen_illegal_exception(dc);
157 }
158}
159#endif*/
160
90aa39a1
SF
161static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
162{
163 if (unlikely(dc->singlestep_enabled)) {
164 return false;
165 }
166
167#ifndef CONFIG_USER_ONLY
168 return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
169#else
170 return true;
171#endif
172}
173
bbe418f2
JL
174static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
175{
90aa39a1 176 if (use_goto_tb(dc, dest)) {
bbe418f2
JL
177 tcg_gen_movi_tl(cpu_pc, dest);
178 tcg_gen_goto_tb(n);
90aa39a1 179 tcg_gen_exit_tb((uintptr_t)dc->tb + n);
bbe418f2
JL
180 } else {
181 tcg_gen_movi_tl(cpu_pc, dest);
182 if (dc->singlestep_enabled) {
183 gen_exception(dc, EXCP_DEBUG);
184 }
185 tcg_gen_exit_tb(0);
186 }
187}
188
6da544a6 189static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
bbe418f2 190{
6da544a6 191 target_ulong tmp_pc = dc->pc + n26 * 4;
bbe418f2 192
da1d7759
SM
193 switch (op0) {
194 case 0x00: /* l.j */
bbe418f2 195 tcg_gen_movi_tl(jmp_pc, tmp_pc);
da1d7759
SM
196 break;
197 case 0x01: /* l.jal */
a8000cb4
RH
198 tcg_gen_movi_tl(cpu_R[9], dc->pc + 8);
199 /* Optimize jal being used to load the PC for PIC. */
200 if (tmp_pc == dc->pc + 8) {
201 return;
202 }
bbe418f2 203 tcg_gen_movi_tl(jmp_pc, tmp_pc);
da1d7759
SM
204 break;
205 case 0x03: /* l.bnf */
206 case 0x04: /* l.bf */
207 {
784696d1
RH
208 TCGv t_next = tcg_const_tl(dc->pc + 8);
209 TCGv t_true = tcg_const_tl(tmp_pc);
210 TCGv t_zero = tcg_const_tl(0);
211
212 tcg_gen_movcond_tl(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
213 jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
214
215 tcg_temp_free(t_next);
216 tcg_temp_free(t_true);
217 tcg_temp_free(t_zero);
da1d7759
SM
218 }
219 break;
220 case 0x11: /* l.jr */
bbe418f2 221 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
da1d7759
SM
222 break;
223 case 0x12: /* l.jalr */
bbe418f2
JL
224 tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
225 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
da1d7759
SM
226 break;
227 default:
bbe418f2 228 gen_illegal_exception(dc);
da1d7759 229 break;
bbe418f2
JL
230 }
231
bbe418f2
JL
232 dc->delayed_branch = 2;
233 dc->tb_flags |= D_FLAG;
234 gen_sync_flags(dc);
235}
236
97458071 237static void gen_ove_cy(DisasContext *dc)
9ecaa27e 238{
0c53d734 239 if (dc->tb_flags & SR_OVE) {
97458071 240 gen_helper_ove_cy(cpu_env);
0c53d734 241 }
9ecaa27e
RH
242}
243
97458071 244static void gen_ove_ov(DisasContext *dc)
9ecaa27e 245{
0c53d734 246 if (dc->tb_flags & SR_OVE) {
97458071 247 gen_helper_ove_ov(cpu_env);
0c53d734 248 }
9ecaa27e
RH
249}
250
97458071 251static void gen_ove_cyov(DisasContext *dc)
9ecaa27e 252{
0c53d734 253 if (dc->tb_flags & SR_OVE) {
97458071 254 gen_helper_ove_cyov(cpu_env);
0c53d734 255 }
9ecaa27e
RH
256}
257
258static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
259{
260 TCGv t0 = tcg_const_tl(0);
261 TCGv res = tcg_temp_new();
9ecaa27e 262
97458071
RH
263 tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
264 tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
9ecaa27e 265 tcg_gen_xor_tl(t0, res, srcb);
97458071 266 tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
9ecaa27e
RH
267 tcg_temp_free(t0);
268
269 tcg_gen_mov_tl(dest, res);
270 tcg_temp_free(res);
271
97458071 272 gen_ove_cyov(dc);
9ecaa27e
RH
273}
274
275static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
276{
277 TCGv t0 = tcg_const_tl(0);
278 TCGv res = tcg_temp_new();
9ecaa27e 279
97458071
RH
280 tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
281 tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
282 tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
9ecaa27e 283 tcg_gen_xor_tl(t0, res, srcb);
97458071 284 tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
9ecaa27e
RH
285 tcg_temp_free(t0);
286
287 tcg_gen_mov_tl(dest, res);
288 tcg_temp_free(res);
289
97458071 290 gen_ove_cyov(dc);
9ecaa27e
RH
291}
292
293static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
294{
295 TCGv res = tcg_temp_new();
9ecaa27e
RH
296
297 tcg_gen_sub_tl(res, srca, srcb);
97458071
RH
298 tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
299 tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
300 tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
301 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
9ecaa27e
RH
302
303 tcg_gen_mov_tl(dest, res);
304 tcg_temp_free(res);
305
97458071 306 gen_ove_cyov(dc);
9ecaa27e
RH
307}
308
309static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
310{
9ecaa27e
RH
311 TCGv t0 = tcg_temp_new();
312
97458071 313 tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
9ecaa27e 314 tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
97458071 315 tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
9ecaa27e
RH
316 tcg_temp_free(t0);
317
97458071
RH
318 tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
319 gen_ove_ov(dc);
9ecaa27e
RH
320}
321
322static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
323{
97458071
RH
324 tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
325 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
9ecaa27e 326
97458071 327 gen_ove_cy(dc);
9ecaa27e
RH
328}
329
330static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
331{
9ecaa27e
RH
332 TCGv t0 = tcg_temp_new();
333
97458071 334 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
9ecaa27e
RH
335 /* The result of divide-by-zero is undefined.
336 Supress the host-side exception by dividing by 1. */
97458071 337 tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
9ecaa27e
RH
338 tcg_gen_div_tl(dest, srca, t0);
339 tcg_temp_free(t0);
340
97458071
RH
341 tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
342 gen_ove_ov(dc);
9ecaa27e
RH
343}
344
345static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
346{
9ecaa27e
RH
347 TCGv t0 = tcg_temp_new();
348
97458071 349 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
9ecaa27e
RH
350 /* The result of divide-by-zero is undefined.
351 Supress the host-side exception by dividing by 1. */
97458071 352 tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
9ecaa27e
RH
353 tcg_gen_divu_tl(dest, srca, t0);
354 tcg_temp_free(t0);
355
97458071 356 gen_ove_cy(dc);
9ecaa27e 357}
da1d7759 358
cc5de49e
RH
359static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
360{
361 TCGv_i64 t1 = tcg_temp_new_i64();
362 TCGv_i64 t2 = tcg_temp_new_i64();
363
364 tcg_gen_ext_tl_i64(t1, srca);
365 tcg_gen_ext_tl_i64(t2, srcb);
366 if (TARGET_LONG_BITS == 32) {
367 tcg_gen_mul_i64(cpu_mac, t1, t2);
368 tcg_gen_movi_tl(cpu_sr_ov, 0);
369 } else {
370 TCGv_i64 high = tcg_temp_new_i64();
371
372 tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
373 tcg_gen_sari_i64(t1, cpu_mac, 63);
374 tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
375 tcg_temp_free_i64(high);
376 tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
377 tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
378
379 gen_ove_ov(dc);
380 }
381 tcg_temp_free_i64(t1);
382 tcg_temp_free_i64(t2);
383}
384
385static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
386{
387 TCGv_i64 t1 = tcg_temp_new_i64();
388 TCGv_i64 t2 = tcg_temp_new_i64();
389
390 tcg_gen_extu_tl_i64(t1, srca);
391 tcg_gen_extu_tl_i64(t2, srcb);
392 if (TARGET_LONG_BITS == 32) {
393 tcg_gen_mul_i64(cpu_mac, t1, t2);
394 tcg_gen_movi_tl(cpu_sr_cy, 0);
395 } else {
396 TCGv_i64 high = tcg_temp_new_i64();
397
398 tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
399 tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
400 tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
401 tcg_temp_free_i64(high);
402
403 gen_ove_cy(dc);
404 }
405 tcg_temp_free_i64(t1);
406 tcg_temp_free_i64(t2);
407}
408
6f7332ba
RH
409static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
410{
411 TCGv_i64 t1 = tcg_temp_new_i64();
412 TCGv_i64 t2 = tcg_temp_new_i64();
413
414 tcg_gen_ext_tl_i64(t1, srca);
415 tcg_gen_ext_tl_i64(t2, srcb);
416 tcg_gen_mul_i64(t1, t1, t2);
417
418 /* Note that overflow is only computed during addition stage. */
419 tcg_gen_xor_i64(t2, cpu_mac, t1);
420 tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
421 tcg_gen_xor_i64(t1, t1, cpu_mac);
422 tcg_gen_andc_i64(t1, t1, t2);
423 tcg_temp_free_i64(t2);
424
425#if TARGET_LONG_BITS == 32
426 tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
427#else
428 tcg_gen_mov_i64(cpu_sr_ov, t1);
429#endif
430 tcg_temp_free_i64(t1);
431
432 gen_ove_ov(dc);
433}
434
cc5de49e
RH
435static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
436{
437 TCGv_i64 t1 = tcg_temp_new_i64();
438 TCGv_i64 t2 = tcg_temp_new_i64();
439
440 tcg_gen_extu_tl_i64(t1, srca);
441 tcg_gen_extu_tl_i64(t2, srcb);
442 tcg_gen_mul_i64(t1, t1, t2);
443 tcg_temp_free_i64(t2);
444
445 /* Note that overflow is only computed during addition stage. */
446 tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
447 tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
448 tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
449 tcg_temp_free_i64(t1);
450
451 gen_ove_cy(dc);
452}
453
6f7332ba
RH
454static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
455{
456 TCGv_i64 t1 = tcg_temp_new_i64();
457 TCGv_i64 t2 = tcg_temp_new_i64();
458
459 tcg_gen_ext_tl_i64(t1, srca);
460 tcg_gen_ext_tl_i64(t2, srcb);
461 tcg_gen_mul_i64(t1, t1, t2);
462
463 /* Note that overflow is only computed during subtraction stage. */
464 tcg_gen_xor_i64(t2, cpu_mac, t1);
465 tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
466 tcg_gen_xor_i64(t1, t1, cpu_mac);
467 tcg_gen_and_i64(t1, t1, t2);
468 tcg_temp_free_i64(t2);
469
470#if TARGET_LONG_BITS == 32
471 tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
472#else
473 tcg_gen_mov_i64(cpu_sr_ov, t1);
474#endif
475 tcg_temp_free_i64(t1);
476
477 gen_ove_ov(dc);
478}
479
cc5de49e
RH
480static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
481{
482 TCGv_i64 t1 = tcg_temp_new_i64();
483 TCGv_i64 t2 = tcg_temp_new_i64();
484
485 tcg_gen_extu_tl_i64(t1, srca);
486 tcg_gen_extu_tl_i64(t2, srcb);
487 tcg_gen_mul_i64(t1, t1, t2);
488
489 /* Note that overflow is only computed during subtraction stage. */
490 tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
491 tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
492 tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
493 tcg_temp_free_i64(t2);
494 tcg_temp_free_i64(t1);
495
496 gen_ove_cy(dc);
497}
498
930c3d00
RH
499static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
500{
501 TCGv ea = tcg_temp_new();
502
503 tcg_gen_addi_tl(ea, ra, ofs);
504 tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL);
505 tcg_gen_mov_tl(cpu_lock_addr, ea);
506 tcg_gen_mov_tl(cpu_lock_value, rd);
507 tcg_temp_free(ea);
508}
509
510static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)
511{
512 TCGv ea, val;
513 TCGLabel *lab_fail, *lab_done;
514
515 ea = tcg_temp_new();
516 tcg_gen_addi_tl(ea, ra, ofs);
517
518 lab_fail = gen_new_label();
519 lab_done = gen_new_label();
520 tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
521 tcg_temp_free(ea);
522
523 val = tcg_temp_new();
524 tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
525 rb, dc->mem_idx, MO_TEUL);
84775c43 526 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
930c3d00
RH
527 tcg_temp_free(val);
528
529 tcg_gen_br(lab_done);
530
531 gen_set_label(lab_fail);
84775c43 532 tcg_gen_movi_tl(cpu_sr_f, 0);
930c3d00
RH
533
534 gen_set_label(lab_done);
535 tcg_gen_movi_tl(cpu_lock_addr, -1);
930c3d00
RH
536}
537
bbe418f2
JL
538static void dec_calc(DisasContext *dc, uint32_t insn)
539{
540 uint32_t op0, op1, op2;
541 uint32_t ra, rb, rd;
542 op0 = extract32(insn, 0, 4);
543 op1 = extract32(insn, 8, 2);
544 op2 = extract32(insn, 6, 2);
545 ra = extract32(insn, 16, 5);
546 rb = extract32(insn, 11, 5);
547 rd = extract32(insn, 21, 5);
548
cf2ae442
RH
549 switch (op1) {
550 case 0:
551 switch (op0) {
552 case 0x0: /* l.add */
bbe418f2 553 LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
9ecaa27e 554 gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 555 return;
bbe418f2 556
cf2ae442 557 case 0x1: /* l.addc */
bbe418f2 558 LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
9ecaa27e 559 gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 560 return;
bbe418f2 561
cf2ae442 562 case 0x2: /* l.sub */
bbe418f2 563 LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
9ecaa27e 564 gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 565 return;
bbe418f2 566
cf2ae442 567 case 0x3: /* l.and */
bbe418f2
JL
568 LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
569 tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 570 return;
bbe418f2 571
cf2ae442 572 case 0x4: /* l.or */
bbe418f2
JL
573 LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
574 tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 575 return;
bbe418f2 576
cf2ae442 577 case 0x5: /* l.xor */
bbe418f2
JL
578 LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
579 tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
cf2ae442 580 return;
bbe418f2 581
cf2ae442
RH
582 case 0x8:
583 switch (op2) {
584 case 0: /* l.sll */
585 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
586 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
587 return;
588 case 1: /* l.srl */
589 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
590 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
591 return;
592 case 2: /* l.sra */
593 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
594 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
595 return;
596 case 3: /* l.ror */
597 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
598 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
599 return;
600 }
bbe418f2 601 break;
bbe418f2 602
cf2ae442
RH
603 case 0xc:
604 switch (op2) {
605 case 0: /* l.exths */
606 LOG_DIS("l.exths r%d, r%d\n", rd, ra);
607 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
608 return;
609 case 1: /* l.extbs */
610 LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
611 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
612 return;
613 case 2: /* l.exthz */
614 LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
615 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
616 return;
617 case 3: /* l.extbz */
618 LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
619 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
620 return;
621 }
bbe418f2
JL
622 break;
623
cf2ae442
RH
624 case 0xd:
625 switch (op2) {
626 case 0: /* l.extws */
627 LOG_DIS("l.extws r%d, r%d\n", rd, ra);
628 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
629 return;
630 case 1: /* l.extwz */
631 LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
632 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
633 return;
634 }
bbe418f2 635 break;
bbe418f2 636
cf2ae442 637 case 0xe: /* l.cmov */
bbe418f2
JL
638 LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
639 {
784696d1
RH
640 TCGv zero = tcg_const_tl(0);
641 tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero,
642 cpu_R[ra], cpu_R[rb]);
643 tcg_temp_free(zero);
bbe418f2 644 }
cf2ae442 645 return;
bbe418f2 646
cf2ae442 647 case 0xf: /* l.ff1 */
bbe418f2 648 LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
555baef8
RH
649 tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);
650 tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);
cf2ae442
RH
651 return;
652 }
653 break;
654
655 case 1:
656 switch (op0) {
657 case 0xf: /* l.fl1 */
bbe418f2 658 LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
555baef8
RH
659 tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);
660 tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);
cf2ae442 661 return;
bbe418f2
JL
662 }
663 break;
664
cf2ae442 665 case 2:
bbe418f2
JL
666 break;
667
cf2ae442
RH
668 case 3:
669 switch (op0) {
670 case 0x6: /* l.mul */
671 LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
672 gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
673 return;
bbe418f2 674
cc5de49e
RH
675 case 0x7: /* l.muld */
676 LOG_DIS("l.muld r%d, r%d\n", ra, rb);
677 gen_muld(dc, cpu_R[ra], cpu_R[rb]);
678 break;
679
cf2ae442
RH
680 case 0x9: /* l.div */
681 LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
682 gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
683 return;
bbe418f2 684
cf2ae442
RH
685 case 0xa: /* l.divu */
686 LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
687 gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
688 return;
bbe418f2 689
cf2ae442
RH
690 case 0xb: /* l.mulu */
691 LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
692 gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
693 return;
cc5de49e
RH
694
695 case 0xc: /* l.muldu */
696 LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
697 gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
698 return;
bbe418f2
JL
699 }
700 break;
bbe418f2 701 }
cf2ae442 702 gen_illegal_exception(dc);
bbe418f2
JL
703}
704
705static void dec_misc(DisasContext *dc, uint32_t insn)
706{
707 uint32_t op0, op1;
708 uint32_t ra, rb, rd;
6da544a6
RH
709 uint32_t L6, K5, K16, K5_11;
710 int32_t I16, I5_11, N26;
5631e69c 711 TCGMemOp mop;
9ecaa27e 712 TCGv t0;
5631e69c 713
bbe418f2
JL
714 op0 = extract32(insn, 26, 6);
715 op1 = extract32(insn, 24, 2);
716 ra = extract32(insn, 16, 5);
717 rb = extract32(insn, 11, 5);
718 rd = extract32(insn, 21, 5);
bbe418f2
JL
719 L6 = extract32(insn, 5, 6);
720 K5 = extract32(insn, 0, 5);
6da544a6
RH
721 K16 = extract32(insn, 0, 16);
722 I16 = (int16_t)K16;
723 N26 = sextract32(insn, 0, 26);
724 K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11);
725 I5_11 = (int16_t)K5_11;
bbe418f2
JL
726
727 switch (op0) {
728 case 0x00: /* l.j */
729 LOG_DIS("l.j %d\n", N26);
730 gen_jump(dc, N26, 0, op0);
731 break;
732
733 case 0x01: /* l.jal */
734 LOG_DIS("l.jal %d\n", N26);
735 gen_jump(dc, N26, 0, op0);
736 break;
737
738 case 0x03: /* l.bnf */
739 LOG_DIS("l.bnf %d\n", N26);
740 gen_jump(dc, N26, 0, op0);
741 break;
742
743 case 0x04: /* l.bf */
744 LOG_DIS("l.bf %d\n", N26);
745 gen_jump(dc, N26, 0, op0);
746 break;
747
748 case 0x05:
749 switch (op1) {
750 case 0x01: /* l.nop */
751 LOG_DIS("l.nop %d\n", I16);
752 break;
753
754 default:
755 gen_illegal_exception(dc);
756 break;
757 }
758 break;
759
760 case 0x11: /* l.jr */
761 LOG_DIS("l.jr r%d\n", rb);
762 gen_jump(dc, 0, rb, op0);
763 break;
764
765 case 0x12: /* l.jalr */
766 LOG_DIS("l.jalr r%d\n", rb);
767 gen_jump(dc, 0, rb, op0);
768 break;
769
770 case 0x13: /* l.maci */
6da544a6 771 LOG_DIS("l.maci r%d, %d\n", ra, I16);
6f7332ba
RH
772 t0 = tcg_const_tl(I16);
773 gen_mac(dc, cpu_R[ra], t0);
774 tcg_temp_free(t0);
bbe418f2
JL
775 break;
776
777 case 0x09: /* l.rfe */
778 LOG_DIS("l.rfe\n");
779 {
780#if defined(CONFIG_USER_ONLY)
781 return;
782#else
783 if (dc->mem_idx == MMU_USER_IDX) {
784 gen_illegal_exception(dc);
785 return;
786 }
787 gen_helper_rfe(cpu_env);
788 dc->is_jmp = DISAS_UPDATE;
789#endif
790 }
791 break;
792
930c3d00
RH
793 case 0x1b: /* l.lwa */
794 LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
795 gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16);
796 break;
797
bbe418f2
JL
798 case 0x1c: /* l.cust1 */
799 LOG_DIS("l.cust1\n");
800 break;
801
802 case 0x1d: /* l.cust2 */
803 LOG_DIS("l.cust2\n");
804 break;
805
806 case 0x1e: /* l.cust3 */
807 LOG_DIS("l.cust3\n");
808 break;
809
810 case 0x1f: /* l.cust4 */
811 LOG_DIS("l.cust4\n");
812 break;
813
814 case 0x3c: /* l.cust5 */
815 LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5);
816 break;
817
818 case 0x3d: /* l.cust6 */
819 LOG_DIS("l.cust6\n");
820 break;
821
822 case 0x3e: /* l.cust7 */
823 LOG_DIS("l.cust7\n");
824 break;
825
826 case 0x3f: /* l.cust8 */
827 LOG_DIS("l.cust8\n");
828 break;
829
830/* not used yet, open it when we need or64. */
831/*#ifdef TARGET_OPENRISC64
832 case 0x20: l.ld
833 LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
834 check_ob64s(dc);
835 mop = MO_TEQ;
836 goto do_load;
bbe418f2
JL
837#endif*/
838
839 case 0x21: /* l.lwz */
840 LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
841 mop = MO_TEUL;
842 goto do_load;
bbe418f2
JL
843
844 case 0x22: /* l.lws */
845 LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
846 mop = MO_TESL;
847 goto do_load;
bbe418f2
JL
848
849 case 0x23: /* l.lbz */
850 LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
851 mop = MO_UB;
852 goto do_load;
bbe418f2
JL
853
854 case 0x24: /* l.lbs */
855 LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
856 mop = MO_SB;
857 goto do_load;
bbe418f2
JL
858
859 case 0x25: /* l.lhz */
860 LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
861 mop = MO_TEUW;
862 goto do_load;
bbe418f2
JL
863
864 case 0x26: /* l.lhs */
865 LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16);
5631e69c
RH
866 mop = MO_TESW;
867 goto do_load;
868
869 do_load:
bbe418f2
JL
870 {
871 TCGv t0 = tcg_temp_new();
6da544a6 872 tcg_gen_addi_tl(t0, cpu_R[ra], I16);
5631e69c 873 tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop);
bbe418f2
JL
874 tcg_temp_free(t0);
875 }
876 break;
877
878 case 0x27: /* l.addi */
879 LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
9ecaa27e
RH
880 t0 = tcg_const_tl(I16);
881 gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
882 tcg_temp_free(t0);
bbe418f2
JL
883 break;
884
885 case 0x28: /* l.addic */
886 LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
9ecaa27e
RH
887 t0 = tcg_const_tl(I16);
888 gen_addc(dc, cpu_R[rd], cpu_R[ra], t0);
889 tcg_temp_free(t0);
bbe418f2
JL
890 break;
891
892 case 0x29: /* l.andi */
6da544a6
RH
893 LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16);
894 tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16);
bbe418f2
JL
895 break;
896
897 case 0x2a: /* l.ori */
6da544a6
RH
898 LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16);
899 tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16);
bbe418f2
JL
900 break;
901
902 case 0x2b: /* l.xori */
903 LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
6da544a6 904 tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16);
bbe418f2
JL
905 break;
906
907 case 0x2c: /* l.muli */
908 LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
9ecaa27e
RH
909 t0 = tcg_const_tl(I16);
910 gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
911 tcg_temp_free(t0);
bbe418f2
JL
912 break;
913
914 case 0x2d: /* l.mfspr */
6da544a6 915 LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
4dd044c6
JL
916 {
917#if defined(CONFIG_USER_ONLY)
918 return;
919#else
6da544a6 920 TCGv_i32 ti = tcg_const_i32(K16);
4dd044c6
JL
921 if (dc->mem_idx == MMU_USER_IDX) {
922 gen_illegal_exception(dc);
923 return;
924 }
925 gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
926 tcg_temp_free_i32(ti);
927#endif
928 }
bbe418f2
JL
929 break;
930
931 case 0x30: /* l.mtspr */
6da544a6 932 LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
4dd044c6
JL
933 {
934#if defined(CONFIG_USER_ONLY)
935 return;
936#else
6da544a6 937 TCGv_i32 im = tcg_const_i32(K5_11);
4dd044c6
JL
938 if (dc->mem_idx == MMU_USER_IDX) {
939 gen_illegal_exception(dc);
940 return;
941 }
942 gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
943 tcg_temp_free_i32(im);
944#endif
945 }
bbe418f2
JL
946 break;
947
930c3d00 948 case 0x33: /* l.swa */
6da544a6
RH
949 LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11);
950 gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11);
930c3d00
RH
951 break;
952
bbe418f2
JL
953/* not used yet, open it when we need or64. */
954/*#ifdef TARGET_OPENRISC64
955 case 0x34: l.sd
6da544a6 956 LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
5631e69c
RH
957 check_ob64s(dc);
958 mop = MO_TEQ;
959 goto do_store;
bbe418f2
JL
960#endif*/
961
962 case 0x35: /* l.sw */
6da544a6 963 LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11);
5631e69c
RH
964 mop = MO_TEUL;
965 goto do_store;
bbe418f2
JL
966
967 case 0x36: /* l.sb */
6da544a6 968 LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11);
5631e69c
RH
969 mop = MO_UB;
970 goto do_store;
bbe418f2
JL
971
972 case 0x37: /* l.sh */
6da544a6 973 LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11);
5631e69c
RH
974 mop = MO_TEUW;
975 goto do_store;
976
977 do_store:
bbe418f2
JL
978 {
979 TCGv t0 = tcg_temp_new();
6da544a6 980 tcg_gen_addi_tl(t0, cpu_R[ra], I5_11);
5631e69c 981 tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop);
bbe418f2
JL
982 tcg_temp_free(t0);
983 }
984 break;
985
986 default:
987 gen_illegal_exception(dc);
988 break;
989 }
990}
991
992static void dec_mac(DisasContext *dc, uint32_t insn)
993{
994 uint32_t op0;
995 uint32_t ra, rb;
996 op0 = extract32(insn, 0, 4);
997 ra = extract32(insn, 16, 5);
998 rb = extract32(insn, 11, 5);
999
1000 switch (op0) {
1001 case 0x0001: /* l.mac */
1002 LOG_DIS("l.mac r%d, r%d\n", ra, rb);
6f7332ba 1003 gen_mac(dc, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1004 break;
1005
1006 case 0x0002: /* l.msb */
1007 LOG_DIS("l.msb r%d, r%d\n", ra, rb);
6f7332ba 1008 gen_msb(dc, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1009 break;
1010
cc5de49e
RH
1011 case 0x0003: /* l.macu */
1012 LOG_DIS("l.macu r%d, r%d\n", ra, rb);
1013 gen_macu(dc, cpu_R[ra], cpu_R[rb]);
1014 break;
1015
1016 case 0x0004: /* l.msbu */
1017 LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
1018 gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
1019 break;
1020
bbe418f2
JL
1021 default:
1022 gen_illegal_exception(dc);
1023 break;
1024 }
1025}
1026
1027static void dec_logic(DisasContext *dc, uint32_t insn)
1028{
1029 uint32_t op0;
6da544a6 1030 uint32_t rd, ra, L6, S6;
bbe418f2
JL
1031 op0 = extract32(insn, 6, 2);
1032 rd = extract32(insn, 21, 5);
1033 ra = extract32(insn, 16, 5);
1034 L6 = extract32(insn, 0, 6);
6da544a6 1035 S6 = L6 & (TARGET_LONG_BITS - 1);
bbe418f2
JL
1036
1037 switch (op0) {
1038 case 0x00: /* l.slli */
1039 LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
6da544a6 1040 tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6);
bbe418f2
JL
1041 break;
1042
1043 case 0x01: /* l.srli */
1044 LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
6da544a6 1045 tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6);
bbe418f2
JL
1046 break;
1047
1048 case 0x02: /* l.srai */
1049 LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
6da544a6
RH
1050 tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6);
1051 break;
bbe418f2
JL
1052
1053 case 0x03: /* l.rori */
1054 LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
6da544a6 1055 tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6);
bbe418f2
JL
1056 break;
1057
1058 default:
1059 gen_illegal_exception(dc);
1060 break;
1061 }
1062}
1063
1064static void dec_M(DisasContext *dc, uint32_t insn)
1065{
1066 uint32_t op0;
1067 uint32_t rd;
1068 uint32_t K16;
1069 op0 = extract32(insn, 16, 1);
1070 rd = extract32(insn, 21, 5);
1071 K16 = extract32(insn, 0, 16);
1072
1073 switch (op0) {
1074 case 0x0: /* l.movhi */
1075 LOG_DIS("l.movhi r%d, %d\n", rd, K16);
1076 tcg_gen_movi_tl(cpu_R[rd], (K16 << 16));
1077 break;
1078
1079 case 0x1: /* l.macrc */
1080 LOG_DIS("l.macrc r%d\n", rd);
6f7332ba
RH
1081 tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
1082 tcg_gen_movi_i64(cpu_mac, 0);
bbe418f2
JL
1083 break;
1084
1085 default:
1086 gen_illegal_exception(dc);
1087 break;
1088 }
1089}
1090
1091static void dec_comp(DisasContext *dc, uint32_t insn)
1092{
1093 uint32_t op0;
1094 uint32_t ra, rb;
1095
1096 op0 = extract32(insn, 21, 5);
1097 ra = extract32(insn, 16, 5);
1098 rb = extract32(insn, 11, 5);
1099
bbe418f2
JL
1100 /* unsigned integers */
1101 tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
1102 tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
1103
1104 switch (op0) {
1105 case 0x0: /* l.sfeq */
1106 LOG_DIS("l.sfeq r%d, r%d\n", ra, rb);
84775c43 1107 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1108 break;
1109
1110 case 0x1: /* l.sfne */
1111 LOG_DIS("l.sfne r%d, r%d\n", ra, rb);
84775c43 1112 tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1113 break;
1114
1115 case 0x2: /* l.sfgtu */
1116 LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb);
84775c43 1117 tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1118 break;
1119
1120 case 0x3: /* l.sfgeu */
1121 LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb);
84775c43 1122 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1123 break;
1124
1125 case 0x4: /* l.sfltu */
1126 LOG_DIS("l.sfltu r%d, r%d\n", ra, rb);
84775c43 1127 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1128 break;
1129
1130 case 0x5: /* l.sfleu */
1131 LOG_DIS("l.sfleu r%d, r%d\n", ra, rb);
84775c43 1132 tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1133 break;
1134
1135 case 0xa: /* l.sfgts */
1136 LOG_DIS("l.sfgts r%d, r%d\n", ra, rb);
84775c43 1137 tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1138 break;
1139
1140 case 0xb: /* l.sfges */
1141 LOG_DIS("l.sfges r%d, r%d\n", ra, rb);
84775c43 1142 tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1143 break;
1144
1145 case 0xc: /* l.sflts */
1146 LOG_DIS("l.sflts r%d, r%d\n", ra, rb);
84775c43 1147 tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1148 break;
1149
1150 case 0xd: /* l.sfles */
1151 LOG_DIS("l.sfles r%d, r%d\n", ra, rb);
84775c43 1152 tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1153 break;
1154
1155 default:
1156 gen_illegal_exception(dc);
1157 break;
1158 }
bbe418f2
JL
1159}
1160
1161static void dec_compi(DisasContext *dc, uint32_t insn)
1162{
6da544a6
RH
1163 uint32_t op0, ra;
1164 int32_t I16;
bbe418f2
JL
1165
1166 op0 = extract32(insn, 21, 5);
1167 ra = extract32(insn, 16, 5);
6da544a6 1168 I16 = sextract32(insn, 0, 16);
bbe418f2 1169
bbe418f2
JL
1170 switch (op0) {
1171 case 0x0: /* l.sfeqi */
1172 LOG_DIS("l.sfeqi r%d, %d\n", ra, I16);
84775c43 1173 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1174 break;
1175
1176 case 0x1: /* l.sfnei */
1177 LOG_DIS("l.sfnei r%d, %d\n", ra, I16);
84775c43 1178 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1179 break;
1180
1181 case 0x2: /* l.sfgtui */
1182 LOG_DIS("l.sfgtui r%d, %d\n", ra, I16);
84775c43 1183 tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1184 break;
1185
1186 case 0x3: /* l.sfgeui */
1187 LOG_DIS("l.sfgeui r%d, %d\n", ra, I16);
84775c43 1188 tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1189 break;
1190
1191 case 0x4: /* l.sfltui */
1192 LOG_DIS("l.sfltui r%d, %d\n", ra, I16);
84775c43 1193 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1194 break;
1195
1196 case 0x5: /* l.sfleui */
1197 LOG_DIS("l.sfleui r%d, %d\n", ra, I16);
84775c43 1198 tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1199 break;
1200
1201 case 0xa: /* l.sfgtsi */
1202 LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16);
84775c43 1203 tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1204 break;
1205
1206 case 0xb: /* l.sfgesi */
1207 LOG_DIS("l.sfgesi r%d, %d\n", ra, I16);
84775c43 1208 tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1209 break;
1210
1211 case 0xc: /* l.sfltsi */
1212 LOG_DIS("l.sfltsi r%d, %d\n", ra, I16);
84775c43 1213 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1214 break;
1215
1216 case 0xd: /* l.sflesi */
1217 LOG_DIS("l.sflesi r%d, %d\n", ra, I16);
84775c43 1218 tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
bbe418f2
JL
1219 break;
1220
1221 default:
1222 gen_illegal_exception(dc);
1223 break;
1224 }
bbe418f2
JL
1225}
1226
1227static void dec_sys(DisasContext *dc, uint32_t insn)
1228{
1229 uint32_t op0;
bbe418f2 1230 uint32_t K16;
111ece51 1231
3d59b680 1232 op0 = extract32(insn, 16, 10);
bbe418f2 1233 K16 = extract32(insn, 0, 16);
bbe418f2
JL
1234
1235 switch (op0) {
1236 case 0x000: /* l.sys */
1237 LOG_DIS("l.sys %d\n", K16);
1238 tcg_gen_movi_tl(cpu_pc, dc->pc);
1239 gen_exception(dc, EXCP_SYSCALL);
1240 dc->is_jmp = DISAS_UPDATE;
1241 break;
1242
1243 case 0x100: /* l.trap */
1244 LOG_DIS("l.trap %d\n", K16);
bbe418f2
JL
1245 tcg_gen_movi_tl(cpu_pc, dc->pc);
1246 gen_exception(dc, EXCP_TRAP);
bbe418f2
JL
1247 break;
1248
1249 case 0x300: /* l.csync */
1250 LOG_DIS("l.csync\n");
bbe418f2
JL
1251 break;
1252
1253 case 0x200: /* l.msync */
1254 LOG_DIS("l.msync\n");
24fc5c0f 1255 tcg_gen_mb(TCG_MO_ALL);
bbe418f2
JL
1256 break;
1257
1258 case 0x270: /* l.psync */
1259 LOG_DIS("l.psync\n");
bbe418f2
JL
1260 break;
1261
1262 default:
1263 gen_illegal_exception(dc);
1264 break;
1265 }
1266}
1267
1268static void dec_float(DisasContext *dc, uint32_t insn)
1269{
1270 uint32_t op0;
1271 uint32_t ra, rb, rd;
1272 op0 = extract32(insn, 0, 8);
1273 ra = extract32(insn, 16, 5);
1274 rb = extract32(insn, 11, 5);
1275 rd = extract32(insn, 21, 5);
1276
1277 switch (op0) {
1278 case 0x00: /* lf.add.s */
1279 LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
1280 gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1281 break;
1282
1283 case 0x01: /* lf.sub.s */
1284 LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
1285 gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1286 break;
1287
1288
1289 case 0x02: /* lf.mul.s */
1290 LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
1291 if (ra != 0 && rb != 0) {
1292 gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1293 } else {
1294 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
1295 tcg_gen_movi_i32(cpu_R[rd], 0x0);
1296 }
1297 break;
1298
1299 case 0x03: /* lf.div.s */
1300 LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
1301 gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1302 break;
1303
1304 case 0x04: /* lf.itof.s */
1305 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1306 gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
1307 break;
1308
1309 case 0x05: /* lf.ftoi.s */
1310 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1311 gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
1312 break;
1313
1314 case 0x06: /* lf.rem.s */
1315 LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
1316 gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1317 break;
1318
1319 case 0x07: /* lf.madd.s */
1320 LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
762e22ed
RH
1321 gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
1322 cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1323 break;
1324
1325 case 0x08: /* lf.sfeq.s */
1326 LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
84775c43 1327 gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1328 break;
1329
1330 case 0x09: /* lf.sfne.s */
1331 LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
84775c43 1332 gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1333 break;
1334
1335 case 0x0a: /* lf.sfgt.s */
1336 LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
84775c43 1337 gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1338 break;
1339
1340 case 0x0b: /* lf.sfge.s */
1341 LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
84775c43 1342 gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1343 break;
1344
1345 case 0x0c: /* lf.sflt.s */
1346 LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
84775c43 1347 gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1348 break;
1349
1350 case 0x0d: /* lf.sfle.s */
1351 LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
84775c43 1352 gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1353 break;
1354
1355/* not used yet, open it when we need or64. */
1356/*#ifdef TARGET_OPENRISC64
1357 case 0x10: lf.add.d
1358 LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1359 check_of64s(dc);
1360 gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1361 break;
1362
1363 case 0x11: lf.sub.d
1364 LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1365 check_of64s(dc);
1366 gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1367 break;
1368
1369 case 0x12: lf.mul.d
1370 LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1371 check_of64s(dc);
1372 if (ra != 0 && rb != 0) {
1373 gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1374 } else {
1375 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
1376 tcg_gen_movi_i64(cpu_R[rd], 0x0);
1377 }
1378 break;
1379
1380 case 0x13: lf.div.d
1381 LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1382 check_of64s(dc);
1383 gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1384 break;
1385
1386 case 0x14: lf.itof.d
1387 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1388 check_of64s(dc);
1389 gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
1390 break;
1391
1392 case 0x15: lf.ftoi.d
1393 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1394 check_of64s(dc);
1395 gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
1396 break;
1397
1398 case 0x16: lf.rem.d
1399 LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1400 check_of64s(dc);
1401 gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1402 break;
1403
1404 case 0x17: lf.madd.d
1405 LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1406 check_of64s(dc);
762e22ed
RH
1407 gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
1408 cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1409 break;
1410
1411 case 0x18: lf.sfeq.d
1412 LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1413 check_of64s(dc);
84775c43 1414 gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1415 break;
1416
1417 case 0x1a: lf.sfgt.d
1418 LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1419 check_of64s(dc);
84775c43 1420 gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1421 break;
1422
1423 case 0x1b: lf.sfge.d
1424 LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1425 check_of64s(dc);
84775c43 1426 gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1427 break;
1428
1429 case 0x19: lf.sfne.d
1430 LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1431 check_of64s(dc);
84775c43 1432 gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1433 break;
1434
1435 case 0x1c: lf.sflt.d
1436 LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1437 check_of64s(dc);
84775c43 1438 gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1439 break;
1440
1441 case 0x1d: lf.sfle.d
1442 LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1443 check_of64s(dc);
84775c43 1444 gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
bbe418f2
JL
1445 break;
1446#endif*/
1447
1448 default:
1449 gen_illegal_exception(dc);
1450 break;
1451 }
bbe418f2
JL
1452}
1453
1454static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1455{
1456 uint32_t op0;
1457 uint32_t insn;
1458 insn = cpu_ldl_code(&cpu->env, dc->pc);
1459 op0 = extract32(insn, 26, 6);
1460
1461 switch (op0) {
1462 case 0x06:
1463 dec_M(dc, insn);
1464 break;
1465
1466 case 0x08:
1467 dec_sys(dc, insn);
1468 break;
1469
1470 case 0x2e:
1471 dec_logic(dc, insn);
1472 break;
1473
1474 case 0x2f:
1475 dec_compi(dc, insn);
1476 break;
1477
1478 case 0x31:
1479 dec_mac(dc, insn);
1480 break;
1481
1482 case 0x32:
1483 dec_float(dc, insn);
1484 break;
1485
1486 case 0x38:
1487 dec_calc(dc, insn);
1488 break;
1489
1490 case 0x39:
1491 dec_comp(dc, insn);
1492 break;
1493
1494 default:
1495 dec_misc(dc, insn);
1496 break;
1497 }
1498}
1499
4e5e1215 1500void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
e67db06e 1501{
4e5e1215 1502 OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
ed2803da 1503 CPUState *cs = CPU(cpu);
bbe418f2 1504 struct DisasContext ctx, *dc = &ctx;
bbe418f2 1505 uint32_t pc_start;
bbe418f2
JL
1506 uint32_t next_page_start;
1507 int num_insns;
1508 int max_insns;
1509
bbe418f2
JL
1510 pc_start = tb->pc;
1511 dc->tb = tb;
1512
bbe418f2 1513 dc->is_jmp = DISAS_NEXT;
bbe418f2
JL
1514 dc->pc = pc_start;
1515 dc->flags = cpu->env.cpucfgr;
97ed5ccd 1516 dc->mem_idx = cpu_mmu_index(&cpu->env, false);
bbe418f2 1517 dc->synced_flags = dc->tb_flags = tb->flags;
0c53d734 1518 dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0;
ed2803da 1519 dc->singlestep_enabled = cs->singlestep_enabled;
bbe418f2
JL
1520
1521 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
bbe418f2
JL
1522 num_insns = 0;
1523 max_insns = tb->cflags & CF_COUNT_MASK;
1524
1525 if (max_insns == 0) {
1526 max_insns = CF_COUNT_MASK;
1527 }
190ce7fb
RH
1528 if (max_insns > TCG_MAX_INSNS) {
1529 max_insns = TCG_MAX_INSNS;
1530 }
bbe418f2 1531
111ece51
RH
1532 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1533 && qemu_log_in_addr_range(pc_start)) {
1534 qemu_log_lock();
1535 qemu_log("----------------\n");
1536 qemu_log("IN: %s\n", lookup_symbol(pc_start));
1537 }
1538
cd42d5b2 1539 gen_tb_start(tb);
bbe418f2
JL
1540
1541 do {
24c32852 1542 tcg_gen_insn_start(dc->pc, num_insns != 0);
959082fc 1543 num_insns++;
bbe418f2 1544
b933066a
RH
1545 if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
1546 tcg_gen_movi_tl(cpu_pc, dc->pc);
1547 gen_exception(dc, EXCP_DEBUG);
1548 dc->is_jmp = DISAS_UPDATE;
522a0d4e
RH
1549 /* The address covered by the breakpoint must be included in
1550 [tb->pc, tb->pc + tb->size) in order to for it to be
1551 properly cleared -- thus we increment the PC here so that
1552 the logic setting tb->size below does the right thing. */
1553 dc->pc += 4;
b933066a
RH
1554 break;
1555 }
1556
959082fc 1557 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
bbe418f2
JL
1558 gen_io_start();
1559 }
bbe418f2 1560 disas_openrisc_insn(dc, cpu);
24c32852
RH
1561 dc->pc = dc->pc + 4;
1562
bbe418f2
JL
1563 /* delay slot */
1564 if (dc->delayed_branch) {
1565 dc->delayed_branch--;
1566 if (!dc->delayed_branch) {
1567 dc->tb_flags &= ~D_FLAG;
1568 gen_sync_flags(dc);
1569 tcg_gen_mov_tl(cpu_pc, jmp_pc);
24c32852
RH
1570 tcg_gen_discard_tl(jmp_pc);
1571 dc->is_jmp = DISAS_UPDATE;
bbe418f2
JL
1572 break;
1573 }
1574 }
1575 } while (!dc->is_jmp
fe700adb 1576 && !tcg_op_buf_full()
ed2803da 1577 && !cs->singlestep_enabled
bbe418f2
JL
1578 && !singlestep
1579 && (dc->pc < next_page_start)
1580 && num_insns < max_insns);
1581
1582 if (tb->cflags & CF_LAST_IO) {
1583 gen_io_end();
1584 }
24c32852
RH
1585
1586 tcg_gen_movi_tl(cpu_ppc, dc->pc - 4);
bbe418f2
JL
1587 if (dc->is_jmp == DISAS_NEXT) {
1588 dc->is_jmp = DISAS_UPDATE;
1589 tcg_gen_movi_tl(cpu_pc, dc->pc);
1590 }
ed2803da 1591 if (unlikely(cs->singlestep_enabled)) {
bbe418f2
JL
1592 gen_exception(dc, EXCP_DEBUG);
1593 } else {
1594 switch (dc->is_jmp) {
1595 case DISAS_NEXT:
1596 gen_goto_tb(dc, 0, dc->pc);
1597 break;
1598 default:
1599 case DISAS_JUMP:
1600 break;
1601 case DISAS_UPDATE:
1602 /* indicate that the hash table must be used
1603 to find the next TB */
1604 tcg_gen_exit_tb(0);
1605 break;
1606 case DISAS_TB_JUMP:
1607 /* nothing more to generate */
1608 break;
1609 }
1610 }
1611
806f352d 1612 gen_tb_end(tb, num_insns);
0a7df5da 1613
4e5e1215
RH
1614 tb->size = dc->pc - pc_start;
1615 tb->icount = num_insns;
bbe418f2 1616
4910e6e4
RH
1617 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1618 && qemu_log_in_addr_range(pc_start)) {
111ece51
RH
1619 log_target_disas(cs, pc_start, tb->size, 0);
1620 qemu_log("\n");
1ee73216 1621 qemu_log_unlock();
bbe418f2 1622 }
e67db06e
JL
1623}
1624
878096ee
AF
1625void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
1626 fprintf_function cpu_fprintf,
1627 int flags)
e67db06e 1628{
878096ee
AF
1629 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1630 CPUOpenRISCState *env = &cpu->env;
e67db06e 1631 int i;
878096ee 1632
e67db06e
JL
1633 cpu_fprintf(f, "PC=%08x\n", env->pc);
1634 for (i = 0; i < 32; ++i) {
878096ee 1635 cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i],
e67db06e
JL
1636 (i % 4) == 3 ? '\n' : ' ');
1637 }
1638}
1639
1640void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
bad729e2 1641 target_ulong *data)
e67db06e 1642{
bad729e2 1643 env->pc = data[0];
24c32852
RH
1644 if (data[1]) {
1645 env->ppc = env->pc - 4;
1646 }
e67db06e 1647}
This page took 0.579715 seconds and 4 git commands to generate.