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