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