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