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