]> git.proxmox.com Git - qemu.git/blob - target-openrisc/translate.c
target-openrisc: Remove unnecessary code generated by jump instructions
[qemu.git] / target-openrisc / translate.c
1 /*
2 * OpenRISC translation
3 *
4 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
5 * Feng Gao <gf91597@gmail.com>
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
21 #include "cpu.h"
22 #include "exec/exec-all.h"
23 #include "disas/disas.h"
24 #include "tcg-op.h"
25 #include "qemu-common.h"
26 #include "qemu/log.h"
27 #include "config.h"
28 #include "qemu/bitops.h"
29
30 #include "helper.h"
31 #define GEN_HELPER 1
32 #include "helper.h"
33
34 #define OPENRISC_DISAS
35
36 #ifdef OPENRISC_DISAS
37 # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
38 #else
39 # define LOG_DIS(...) do { } while (0)
40 #endif
41
42 typedef struct DisasContext {
43 TranslationBlock *tb;
44 target_ulong pc, ppc, npc;
45 uint32_t tb_flags, synced_flags, flags;
46 uint32_t is_jmp;
47 uint32_t mem_idx;
48 int singlestep_enabled;
49 uint32_t delayed_branch;
50 } DisasContext;
51
52 static TCGv_ptr cpu_env;
53 static TCGv cpu_sr;
54 static TCGv cpu_R[32];
55 static TCGv cpu_pc;
56 static TCGv jmp_pc; /* l.jr/l.jalr temp pc */
57 static TCGv cpu_npc;
58 static TCGv cpu_ppc;
59 static TCGv_i32 env_btaken; /* bf/bnf , F flag taken */
60 static TCGv_i32 fpcsr;
61 static TCGv machi, maclo;
62 static TCGv fpmaddhi, fpmaddlo;
63 static TCGv_i32 env_flags;
64 #include "exec/gen-icount.h"
65
66 void openrisc_translate_init(void)
67 {
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");
77 cpu_sr = tcg_global_mem_new(TCG_AREG0,
78 offsetof(CPUOpenRISCState, sr), "sr");
79 env_flags = tcg_global_mem_new_i32(TCG_AREG0,
80 offsetof(CPUOpenRISCState, flags),
81 "flags");
82 cpu_pc = tcg_global_mem_new(TCG_AREG0,
83 offsetof(CPUOpenRISCState, pc), "pc");
84 cpu_npc = tcg_global_mem_new(TCG_AREG0,
85 offsetof(CPUOpenRISCState, npc), "npc");
86 cpu_ppc = tcg_global_mem_new(TCG_AREG0,
87 offsetof(CPUOpenRISCState, ppc), "ppc");
88 jmp_pc = tcg_global_mem_new(TCG_AREG0,
89 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
90 env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
91 offsetof(CPUOpenRISCState, btaken),
92 "btaken");
93 fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
94 offsetof(CPUOpenRISCState, fpcsr),
95 "fpcsr");
96 machi = tcg_global_mem_new(TCG_AREG0,
97 offsetof(CPUOpenRISCState, machi),
98 "machi");
99 maclo = tcg_global_mem_new(TCG_AREG0,
100 offsetof(CPUOpenRISCState, maclo),
101 "maclo");
102 fpmaddhi = tcg_global_mem_new(TCG_AREG0,
103 offsetof(CPUOpenRISCState, fpmaddhi),
104 "fpmaddhi");
105 fpmaddlo = tcg_global_mem_new(TCG_AREG0,
106 offsetof(CPUOpenRISCState, fpmaddlo),
107 "fpmaddlo");
108 for (i = 0; i < 32; i++) {
109 cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
110 offsetof(CPUOpenRISCState, gpr[i]),
111 regnames[i]);
112 }
113 }
114
115 /* Writeback SR_F transaltion-space to execution-space. */
116 static inline void wb_SR_F(void)
117 {
118 int label;
119
120 label = gen_new_label();
121 tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F);
122 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label);
123 tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F);
124 gen_set_label(label);
125 }
126
127 static inline int zero_extend(unsigned int val, int width)
128 {
129 return val & ((1 << width) - 1);
130 }
131
132 static inline int sign_extend(unsigned int val, int width)
133 {
134 int sval;
135
136 /* LSL */
137 val <<= TARGET_LONG_BITS - width;
138 sval = val;
139 /* ASR. */
140 sval >>= TARGET_LONG_BITS - width;
141 return sval;
142 }
143
144 static inline void gen_sync_flags(DisasContext *dc)
145 {
146 /* Sync the tb dependent flag between translate and runtime. */
147 if (dc->tb_flags != dc->synced_flags) {
148 tcg_gen_movi_tl(env_flags, dc->tb_flags);
149 dc->synced_flags = dc->tb_flags;
150 }
151 }
152
153 static void gen_exception(DisasContext *dc, unsigned int excp)
154 {
155 TCGv_i32 tmp = tcg_const_i32(excp);
156 gen_helper_exception(cpu_env, tmp);
157 tcg_temp_free_i32(tmp);
158 }
159
160 static void gen_illegal_exception(DisasContext *dc)
161 {
162 tcg_gen_movi_tl(cpu_pc, dc->pc);
163 gen_exception(dc, EXCP_ILLEGAL);
164 dc->is_jmp = DISAS_UPDATE;
165 }
166
167 /* not used yet, open it when we need or64. */
168 /*#ifdef TARGET_OPENRISC64
169 static void check_ob64s(DisasContext *dc)
170 {
171 if (!(dc->flags & CPUCFGR_OB64S)) {
172 gen_illegal_exception(dc);
173 }
174 }
175
176 static void check_of64s(DisasContext *dc)
177 {
178 if (!(dc->flags & CPUCFGR_OF64S)) {
179 gen_illegal_exception(dc);
180 }
181 }
182
183 static void check_ov64s(DisasContext *dc)
184 {
185 if (!(dc->flags & CPUCFGR_OV64S)) {
186 gen_illegal_exception(dc);
187 }
188 }
189 #endif*/
190
191 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
192 {
193 TranslationBlock *tb;
194 tb = dc->tb;
195 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
196 likely(!dc->singlestep_enabled)) {
197 tcg_gen_movi_tl(cpu_pc, dest);
198 tcg_gen_goto_tb(n);
199 tcg_gen_exit_tb((uintptr_t)tb + n);
200 } else {
201 tcg_gen_movi_tl(cpu_pc, dest);
202 if (dc->singlestep_enabled) {
203 gen_exception(dc, EXCP_DEBUG);
204 }
205 tcg_gen_exit_tb(0);
206 }
207 }
208
209 static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
210 {
211 target_ulong tmp_pc;
212 /* N26, 26bits imm */
213 tmp_pc = sign_extend((imm<<2), 26) + dc->pc;
214
215 switch (op0) {
216 case 0x00: /* l.j */
217 tcg_gen_movi_tl(jmp_pc, tmp_pc);
218 break;
219 case 0x01: /* l.jal */
220 tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
221 tcg_gen_movi_tl(jmp_pc, tmp_pc);
222 break;
223 case 0x03: /* l.bnf */
224 case 0x04: /* l.bf */
225 {
226 int lab = gen_new_label();
227 TCGv sr_f = tcg_temp_new();
228 tcg_gen_movi_tl(jmp_pc, dc->pc+8);
229 tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
230 tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
231 sr_f, SR_F, lab);
232 tcg_gen_movi_tl(jmp_pc, tmp_pc);
233 gen_set_label(lab);
234 tcg_temp_free(sr_f);
235 }
236 break;
237 case 0x11: /* l.jr */
238 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
239 break;
240 case 0x12: /* l.jalr */
241 tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
242 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
243 break;
244 default:
245 gen_illegal_exception(dc);
246 break;
247 }
248
249 dc->delayed_branch = 2;
250 dc->tb_flags |= D_FLAG;
251 gen_sync_flags(dc);
252 }
253
254
255 static void dec_calc(DisasContext *dc, uint32_t insn)
256 {
257 uint32_t op0, op1, op2;
258 uint32_t ra, rb, rd;
259 op0 = extract32(insn, 0, 4);
260 op1 = extract32(insn, 8, 2);
261 op2 = extract32(insn, 6, 2);
262 ra = extract32(insn, 16, 5);
263 rb = extract32(insn, 11, 5);
264 rd = extract32(insn, 21, 5);
265
266 switch (op0) {
267 case 0x0000:
268 switch (op1) {
269 case 0x00: /* l.add */
270 LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
271 {
272 int lab = gen_new_label();
273 TCGv_i64 ta = tcg_temp_new_i64();
274 TCGv_i64 tb = tcg_temp_new_i64();
275 TCGv_i64 td = tcg_temp_local_new_i64();
276 TCGv_i32 res = tcg_temp_local_new_i32();
277 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
278 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
279 tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
280 tcg_gen_add_i64(td, ta, tb);
281 tcg_gen_trunc_i64_i32(res, td);
282 tcg_gen_shri_i64(td, td, 31);
283 tcg_gen_andi_i64(td, td, 0x3);
284 /* Jump to lab when no overflow. */
285 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
286 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
287 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
288 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
289 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
290 gen_exception(dc, EXCP_RANGE);
291 gen_set_label(lab);
292 tcg_gen_mov_i32(cpu_R[rd], res);
293 tcg_temp_free_i64(ta);
294 tcg_temp_free_i64(tb);
295 tcg_temp_free_i64(td);
296 tcg_temp_free_i32(res);
297 tcg_temp_free_i32(sr_ove);
298 }
299 break;
300 default:
301 gen_illegal_exception(dc);
302 break;
303 }
304 break;
305
306 case 0x0001: /* l.addc */
307 switch (op1) {
308 case 0x00:
309 LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
310 {
311 int lab = gen_new_label();
312 TCGv_i64 ta = tcg_temp_new_i64();
313 TCGv_i64 tb = tcg_temp_new_i64();
314 TCGv_i64 tcy = tcg_temp_local_new_i64();
315 TCGv_i64 td = tcg_temp_local_new_i64();
316 TCGv_i32 res = tcg_temp_local_new_i32();
317 TCGv_i32 sr_cy = tcg_temp_local_new_i32();
318 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
319 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
320 tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
321 tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
322 tcg_gen_extu_i32_i64(tcy, sr_cy);
323 tcg_gen_shri_i64(tcy, tcy, 10);
324 tcg_gen_add_i64(td, ta, tb);
325 tcg_gen_add_i64(td, td, tcy);
326 tcg_gen_trunc_i64_i32(res, td);
327 tcg_gen_shri_i64(td, td, 32);
328 tcg_gen_andi_i64(td, td, 0x3);
329 /* Jump to lab when no overflow. */
330 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
331 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
332 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
333 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
334 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
335 gen_exception(dc, EXCP_RANGE);
336 gen_set_label(lab);
337 tcg_gen_mov_i32(cpu_R[rd], res);
338 tcg_temp_free_i64(ta);
339 tcg_temp_free_i64(tb);
340 tcg_temp_free_i64(tcy);
341 tcg_temp_free_i64(td);
342 tcg_temp_free_i32(res);
343 tcg_temp_free_i32(sr_cy);
344 tcg_temp_free_i32(sr_ove);
345 }
346 break;
347 default:
348 gen_illegal_exception(dc);
349 break;
350 }
351 break;
352
353 case 0x0002: /* l.sub */
354 switch (op1) {
355 case 0x00:
356 LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
357 {
358 int lab = gen_new_label();
359 TCGv_i64 ta = tcg_temp_new_i64();
360 TCGv_i64 tb = tcg_temp_new_i64();
361 TCGv_i64 td = tcg_temp_local_new_i64();
362 TCGv_i32 res = tcg_temp_local_new_i32();
363 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
364
365 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
366 tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
367 tcg_gen_sub_i64(td, ta, tb);
368 tcg_gen_trunc_i64_i32(res, td);
369 tcg_gen_shri_i64(td, td, 31);
370 tcg_gen_andi_i64(td, td, 0x3);
371 /* Jump to lab when no overflow. */
372 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
373 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
374 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
375 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
376 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
377 gen_exception(dc, EXCP_RANGE);
378 gen_set_label(lab);
379 tcg_gen_mov_i32(cpu_R[rd], res);
380 tcg_temp_free_i64(ta);
381 tcg_temp_free_i64(tb);
382 tcg_temp_free_i64(td);
383 tcg_temp_free_i32(res);
384 tcg_temp_free_i32(sr_ove);
385 }
386 break;
387 default:
388 gen_illegal_exception(dc);
389 break;
390 }
391 break;
392
393 case 0x0003: /* l.and */
394 switch (op1) {
395 case 0x00:
396 LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
397 tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
398 break;
399 default:
400 gen_illegal_exception(dc);
401 break;
402 }
403 break;
404
405 case 0x0004: /* l.or */
406 switch (op1) {
407 case 0x00:
408 LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
409 tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
410 break;
411 default:
412 gen_illegal_exception(dc);
413 break;
414 }
415 break;
416
417 case 0x0005:
418 switch (op1) {
419 case 0x00: /* l.xor */
420 LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
421 tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
422 break;
423 default:
424 gen_illegal_exception(dc);
425 break;
426 }
427 break;
428
429 case 0x0006:
430 switch (op1) {
431 case 0x03: /* l.mul */
432 LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
433 if (ra != 0 && rb != 0) {
434 gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
435 } else {
436 tcg_gen_movi_tl(cpu_R[rd], 0x0);
437 }
438 break;
439 default:
440 gen_illegal_exception(dc);
441 break;
442 }
443 break;
444
445 case 0x0009:
446 switch (op1) {
447 case 0x03: /* l.div */
448 LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
449 {
450 int lab0 = gen_new_label();
451 int lab1 = gen_new_label();
452 int lab2 = gen_new_label();
453 int lab3 = gen_new_label();
454 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
455 if (rb == 0) {
456 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
457 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
458 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
459 gen_exception(dc, EXCP_RANGE);
460 gen_set_label(lab0);
461 } else {
462 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
463 0x00000000, lab1);
464 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
465 0x80000000, lab2);
466 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
467 0xffffffff, lab2);
468 gen_set_label(lab1);
469 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
470 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
471 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3);
472 gen_exception(dc, EXCP_RANGE);
473 gen_set_label(lab2);
474 tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
475 gen_set_label(lab3);
476 }
477 tcg_temp_free_i32(sr_ove);
478 }
479 break;
480
481 default:
482 gen_illegal_exception(dc);
483 break;
484 }
485 break;
486
487 case 0x000a:
488 switch (op1) {
489 case 0x03: /* l.divu */
490 LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
491 {
492 int lab0 = gen_new_label();
493 int lab1 = gen_new_label();
494 int lab2 = gen_new_label();
495 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
496 if (rb == 0) {
497 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
498 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
499 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
500 gen_exception(dc, EXCP_RANGE);
501 gen_set_label(lab0);
502 } else {
503 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
504 0x00000000, lab1);
505 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
506 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
507 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);
508 gen_exception(dc, EXCP_RANGE);
509 gen_set_label(lab1);
510 tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
511 gen_set_label(lab2);
512 }
513 tcg_temp_free_i32(sr_ove);
514 }
515 break;
516
517 default:
518 gen_illegal_exception(dc);
519 break;
520 }
521 break;
522
523 case 0x000b:
524 switch (op1) {
525 case 0x03: /* l.mulu */
526 LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
527 if (rb != 0 && ra != 0) {
528 TCGv_i64 result = tcg_temp_local_new_i64();
529 TCGv_i64 tra = tcg_temp_local_new_i64();
530 TCGv_i64 trb = tcg_temp_local_new_i64();
531 TCGv_i64 high = tcg_temp_new_i64();
532 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
533 int lab = gen_new_label();
534 /* Calculate the each result. */
535 tcg_gen_extu_i32_i64(tra, cpu_R[ra]);
536 tcg_gen_extu_i32_i64(trb, cpu_R[rb]);
537 tcg_gen_mul_i64(result, tra, trb);
538 tcg_temp_free_i64(tra);
539 tcg_temp_free_i64(trb);
540 tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);
541 /* Overflow or not. */
542 tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);
543 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
544 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
545 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab);
546 gen_exception(dc, EXCP_RANGE);
547 gen_set_label(lab);
548 tcg_temp_free_i64(high);
549 tcg_gen_trunc_i64_tl(cpu_R[rd], result);
550 tcg_temp_free_i64(result);
551 tcg_temp_free_i32(sr_ove);
552 } else {
553 tcg_gen_movi_tl(cpu_R[rd], 0);
554 }
555 break;
556
557 default:
558 gen_illegal_exception(dc);
559 break;
560 }
561 break;
562
563 case 0x000e:
564 switch (op1) {
565 case 0x00: /* l.cmov */
566 LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
567 {
568 int lab = gen_new_label();
569 TCGv res = tcg_temp_local_new();
570 TCGv sr_f = tcg_temp_new();
571 tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
572 tcg_gen_mov_tl(res, cpu_R[rb]);
573 tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
574 tcg_gen_mov_tl(res, cpu_R[ra]);
575 gen_set_label(lab);
576 tcg_gen_mov_tl(cpu_R[rd], res);
577 tcg_temp_free(sr_f);
578 tcg_temp_free(res);
579 }
580 break;
581
582 default:
583 gen_illegal_exception(dc);
584 break;
585 }
586 break;
587
588 case 0x000f:
589 switch (op1) {
590 case 0x00: /* l.ff1 */
591 LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
592 gen_helper_ff1(cpu_R[rd], cpu_R[ra]);
593 break;
594 case 0x01: /* l.fl1 */
595 LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
596 gen_helper_fl1(cpu_R[rd], cpu_R[ra]);
597 break;
598
599 default:
600 gen_illegal_exception(dc);
601 break;
602 }
603 break;
604
605 case 0x0008:
606 switch (op1) {
607 case 0x00:
608 switch (op2) {
609 case 0x00: /* l.sll */
610 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
611 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
612 break;
613 case 0x01: /* l.srl */
614 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
615 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
616 break;
617 case 0x02: /* l.sra */
618 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
619 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
620 break;
621 case 0x03: /* l.ror */
622 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
623 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
624 break;
625
626 default:
627 gen_illegal_exception(dc);
628 break;
629 }
630 break;
631
632 default:
633 gen_illegal_exception(dc);
634 break;
635 }
636 break;
637
638 case 0x000c:
639 switch (op1) {
640 case 0x00:
641 switch (op2) {
642 case 0x00: /* l.exths */
643 LOG_DIS("l.exths r%d, r%d\n", rd, ra);
644 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
645 break;
646 case 0x01: /* l.extbs */
647 LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
648 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
649 break;
650 case 0x02: /* l.exthz */
651 LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
652 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
653 break;
654 case 0x03: /* l.extbz */
655 LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
656 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
657 break;
658
659 default:
660 gen_illegal_exception(dc);
661 break;
662 }
663 break;
664
665 default:
666 gen_illegal_exception(dc);
667 break;
668 }
669 break;
670
671 case 0x000d:
672 switch (op1) {
673 case 0x00:
674 switch (op2) {
675 case 0x00: /* l.extws */
676 LOG_DIS("l.extws r%d, r%d\n", rd, ra);
677 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
678 break;
679 case 0x01: /* l.extwz */
680 LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
681 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
682 break;
683
684 default:
685 gen_illegal_exception(dc);
686 break;
687 }
688 break;
689
690 default:
691 gen_illegal_exception(dc);
692 break;
693 }
694 break;
695
696 default:
697 gen_illegal_exception(dc);
698 break;
699 }
700 }
701
702 static void dec_misc(DisasContext *dc, uint32_t insn)
703 {
704 uint32_t op0, op1;
705 uint32_t ra, rb, rd;
706 #ifdef OPENRISC_DISAS
707 uint32_t L6, K5;
708 #endif
709 uint32_t I16, I5, I11, N26, tmp;
710 op0 = extract32(insn, 26, 6);
711 op1 = extract32(insn, 24, 2);
712 ra = extract32(insn, 16, 5);
713 rb = extract32(insn, 11, 5);
714 rd = extract32(insn, 21, 5);
715 #ifdef OPENRISC_DISAS
716 L6 = extract32(insn, 5, 6);
717 K5 = extract32(insn, 0, 5);
718 #endif
719 I16 = extract32(insn, 0, 16);
720 I5 = extract32(insn, 21, 5);
721 I11 = extract32(insn, 0, 11);
722 N26 = extract32(insn, 0, 26);
723 tmp = (I5<<11) + I11;
724
725 switch (op0) {
726 case 0x00: /* l.j */
727 LOG_DIS("l.j %d\n", N26);
728 gen_jump(dc, N26, 0, op0);
729 break;
730
731 case 0x01: /* l.jal */
732 LOG_DIS("l.jal %d\n", N26);
733 gen_jump(dc, N26, 0, op0);
734 break;
735
736 case 0x03: /* l.bnf */
737 LOG_DIS("l.bnf %d\n", N26);
738 gen_jump(dc, N26, 0, op0);
739 break;
740
741 case 0x04: /* l.bf */
742 LOG_DIS("l.bf %d\n", N26);
743 gen_jump(dc, N26, 0, op0);
744 break;
745
746 case 0x05:
747 switch (op1) {
748 case 0x01: /* l.nop */
749 LOG_DIS("l.nop %d\n", I16);
750 break;
751
752 default:
753 gen_illegal_exception(dc);
754 break;
755 }
756 break;
757
758 case 0x11: /* l.jr */
759 LOG_DIS("l.jr r%d\n", rb);
760 gen_jump(dc, 0, rb, op0);
761 break;
762
763 case 0x12: /* l.jalr */
764 LOG_DIS("l.jalr r%d\n", rb);
765 gen_jump(dc, 0, rb, op0);
766 break;
767
768 case 0x13: /* l.maci */
769 LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
770 {
771 TCGv_i64 t1 = tcg_temp_new_i64();
772 TCGv_i64 t2 = tcg_temp_new_i64();
773 TCGv_i32 dst = tcg_temp_new_i32();
774 TCGv ttmp = tcg_const_tl(tmp);
775 tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
776 tcg_gen_ext_i32_i64(t1, dst);
777 tcg_gen_concat_i32_i64(t2, maclo, machi);
778 tcg_gen_add_i64(t2, t2, t1);
779 tcg_gen_trunc_i64_i32(maclo, t2);
780 tcg_gen_shri_i64(t2, t2, 32);
781 tcg_gen_trunc_i64_i32(machi, t2);
782 tcg_temp_free_i32(dst);
783 tcg_temp_free(ttmp);
784 tcg_temp_free_i64(t1);
785 tcg_temp_free_i64(t2);
786 }
787 break;
788
789 case 0x09: /* l.rfe */
790 LOG_DIS("l.rfe\n");
791 {
792 #if defined(CONFIG_USER_ONLY)
793 return;
794 #else
795 if (dc->mem_idx == MMU_USER_IDX) {
796 gen_illegal_exception(dc);
797 return;
798 }
799 gen_helper_rfe(cpu_env);
800 dc->is_jmp = DISAS_UPDATE;
801 #endif
802 }
803 break;
804
805 case 0x1c: /* l.cust1 */
806 LOG_DIS("l.cust1\n");
807 break;
808
809 case 0x1d: /* l.cust2 */
810 LOG_DIS("l.cust2\n");
811 break;
812
813 case 0x1e: /* l.cust3 */
814 LOG_DIS("l.cust3\n");
815 break;
816
817 case 0x1f: /* l.cust4 */
818 LOG_DIS("l.cust4\n");
819 break;
820
821 case 0x3c: /* l.cust5 */
822 LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5);
823 break;
824
825 case 0x3d: /* l.cust6 */
826 LOG_DIS("l.cust6\n");
827 break;
828
829 case 0x3e: /* l.cust7 */
830 LOG_DIS("l.cust7\n");
831 break;
832
833 case 0x3f: /* l.cust8 */
834 LOG_DIS("l.cust8\n");
835 break;
836
837 /* not used yet, open it when we need or64. */
838 /*#ifdef TARGET_OPENRISC64
839 case 0x20: l.ld
840 LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16);
841 {
842 check_ob64s(dc);
843 TCGv_i64 t0 = tcg_temp_new_i64();
844 tcg_gen_addi_i64(t0, cpu_R[ra], sign_extend(I16, 16));
845 tcg_gen_qemu_ld64(cpu_R[rd], t0, dc->mem_idx);
846 tcg_temp_free_i64(t0);
847 }
848 break;
849 #endif*/
850
851 case 0x21: /* l.lwz */
852 LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16);
853 {
854 TCGv t0 = tcg_temp_new();
855 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
856 tcg_gen_qemu_ld32u(cpu_R[rd], t0, dc->mem_idx);
857 tcg_temp_free(t0);
858 }
859 break;
860
861 case 0x22: /* l.lws */
862 LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16);
863 {
864 TCGv t0 = tcg_temp_new();
865 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
866 tcg_gen_qemu_ld32s(cpu_R[rd], t0, dc->mem_idx);
867 tcg_temp_free(t0);
868 }
869 break;
870
871 case 0x23: /* l.lbz */
872 LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16);
873 {
874 TCGv t0 = tcg_temp_new();
875 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
876 tcg_gen_qemu_ld8u(cpu_R[rd], t0, dc->mem_idx);
877 tcg_temp_free(t0);
878 }
879 break;
880
881 case 0x24: /* l.lbs */
882 LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16);
883 {
884 TCGv t0 = tcg_temp_new();
885 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
886 tcg_gen_qemu_ld8s(cpu_R[rd], t0, dc->mem_idx);
887 tcg_temp_free(t0);
888 }
889 break;
890
891 case 0x25: /* l.lhz */
892 LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16);
893 {
894 TCGv t0 = tcg_temp_new();
895 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
896 tcg_gen_qemu_ld16u(cpu_R[rd], t0, dc->mem_idx);
897 tcg_temp_free(t0);
898 }
899 break;
900
901 case 0x26: /* l.lhs */
902 LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16);
903 {
904 TCGv t0 = tcg_temp_new();
905 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
906 tcg_gen_qemu_ld16s(cpu_R[rd], t0, dc->mem_idx);
907 tcg_temp_free(t0);
908 }
909 break;
910
911 case 0x27: /* l.addi */
912 LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
913 {
914 if (I16 == 0) {
915 tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
916 } else {
917 int lab = gen_new_label();
918 TCGv_i64 ta = tcg_temp_new_i64();
919 TCGv_i64 td = tcg_temp_local_new_i64();
920 TCGv_i32 res = tcg_temp_local_new_i32();
921 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
922 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
923 tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
924 tcg_gen_trunc_i64_i32(res, td);
925 tcg_gen_shri_i64(td, td, 32);
926 tcg_gen_andi_i64(td, td, 0x3);
927 /* Jump to lab when no overflow. */
928 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
929 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
930 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
931 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
932 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
933 gen_exception(dc, EXCP_RANGE);
934 gen_set_label(lab);
935 tcg_gen_mov_i32(cpu_R[rd], res);
936 tcg_temp_free_i64(ta);
937 tcg_temp_free_i64(td);
938 tcg_temp_free_i32(res);
939 tcg_temp_free_i32(sr_ove);
940 }
941 }
942 break;
943
944 case 0x28: /* l.addic */
945 LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
946 {
947 int lab = gen_new_label();
948 TCGv_i64 ta = tcg_temp_new_i64();
949 TCGv_i64 td = tcg_temp_local_new_i64();
950 TCGv_i64 tcy = tcg_temp_local_new_i64();
951 TCGv_i32 res = tcg_temp_local_new_i32();
952 TCGv_i32 sr_cy = tcg_temp_local_new_i32();
953 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
954 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
955 tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
956 tcg_gen_shri_i32(sr_cy, sr_cy, 10);
957 tcg_gen_extu_i32_i64(tcy, sr_cy);
958 tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
959 tcg_gen_add_i64(td, td, tcy);
960 tcg_gen_trunc_i64_i32(res, td);
961 tcg_gen_shri_i64(td, td, 32);
962 tcg_gen_andi_i64(td, td, 0x3);
963 /* Jump to lab when no overflow. */
964 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
965 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
966 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
967 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
968 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
969 gen_exception(dc, EXCP_RANGE);
970 gen_set_label(lab);
971 tcg_gen_mov_i32(cpu_R[rd], res);
972 tcg_temp_free_i64(ta);
973 tcg_temp_free_i64(td);
974 tcg_temp_free_i64(tcy);
975 tcg_temp_free_i32(res);
976 tcg_temp_free_i32(sr_cy);
977 tcg_temp_free_i32(sr_ove);
978 }
979 break;
980
981 case 0x29: /* l.andi */
982 LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, I16);
983 tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
984 break;
985
986 case 0x2a: /* l.ori */
987 LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, I16);
988 tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
989 break;
990
991 case 0x2b: /* l.xori */
992 LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
993 tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], sign_extend(I16, 16));
994 break;
995
996 case 0x2c: /* l.muli */
997 LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
998 if (ra != 0 && I16 != 0) {
999 TCGv_i32 im = tcg_const_i32(I16);
1000 gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im);
1001 tcg_temp_free_i32(im);
1002 } else {
1003 tcg_gen_movi_tl(cpu_R[rd], 0x0);
1004 }
1005 break;
1006
1007 case 0x2d: /* l.mfspr */
1008 LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16);
1009 {
1010 #if defined(CONFIG_USER_ONLY)
1011 return;
1012 #else
1013 TCGv_i32 ti = tcg_const_i32(I16);
1014 if (dc->mem_idx == MMU_USER_IDX) {
1015 gen_illegal_exception(dc);
1016 return;
1017 }
1018 gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
1019 tcg_temp_free_i32(ti);
1020 #endif
1021 }
1022 break;
1023
1024 case 0x30: /* l.mtspr */
1025 LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11);
1026 {
1027 #if defined(CONFIG_USER_ONLY)
1028 return;
1029 #else
1030 TCGv_i32 im = tcg_const_i32(tmp);
1031 if (dc->mem_idx == MMU_USER_IDX) {
1032 gen_illegal_exception(dc);
1033 return;
1034 }
1035 gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
1036 tcg_temp_free_i32(im);
1037 #endif
1038 }
1039 break;
1040
1041 /* not used yet, open it when we need or64. */
1042 /*#ifdef TARGET_OPENRISC64
1043 case 0x34: l.sd
1044 LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11);
1045 {
1046 check_ob64s(dc);
1047 TCGv_i64 t0 = tcg_temp_new_i64();
1048 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
1049 tcg_gen_qemu_st64(cpu_R[rb], t0, dc->mem_idx);
1050 tcg_temp_free_i64(t0);
1051 }
1052 break;
1053 #endif*/
1054
1055 case 0x35: /* l.sw */
1056 LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11);
1057 {
1058 TCGv t0 = tcg_temp_new();
1059 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
1060 tcg_gen_qemu_st32(cpu_R[rb], t0, dc->mem_idx);
1061 tcg_temp_free(t0);
1062 }
1063 break;
1064
1065 case 0x36: /* l.sb */
1066 LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11);
1067 {
1068 TCGv t0 = tcg_temp_new();
1069 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
1070 tcg_gen_qemu_st8(cpu_R[rb], t0, dc->mem_idx);
1071 tcg_temp_free(t0);
1072 }
1073 break;
1074
1075 case 0x37: /* l.sh */
1076 LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11);
1077 {
1078 TCGv t0 = tcg_temp_new();
1079 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
1080 tcg_gen_qemu_st16(cpu_R[rb], t0, dc->mem_idx);
1081 tcg_temp_free(t0);
1082 }
1083 break;
1084
1085 default:
1086 gen_illegal_exception(dc);
1087 break;
1088 }
1089 }
1090
1091 static void dec_mac(DisasContext *dc, uint32_t insn)
1092 {
1093 uint32_t op0;
1094 uint32_t ra, rb;
1095 op0 = extract32(insn, 0, 4);
1096 ra = extract32(insn, 16, 5);
1097 rb = extract32(insn, 11, 5);
1098
1099 switch (op0) {
1100 case 0x0001: /* l.mac */
1101 LOG_DIS("l.mac r%d, r%d\n", ra, rb);
1102 {
1103 TCGv_i32 t0 = tcg_temp_new_i32();
1104 TCGv_i64 t1 = tcg_temp_new_i64();
1105 TCGv_i64 t2 = tcg_temp_new_i64();
1106 tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
1107 tcg_gen_ext_i32_i64(t1, t0);
1108 tcg_gen_concat_i32_i64(t2, maclo, machi);
1109 tcg_gen_add_i64(t2, t2, t1);
1110 tcg_gen_trunc_i64_i32(maclo, t2);
1111 tcg_gen_shri_i64(t2, t2, 32);
1112 tcg_gen_trunc_i64_i32(machi, t2);
1113 tcg_temp_free_i32(t0);
1114 tcg_temp_free_i64(t1);
1115 tcg_temp_free_i64(t2);
1116 }
1117 break;
1118
1119 case 0x0002: /* l.msb */
1120 LOG_DIS("l.msb r%d, r%d\n", ra, rb);
1121 {
1122 TCGv_i32 t0 = tcg_temp_new_i32();
1123 TCGv_i64 t1 = tcg_temp_new_i64();
1124 TCGv_i64 t2 = tcg_temp_new_i64();
1125 tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
1126 tcg_gen_ext_i32_i64(t1, t0);
1127 tcg_gen_concat_i32_i64(t2, maclo, machi);
1128 tcg_gen_sub_i64(t2, t2, t1);
1129 tcg_gen_trunc_i64_i32(maclo, t2);
1130 tcg_gen_shri_i64(t2, t2, 32);
1131 tcg_gen_trunc_i64_i32(machi, t2);
1132 tcg_temp_free_i32(t0);
1133 tcg_temp_free_i64(t1);
1134 tcg_temp_free_i64(t2);
1135 }
1136 break;
1137
1138 default:
1139 gen_illegal_exception(dc);
1140 break;
1141 }
1142 }
1143
1144 static void dec_logic(DisasContext *dc, uint32_t insn)
1145 {
1146 uint32_t op0;
1147 uint32_t rd, ra, L6;
1148 op0 = extract32(insn, 6, 2);
1149 rd = extract32(insn, 21, 5);
1150 ra = extract32(insn, 16, 5);
1151 L6 = extract32(insn, 0, 6);
1152
1153 switch (op0) {
1154 case 0x00: /* l.slli */
1155 LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
1156 tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
1157 break;
1158
1159 case 0x01: /* l.srli */
1160 LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
1161 tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
1162 break;
1163
1164 case 0x02: /* l.srai */
1165 LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
1166 tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); break;
1167
1168 case 0x03: /* l.rori */
1169 LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
1170 tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
1171 break;
1172
1173 default:
1174 gen_illegal_exception(dc);
1175 break;
1176 }
1177 }
1178
1179 static void dec_M(DisasContext *dc, uint32_t insn)
1180 {
1181 uint32_t op0;
1182 uint32_t rd;
1183 uint32_t K16;
1184 op0 = extract32(insn, 16, 1);
1185 rd = extract32(insn, 21, 5);
1186 K16 = extract32(insn, 0, 16);
1187
1188 switch (op0) {
1189 case 0x0: /* l.movhi */
1190 LOG_DIS("l.movhi r%d, %d\n", rd, K16);
1191 tcg_gen_movi_tl(cpu_R[rd], (K16 << 16));
1192 break;
1193
1194 case 0x1: /* l.macrc */
1195 LOG_DIS("l.macrc r%d\n", rd);
1196 tcg_gen_mov_tl(cpu_R[rd], maclo);
1197 tcg_gen_movi_tl(maclo, 0x0);
1198 tcg_gen_movi_tl(machi, 0x0);
1199 break;
1200
1201 default:
1202 gen_illegal_exception(dc);
1203 break;
1204 }
1205 }
1206
1207 static void dec_comp(DisasContext *dc, uint32_t insn)
1208 {
1209 uint32_t op0;
1210 uint32_t ra, rb;
1211
1212 op0 = extract32(insn, 21, 5);
1213 ra = extract32(insn, 16, 5);
1214 rb = extract32(insn, 11, 5);
1215
1216 tcg_gen_movi_i32(env_btaken, 0x0);
1217 /* unsigned integers */
1218 tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
1219 tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
1220
1221 switch (op0) {
1222 case 0x0: /* l.sfeq */
1223 LOG_DIS("l.sfeq r%d, r%d\n", ra, rb);
1224 tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]);
1225 break;
1226
1227 case 0x1: /* l.sfne */
1228 LOG_DIS("l.sfne r%d, r%d\n", ra, rb);
1229 tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]);
1230 break;
1231
1232 case 0x2: /* l.sfgtu */
1233 LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb);
1234 tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]);
1235 break;
1236
1237 case 0x3: /* l.sfgeu */
1238 LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb);
1239 tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]);
1240 break;
1241
1242 case 0x4: /* l.sfltu */
1243 LOG_DIS("l.sfltu r%d, r%d\n", ra, rb);
1244 tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]);
1245 break;
1246
1247 case 0x5: /* l.sfleu */
1248 LOG_DIS("l.sfleu r%d, r%d\n", ra, rb);
1249 tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]);
1250 break;
1251
1252 case 0xa: /* l.sfgts */
1253 LOG_DIS("l.sfgts r%d, r%d\n", ra, rb);
1254 tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]);
1255 break;
1256
1257 case 0xb: /* l.sfges */
1258 LOG_DIS("l.sfges r%d, r%d\n", ra, rb);
1259 tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]);
1260 break;
1261
1262 case 0xc: /* l.sflts */
1263 LOG_DIS("l.sflts r%d, r%d\n", ra, rb);
1264 tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]);
1265 break;
1266
1267 case 0xd: /* l.sfles */
1268 LOG_DIS("l.sfles r%d, r%d\n", ra, rb);
1269 tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]);
1270 break;
1271
1272 default:
1273 gen_illegal_exception(dc);
1274 break;
1275 }
1276 wb_SR_F();
1277 }
1278
1279 static void dec_compi(DisasContext *dc, uint32_t insn)
1280 {
1281 uint32_t op0;
1282 uint32_t ra, I16;
1283
1284 op0 = extract32(insn, 21, 5);
1285 ra = extract32(insn, 16, 5);
1286 I16 = extract32(insn, 0, 16);
1287
1288 tcg_gen_movi_i32(env_btaken, 0x0);
1289 I16 = sign_extend(I16, 16);
1290
1291 switch (op0) {
1292 case 0x0: /* l.sfeqi */
1293 LOG_DIS("l.sfeqi r%d, %d\n", ra, I16);
1294 tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16);
1295 break;
1296
1297 case 0x1: /* l.sfnei */
1298 LOG_DIS("l.sfnei r%d, %d\n", ra, I16);
1299 tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16);
1300 break;
1301
1302 case 0x2: /* l.sfgtui */
1303 LOG_DIS("l.sfgtui r%d, %d\n", ra, I16);
1304 tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16);
1305 break;
1306
1307 case 0x3: /* l.sfgeui */
1308 LOG_DIS("l.sfgeui r%d, %d\n", ra, I16);
1309 tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16);
1310 break;
1311
1312 case 0x4: /* l.sfltui */
1313 LOG_DIS("l.sfltui r%d, %d\n", ra, I16);
1314 tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16);
1315 break;
1316
1317 case 0x5: /* l.sfleui */
1318 LOG_DIS("l.sfleui r%d, %d\n", ra, I16);
1319 tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16);
1320 break;
1321
1322 case 0xa: /* l.sfgtsi */
1323 LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16);
1324 tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16);
1325 break;
1326
1327 case 0xb: /* l.sfgesi */
1328 LOG_DIS("l.sfgesi r%d, %d\n", ra, I16);
1329 tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16);
1330 break;
1331
1332 case 0xc: /* l.sfltsi */
1333 LOG_DIS("l.sfltsi r%d, %d\n", ra, I16);
1334 tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16);
1335 break;
1336
1337 case 0xd: /* l.sflesi */
1338 LOG_DIS("l.sflesi r%d, %d\n", ra, I16);
1339 tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16);
1340 break;
1341
1342 default:
1343 gen_illegal_exception(dc);
1344 break;
1345 }
1346 wb_SR_F();
1347 }
1348
1349 static void dec_sys(DisasContext *dc, uint32_t insn)
1350 {
1351 uint32_t op0;
1352 #ifdef OPENRISC_DISAS
1353 uint32_t K16;
1354 #endif
1355 op0 = extract32(insn, 16, 8);
1356 #ifdef OPENRISC_DISAS
1357 K16 = extract32(insn, 0, 16);
1358 #endif
1359
1360 switch (op0) {
1361 case 0x000: /* l.sys */
1362 LOG_DIS("l.sys %d\n", K16);
1363 tcg_gen_movi_tl(cpu_pc, dc->pc);
1364 gen_exception(dc, EXCP_SYSCALL);
1365 dc->is_jmp = DISAS_UPDATE;
1366 break;
1367
1368 case 0x100: /* l.trap */
1369 LOG_DIS("l.trap %d\n", K16);
1370 #if defined(CONFIG_USER_ONLY)
1371 return;
1372 #else
1373 if (dc->mem_idx == MMU_USER_IDX) {
1374 gen_illegal_exception(dc);
1375 return;
1376 }
1377 tcg_gen_movi_tl(cpu_pc, dc->pc);
1378 gen_exception(dc, EXCP_TRAP);
1379 #endif
1380 break;
1381
1382 case 0x300: /* l.csync */
1383 LOG_DIS("l.csync\n");
1384 #if defined(CONFIG_USER_ONLY)
1385 return;
1386 #else
1387 if (dc->mem_idx == MMU_USER_IDX) {
1388 gen_illegal_exception(dc);
1389 return;
1390 }
1391 #endif
1392 break;
1393
1394 case 0x200: /* l.msync */
1395 LOG_DIS("l.msync\n");
1396 #if defined(CONFIG_USER_ONLY)
1397 return;
1398 #else
1399 if (dc->mem_idx == MMU_USER_IDX) {
1400 gen_illegal_exception(dc);
1401 return;
1402 }
1403 #endif
1404 break;
1405
1406 case 0x270: /* l.psync */
1407 LOG_DIS("l.psync\n");
1408 #if defined(CONFIG_USER_ONLY)
1409 return;
1410 #else
1411 if (dc->mem_idx == MMU_USER_IDX) {
1412 gen_illegal_exception(dc);
1413 return;
1414 }
1415 #endif
1416 break;
1417
1418 default:
1419 gen_illegal_exception(dc);
1420 break;
1421 }
1422 }
1423
1424 static void dec_float(DisasContext *dc, uint32_t insn)
1425 {
1426 uint32_t op0;
1427 uint32_t ra, rb, rd;
1428 op0 = extract32(insn, 0, 8);
1429 ra = extract32(insn, 16, 5);
1430 rb = extract32(insn, 11, 5);
1431 rd = extract32(insn, 21, 5);
1432
1433 switch (op0) {
1434 case 0x00: /* lf.add.s */
1435 LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
1436 gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1437 break;
1438
1439 case 0x01: /* lf.sub.s */
1440 LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
1441 gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1442 break;
1443
1444
1445 case 0x02: /* lf.mul.s */
1446 LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
1447 if (ra != 0 && rb != 0) {
1448 gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1449 } else {
1450 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
1451 tcg_gen_movi_i32(cpu_R[rd], 0x0);
1452 }
1453 break;
1454
1455 case 0x03: /* lf.div.s */
1456 LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
1457 gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1458 break;
1459
1460 case 0x04: /* lf.itof.s */
1461 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1462 gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
1463 break;
1464
1465 case 0x05: /* lf.ftoi.s */
1466 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1467 gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
1468 break;
1469
1470 case 0x06: /* lf.rem.s */
1471 LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
1472 gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1473 break;
1474
1475 case 0x07: /* lf.madd.s */
1476 LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
1477 gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1478 break;
1479
1480 case 0x08: /* lf.sfeq.s */
1481 LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
1482 gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1483 break;
1484
1485 case 0x09: /* lf.sfne.s */
1486 LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
1487 gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1488 break;
1489
1490 case 0x0a: /* lf.sfgt.s */
1491 LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
1492 gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1493 break;
1494
1495 case 0x0b: /* lf.sfge.s */
1496 LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
1497 gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1498 break;
1499
1500 case 0x0c: /* lf.sflt.s */
1501 LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
1502 gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1503 break;
1504
1505 case 0x0d: /* lf.sfle.s */
1506 LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
1507 gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1508 break;
1509
1510 /* not used yet, open it when we need or64. */
1511 /*#ifdef TARGET_OPENRISC64
1512 case 0x10: lf.add.d
1513 LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
1514 check_of64s(dc);
1515 gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1516 break;
1517
1518 case 0x11: lf.sub.d
1519 LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
1520 check_of64s(dc);
1521 gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1522 break;
1523
1524 case 0x12: lf.mul.d
1525 LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
1526 check_of64s(dc);
1527 if (ra != 0 && rb != 0) {
1528 gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1529 } else {
1530 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
1531 tcg_gen_movi_i64(cpu_R[rd], 0x0);
1532 }
1533 break;
1534
1535 case 0x13: lf.div.d
1536 LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
1537 check_of64s(dc);
1538 gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1539 break;
1540
1541 case 0x14: lf.itof.d
1542 LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
1543 check_of64s(dc);
1544 gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
1545 break;
1546
1547 case 0x15: lf.ftoi.d
1548 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
1549 check_of64s(dc);
1550 gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
1551 break;
1552
1553 case 0x16: lf.rem.d
1554 LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
1555 check_of64s(dc);
1556 gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1557 break;
1558
1559 case 0x17: lf.madd.d
1560 LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
1561 check_of64s(dc);
1562 gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
1563 break;
1564
1565 case 0x18: lf.sfeq.d
1566 LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
1567 check_of64s(dc);
1568 gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1569 break;
1570
1571 case 0x1a: lf.sfgt.d
1572 LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
1573 check_of64s(dc);
1574 gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1575 break;
1576
1577 case 0x1b: lf.sfge.d
1578 LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
1579 check_of64s(dc);
1580 gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1581 break;
1582
1583 case 0x19: lf.sfne.d
1584 LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
1585 check_of64s(dc);
1586 gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1587 break;
1588
1589 case 0x1c: lf.sflt.d
1590 LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
1591 check_of64s(dc);
1592 gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1593 break;
1594
1595 case 0x1d: lf.sfle.d
1596 LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
1597 check_of64s(dc);
1598 gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
1599 break;
1600 #endif*/
1601
1602 default:
1603 gen_illegal_exception(dc);
1604 break;
1605 }
1606 wb_SR_F();
1607 }
1608
1609 static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
1610 {
1611 uint32_t op0;
1612 uint32_t insn;
1613 insn = cpu_ldl_code(&cpu->env, dc->pc);
1614 op0 = extract32(insn, 26, 6);
1615
1616 switch (op0) {
1617 case 0x06:
1618 dec_M(dc, insn);
1619 break;
1620
1621 case 0x08:
1622 dec_sys(dc, insn);
1623 break;
1624
1625 case 0x2e:
1626 dec_logic(dc, insn);
1627 break;
1628
1629 case 0x2f:
1630 dec_compi(dc, insn);
1631 break;
1632
1633 case 0x31:
1634 dec_mac(dc, insn);
1635 break;
1636
1637 case 0x32:
1638 dec_float(dc, insn);
1639 break;
1640
1641 case 0x38:
1642 dec_calc(dc, insn);
1643 break;
1644
1645 case 0x39:
1646 dec_comp(dc, insn);
1647 break;
1648
1649 default:
1650 dec_misc(dc, insn);
1651 break;
1652 }
1653 }
1654
1655 static void check_breakpoint(OpenRISCCPU *cpu, DisasContext *dc)
1656 {
1657 CPUBreakpoint *bp;
1658
1659 if (unlikely(!QTAILQ_EMPTY(&cpu->env.breakpoints))) {
1660 QTAILQ_FOREACH(bp, &cpu->env.breakpoints, entry) {
1661 if (bp->pc == dc->pc) {
1662 tcg_gen_movi_tl(cpu_pc, dc->pc);
1663 gen_exception(dc, EXCP_DEBUG);
1664 dc->is_jmp = DISAS_UPDATE;
1665 }
1666 }
1667 }
1668 }
1669
1670 static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
1671 TranslationBlock *tb,
1672 int search_pc)
1673 {
1674 CPUState *cs = CPU(cpu);
1675 struct DisasContext ctx, *dc = &ctx;
1676 uint16_t *gen_opc_end;
1677 uint32_t pc_start;
1678 int j, k;
1679 uint32_t next_page_start;
1680 int num_insns;
1681 int max_insns;
1682
1683 pc_start = tb->pc;
1684 dc->tb = tb;
1685
1686 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
1687 dc->is_jmp = DISAS_NEXT;
1688 dc->ppc = pc_start;
1689 dc->pc = pc_start;
1690 dc->flags = cpu->env.cpucfgr;
1691 dc->mem_idx = cpu_mmu_index(&cpu->env);
1692 dc->synced_flags = dc->tb_flags = tb->flags;
1693 dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
1694 dc->singlestep_enabled = cs->singlestep_enabled;
1695 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1696 qemu_log("-----------------------------------------\n");
1697 log_cpu_state(CPU(cpu), 0);
1698 }
1699
1700 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1701 k = -1;
1702 num_insns = 0;
1703 max_insns = tb->cflags & CF_COUNT_MASK;
1704
1705 if (max_insns == 0) {
1706 max_insns = CF_COUNT_MASK;
1707 }
1708
1709 gen_tb_start();
1710
1711 do {
1712 check_breakpoint(cpu, dc);
1713 if (search_pc) {
1714 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
1715 if (k < j) {
1716 k++;
1717 while (k < j) {
1718 tcg_ctx.gen_opc_instr_start[k++] = 0;
1719 }
1720 }
1721 tcg_ctx.gen_opc_pc[k] = dc->pc;
1722 tcg_ctx.gen_opc_instr_start[k] = 1;
1723 tcg_ctx.gen_opc_icount[k] = num_insns;
1724 }
1725
1726 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
1727 tcg_gen_debug_insn_start(dc->pc);
1728 }
1729
1730 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
1731 gen_io_start();
1732 }
1733 dc->ppc = dc->pc - 4;
1734 dc->npc = dc->pc + 4;
1735 tcg_gen_movi_tl(cpu_ppc, dc->ppc);
1736 tcg_gen_movi_tl(cpu_npc, dc->npc);
1737 disas_openrisc_insn(dc, cpu);
1738 dc->pc = dc->npc;
1739 num_insns++;
1740 /* delay slot */
1741 if (dc->delayed_branch) {
1742 dc->delayed_branch--;
1743 if (!dc->delayed_branch) {
1744 dc->tb_flags &= ~D_FLAG;
1745 gen_sync_flags(dc);
1746 tcg_gen_mov_tl(cpu_pc, jmp_pc);
1747 tcg_gen_mov_tl(cpu_npc, jmp_pc);
1748 tcg_gen_movi_tl(jmp_pc, 0);
1749 tcg_gen_exit_tb(0);
1750 dc->is_jmp = DISAS_JUMP;
1751 break;
1752 }
1753 }
1754 } while (!dc->is_jmp
1755 && tcg_ctx.gen_opc_ptr < gen_opc_end
1756 && !cs->singlestep_enabled
1757 && !singlestep
1758 && (dc->pc < next_page_start)
1759 && num_insns < max_insns);
1760
1761 if (tb->cflags & CF_LAST_IO) {
1762 gen_io_end();
1763 }
1764 if (dc->is_jmp == DISAS_NEXT) {
1765 dc->is_jmp = DISAS_UPDATE;
1766 tcg_gen_movi_tl(cpu_pc, dc->pc);
1767 }
1768 if (unlikely(cs->singlestep_enabled)) {
1769 if (dc->is_jmp == DISAS_NEXT) {
1770 tcg_gen_movi_tl(cpu_pc, dc->pc);
1771 }
1772 gen_exception(dc, EXCP_DEBUG);
1773 } else {
1774 switch (dc->is_jmp) {
1775 case DISAS_NEXT:
1776 gen_goto_tb(dc, 0, dc->pc);
1777 break;
1778 default:
1779 case DISAS_JUMP:
1780 break;
1781 case DISAS_UPDATE:
1782 /* indicate that the hash table must be used
1783 to find the next TB */
1784 tcg_gen_exit_tb(0);
1785 break;
1786 case DISAS_TB_JUMP:
1787 /* nothing more to generate */
1788 break;
1789 }
1790 }
1791
1792 gen_tb_end(tb, num_insns);
1793 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
1794 if (search_pc) {
1795 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
1796 k++;
1797 while (k <= j) {
1798 tcg_ctx.gen_opc_instr_start[k++] = 0;
1799 }
1800 } else {
1801 tb->size = dc->pc - pc_start;
1802 tb->icount = num_insns;
1803 }
1804
1805 #ifdef DEBUG_DISAS
1806 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1807 qemu_log("\n");
1808 log_target_disas(&cpu->env, pc_start, dc->pc - pc_start, 0);
1809 qemu_log("\nisize=%d osize=%td\n",
1810 dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
1811 tcg_ctx.gen_opc_buf);
1812 }
1813 #endif
1814 }
1815
1816 void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
1817 {
1818 gen_intermediate_code_internal(openrisc_env_get_cpu(env), tb, 0);
1819 }
1820
1821 void gen_intermediate_code_pc(CPUOpenRISCState *env,
1822 struct TranslationBlock *tb)
1823 {
1824 gen_intermediate_code_internal(openrisc_env_get_cpu(env), tb, 1);
1825 }
1826
1827 void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
1828 fprintf_function cpu_fprintf,
1829 int flags)
1830 {
1831 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
1832 CPUOpenRISCState *env = &cpu->env;
1833 int i;
1834
1835 cpu_fprintf(f, "PC=%08x\n", env->pc);
1836 for (i = 0; i < 32; ++i) {
1837 cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i],
1838 (i % 4) == 3 ? '\n' : ' ');
1839 }
1840 }
1841
1842 void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
1843 int pc_pos)
1844 {
1845 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
1846 }