]> Git Repo - qemu.git/blob - target/lm32/translate.c
tricore: cleanup cpu type name composition
[qemu.git] / target / lm32 / translate.c
1 /*
2  *  LatticeMico32 main translation routines.
3  *
4  *  Copyright (c) 2010 Michael Walle <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "disas/disas.h"
23 #include "exec/helper-proto.h"
24 #include "exec/exec-all.h"
25 #include "exec/translator.h"
26 #include "tcg-op.h"
27
28 #include "exec/cpu_ldst.h"
29 #include "hw/lm32/lm32_pic.h"
30
31 #include "exec/helper-gen.h"
32
33 #include "trace-tcg.h"
34 #include "exec/log.h"
35
36
37 #define DISAS_LM32 0
38
39 #define LOG_DIS(...) \
40     do { \
41         if (DISAS_LM32) { \
42             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
43         } \
44     } while (0)
45
46 #define EXTRACT_FIELD(src, start, end) \
47             (((src) >> start) & ((1 << (end - start + 1)) - 1))
48
49 #define MEM_INDEX 0
50
51 /* is_jmp field values */
52 #define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
53 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
54 #define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
55
56 static TCGv cpu_R[32];
57 static TCGv cpu_pc;
58 static TCGv cpu_ie;
59 static TCGv cpu_icc;
60 static TCGv cpu_dcc;
61 static TCGv cpu_cc;
62 static TCGv cpu_cfg;
63 static TCGv cpu_eba;
64 static TCGv cpu_dc;
65 static TCGv cpu_deba;
66 static TCGv cpu_bp[4];
67 static TCGv cpu_wp[4];
68
69 #include "exec/gen-icount.h"
70
71 enum {
72     OP_FMT_RI,
73     OP_FMT_RR,
74     OP_FMT_CR,
75     OP_FMT_I
76 };
77
78 /* This is the state at translation time.  */
79 typedef struct DisasContext {
80     target_ulong pc;
81
82     /* Decoder.  */
83     int format;
84     uint32_t ir;
85     uint8_t opcode;
86     uint8_t r0, r1, r2, csr;
87     uint16_t imm5;
88     uint16_t imm16;
89     uint32_t imm26;
90
91     unsigned int delayed_branch;
92     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
93     int is_jmp;
94
95     struct TranslationBlock *tb;
96     int singlestep_enabled;
97
98     uint32_t features;
99     uint8_t num_breakpoints;
100     uint8_t num_watchpoints;
101 } DisasContext;
102
103 static const char *regnames[] = {
104     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
106     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
107     "r24", "r25", "r26/gp", "r27/fp", "r28/sp", "r29/ra",
108     "r30/ea", "r31/ba", "bp0", "bp1", "bp2", "bp3", "wp0",
109     "wp1", "wp2", "wp3"
110 };
111
112 static inline int zero_extend(unsigned int val, int width)
113 {
114     return val & ((1 << width) - 1);
115 }
116
117 static inline int sign_extend(unsigned int val, int width)
118 {
119     int sval;
120
121     /* LSL.  */
122     val <<= 32 - width;
123     sval = val;
124     /* ASR.  */
125     sval >>= 32 - width;
126
127     return sval;
128 }
129
130 static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
131 {
132     TCGv_i32 tmp = tcg_const_i32(index);
133
134     gen_helper_raise_exception(cpu_env, tmp);
135     tcg_temp_free_i32(tmp);
136 }
137
138 static inline void t_gen_illegal_insn(DisasContext *dc)
139 {
140     tcg_gen_movi_tl(cpu_pc, dc->pc);
141     gen_helper_ill(cpu_env);
142 }
143
144 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
145 {
146     if (unlikely(dc->singlestep_enabled)) {
147         return false;
148     }
149
150 #ifndef CONFIG_USER_ONLY
151     return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
152 #else
153     return true;
154 #endif
155 }
156
157 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
158 {
159     if (use_goto_tb(dc, dest)) {
160         tcg_gen_goto_tb(n);
161         tcg_gen_movi_tl(cpu_pc, dest);
162         tcg_gen_exit_tb((uintptr_t)dc->tb + n);
163     } else {
164         tcg_gen_movi_tl(cpu_pc, dest);
165         if (dc->singlestep_enabled) {
166             t_gen_raise_exception(dc, EXCP_DEBUG);
167         }
168         tcg_gen_exit_tb(0);
169     }
170 }
171
172 static void dec_add(DisasContext *dc)
173 {
174     if (dc->format == OP_FMT_RI) {
175         if (dc->r0 == R_R0) {
176             if (dc->r1 == R_R0 && dc->imm16 == 0) {
177                 LOG_DIS("nop\n");
178             } else {
179                 LOG_DIS("mvi r%d, %d\n", dc->r1, sign_extend(dc->imm16, 16));
180             }
181         } else {
182             LOG_DIS("addi r%d, r%d, %d\n", dc->r1, dc->r0,
183                     sign_extend(dc->imm16, 16));
184         }
185     } else {
186         LOG_DIS("add r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
187     }
188
189     if (dc->format == OP_FMT_RI) {
190         tcg_gen_addi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
191                 sign_extend(dc->imm16, 16));
192     } else {
193         tcg_gen_add_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
194     }
195 }
196
197 static void dec_and(DisasContext *dc)
198 {
199     if (dc->format == OP_FMT_RI) {
200         LOG_DIS("andi r%d, r%d, %d\n", dc->r1, dc->r0,
201                 zero_extend(dc->imm16, 16));
202     } else {
203         LOG_DIS("and r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
204     }
205
206     if (dc->format == OP_FMT_RI) {
207         tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
208                 zero_extend(dc->imm16, 16));
209     } else  {
210         if (dc->r0 == 0 && dc->r1 == 0 && dc->r2 == 0) {
211             tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
212             gen_helper_hlt(cpu_env);
213         } else {
214             tcg_gen_and_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
215         }
216     }
217 }
218
219 static void dec_andhi(DisasContext *dc)
220 {
221     LOG_DIS("andhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
222
223     tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
224 }
225
226 static void dec_b(DisasContext *dc)
227 {
228     if (dc->r0 == R_RA) {
229         LOG_DIS("ret\n");
230     } else if (dc->r0 == R_EA) {
231         LOG_DIS("eret\n");
232     } else if (dc->r0 == R_BA) {
233         LOG_DIS("bret\n");
234     } else {
235         LOG_DIS("b r%d\n", dc->r0);
236     }
237
238     /* restore IE.IE in case of an eret */
239     if (dc->r0 == R_EA) {
240         TCGv t0 = tcg_temp_new();
241         TCGLabel *l1 = gen_new_label();
242         tcg_gen_andi_tl(t0, cpu_ie, IE_EIE);
243         tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
244         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_EIE, l1);
245         tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
246         gen_set_label(l1);
247         tcg_temp_free(t0);
248     } else if (dc->r0 == R_BA) {
249         TCGv t0 = tcg_temp_new();
250         TCGLabel *l1 = gen_new_label();
251         tcg_gen_andi_tl(t0, cpu_ie, IE_BIE);
252         tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
253         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_BIE, l1);
254         tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
255         gen_set_label(l1);
256         tcg_temp_free(t0);
257     }
258     tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
259
260     dc->is_jmp = DISAS_JUMP;
261 }
262
263 static void dec_bi(DisasContext *dc)
264 {
265     LOG_DIS("bi %d\n", sign_extend(dc->imm26 << 2, 26));
266
267     gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
268
269     dc->is_jmp = DISAS_TB_JUMP;
270 }
271
272 static inline void gen_cond_branch(DisasContext *dc, int cond)
273 {
274     TCGLabel *l1 = gen_new_label();
275     tcg_gen_brcond_tl(cond, cpu_R[dc->r0], cpu_R[dc->r1], l1);
276     gen_goto_tb(dc, 0, dc->pc + 4);
277     gen_set_label(l1);
278     gen_goto_tb(dc, 1, dc->pc + (sign_extend(dc->imm16 << 2, 16)));
279     dc->is_jmp = DISAS_TB_JUMP;
280 }
281
282 static void dec_be(DisasContext *dc)
283 {
284     LOG_DIS("be r%d, r%d, %d\n", dc->r1, dc->r0,
285             sign_extend(dc->imm16, 16) * 4);
286
287     gen_cond_branch(dc, TCG_COND_EQ);
288 }
289
290 static void dec_bg(DisasContext *dc)
291 {
292     LOG_DIS("bg r%d, r%d, %d\n", dc->r1, dc->r0,
293             sign_extend(dc->imm16, 16 * 4));
294
295     gen_cond_branch(dc, TCG_COND_GT);
296 }
297
298 static void dec_bge(DisasContext *dc)
299 {
300     LOG_DIS("bge r%d, r%d, %d\n", dc->r1, dc->r0,
301             sign_extend(dc->imm16, 16) * 4);
302
303     gen_cond_branch(dc, TCG_COND_GE);
304 }
305
306 static void dec_bgeu(DisasContext *dc)
307 {
308     LOG_DIS("bgeu r%d, r%d, %d\n", dc->r1, dc->r0,
309             sign_extend(dc->imm16, 16) * 4);
310
311     gen_cond_branch(dc, TCG_COND_GEU);
312 }
313
314 static void dec_bgu(DisasContext *dc)
315 {
316     LOG_DIS("bgu r%d, r%d, %d\n", dc->r1, dc->r0,
317             sign_extend(dc->imm16, 16) * 4);
318
319     gen_cond_branch(dc, TCG_COND_GTU);
320 }
321
322 static void dec_bne(DisasContext *dc)
323 {
324     LOG_DIS("bne r%d, r%d, %d\n", dc->r1, dc->r0,
325             sign_extend(dc->imm16, 16) * 4);
326
327     gen_cond_branch(dc, TCG_COND_NE);
328 }
329
330 static void dec_call(DisasContext *dc)
331 {
332     LOG_DIS("call r%d\n", dc->r0);
333
334     tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
335     tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
336
337     dc->is_jmp = DISAS_JUMP;
338 }
339
340 static void dec_calli(DisasContext *dc)
341 {
342     LOG_DIS("calli %d\n", sign_extend(dc->imm26, 26) * 4);
343
344     tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
345     gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
346
347     dc->is_jmp = DISAS_TB_JUMP;
348 }
349
350 static inline void gen_compare(DisasContext *dc, int cond)
351 {
352     int i;
353
354     if (dc->format == OP_FMT_RI) {
355         switch (cond) {
356         case TCG_COND_GEU:
357         case TCG_COND_GTU:
358             i = zero_extend(dc->imm16, 16);
359             break;
360         default:
361             i = sign_extend(dc->imm16, 16);
362             break;
363         }
364
365         tcg_gen_setcondi_tl(cond, cpu_R[dc->r1], cpu_R[dc->r0], i);
366     } else {
367         tcg_gen_setcond_tl(cond, cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
368     }
369 }
370
371 static void dec_cmpe(DisasContext *dc)
372 {
373     if (dc->format == OP_FMT_RI) {
374         LOG_DIS("cmpei r%d, r%d, %d\n", dc->r1, dc->r0,
375                 sign_extend(dc->imm16, 16));
376     } else {
377         LOG_DIS("cmpe r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
378     }
379
380     gen_compare(dc, TCG_COND_EQ);
381 }
382
383 static void dec_cmpg(DisasContext *dc)
384 {
385     if (dc->format == OP_FMT_RI) {
386         LOG_DIS("cmpgi r%d, r%d, %d\n", dc->r1, dc->r0,
387                 sign_extend(dc->imm16, 16));
388     } else {
389         LOG_DIS("cmpg r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
390     }
391
392     gen_compare(dc, TCG_COND_GT);
393 }
394
395 static void dec_cmpge(DisasContext *dc)
396 {
397     if (dc->format == OP_FMT_RI) {
398         LOG_DIS("cmpgei r%d, r%d, %d\n", dc->r1, dc->r0,
399                 sign_extend(dc->imm16, 16));
400     } else {
401         LOG_DIS("cmpge r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
402     }
403
404     gen_compare(dc, TCG_COND_GE);
405 }
406
407 static void dec_cmpgeu(DisasContext *dc)
408 {
409     if (dc->format == OP_FMT_RI) {
410         LOG_DIS("cmpgeui r%d, r%d, %d\n", dc->r1, dc->r0,
411                 zero_extend(dc->imm16, 16));
412     } else {
413         LOG_DIS("cmpgeu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
414     }
415
416     gen_compare(dc, TCG_COND_GEU);
417 }
418
419 static void dec_cmpgu(DisasContext *dc)
420 {
421     if (dc->format == OP_FMT_RI) {
422         LOG_DIS("cmpgui r%d, r%d, %d\n", dc->r1, dc->r0,
423                 zero_extend(dc->imm16, 16));
424     } else {
425         LOG_DIS("cmpgu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
426     }
427
428     gen_compare(dc, TCG_COND_GTU);
429 }
430
431 static void dec_cmpne(DisasContext *dc)
432 {
433     if (dc->format == OP_FMT_RI) {
434         LOG_DIS("cmpnei r%d, r%d, %d\n", dc->r1, dc->r0,
435                 sign_extend(dc->imm16, 16));
436     } else {
437         LOG_DIS("cmpne r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
438     }
439
440     gen_compare(dc, TCG_COND_NE);
441 }
442
443 static void dec_divu(DisasContext *dc)
444 {
445     TCGLabel *l1;
446
447     LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
448
449     if (!(dc->features & LM32_FEATURE_DIVIDE)) {
450         qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
451         t_gen_illegal_insn(dc);
452         return;
453     }
454
455     l1 = gen_new_label();
456     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
457     tcg_gen_movi_tl(cpu_pc, dc->pc);
458     t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
459     gen_set_label(l1);
460     tcg_gen_divu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
461 }
462
463 static void dec_lb(DisasContext *dc)
464 {
465     TCGv t0;
466
467     LOG_DIS("lb r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
468
469     t0 = tcg_temp_new();
470     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
471     tcg_gen_qemu_ld8s(cpu_R[dc->r1], t0, MEM_INDEX);
472     tcg_temp_free(t0);
473 }
474
475 static void dec_lbu(DisasContext *dc)
476 {
477     TCGv t0;
478
479     LOG_DIS("lbu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
480
481     t0 = tcg_temp_new();
482     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
483     tcg_gen_qemu_ld8u(cpu_R[dc->r1], t0, MEM_INDEX);
484     tcg_temp_free(t0);
485 }
486
487 static void dec_lh(DisasContext *dc)
488 {
489     TCGv t0;
490
491     LOG_DIS("lh r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
492
493     t0 = tcg_temp_new();
494     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
495     tcg_gen_qemu_ld16s(cpu_R[dc->r1], t0, MEM_INDEX);
496     tcg_temp_free(t0);
497 }
498
499 static void dec_lhu(DisasContext *dc)
500 {
501     TCGv t0;
502
503     LOG_DIS("lhu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
504
505     t0 = tcg_temp_new();
506     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
507     tcg_gen_qemu_ld16u(cpu_R[dc->r1], t0, MEM_INDEX);
508     tcg_temp_free(t0);
509 }
510
511 static void dec_lw(DisasContext *dc)
512 {
513     TCGv t0;
514
515     LOG_DIS("lw r%d, (r%d+%d)\n", dc->r1, dc->r0, sign_extend(dc->imm16, 16));
516
517     t0 = tcg_temp_new();
518     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
519     tcg_gen_qemu_ld32s(cpu_R[dc->r1], t0, MEM_INDEX);
520     tcg_temp_free(t0);
521 }
522
523 static void dec_modu(DisasContext *dc)
524 {
525     TCGLabel *l1;
526
527     LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);
528
529     if (!(dc->features & LM32_FEATURE_DIVIDE)) {
530         qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
531         t_gen_illegal_insn(dc);
532         return;
533     }
534
535     l1 = gen_new_label();
536     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
537     tcg_gen_movi_tl(cpu_pc, dc->pc);
538     t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
539     gen_set_label(l1);
540     tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
541 }
542
543 static void dec_mul(DisasContext *dc)
544 {
545     if (dc->format == OP_FMT_RI) {
546         LOG_DIS("muli r%d, r%d, %d\n", dc->r1, dc->r0,
547                 sign_extend(dc->imm16, 16));
548     } else {
549         LOG_DIS("mul r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
550     }
551
552     if (!(dc->features & LM32_FEATURE_MULTIPLY)) {
553         qemu_log_mask(LOG_GUEST_ERROR,
554                       "hardware multiplier is not available\n");
555         t_gen_illegal_insn(dc);
556         return;
557     }
558
559     if (dc->format == OP_FMT_RI) {
560         tcg_gen_muli_tl(cpu_R[dc->r1], cpu_R[dc->r0],
561                 sign_extend(dc->imm16, 16));
562     } else {
563         tcg_gen_mul_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
564     }
565 }
566
567 static void dec_nor(DisasContext *dc)
568 {
569     if (dc->format == OP_FMT_RI) {
570         LOG_DIS("nori r%d, r%d, %d\n", dc->r1, dc->r0,
571                 zero_extend(dc->imm16, 16));
572     } else {
573         LOG_DIS("nor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
574     }
575
576     if (dc->format == OP_FMT_RI) {
577         TCGv t0 = tcg_temp_new();
578         tcg_gen_movi_tl(t0, zero_extend(dc->imm16, 16));
579         tcg_gen_nor_tl(cpu_R[dc->r1], cpu_R[dc->r0], t0);
580         tcg_temp_free(t0);
581     } else {
582         tcg_gen_nor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
583     }
584 }
585
586 static void dec_or(DisasContext *dc)
587 {
588     if (dc->format == OP_FMT_RI) {
589         LOG_DIS("ori r%d, r%d, %d\n", dc->r1, dc->r0,
590                 zero_extend(dc->imm16, 16));
591     } else {
592         if (dc->r1 == R_R0) {
593             LOG_DIS("mv r%d, r%d\n", dc->r2, dc->r0);
594         } else {
595             LOG_DIS("or r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
596         }
597     }
598
599     if (dc->format == OP_FMT_RI) {
600         tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
601                 zero_extend(dc->imm16, 16));
602     } else {
603         tcg_gen_or_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
604     }
605 }
606
607 static void dec_orhi(DisasContext *dc)
608 {
609     if (dc->r0 == R_R0) {
610         LOG_DIS("mvhi r%d, %d\n", dc->r1, dc->imm16);
611     } else {
612         LOG_DIS("orhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
613     }
614
615     tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
616 }
617
618 static void dec_scall(DisasContext *dc)
619 {
620     switch (dc->imm5) {
621     case 2:
622         LOG_DIS("break\n");
623         tcg_gen_movi_tl(cpu_pc, dc->pc);
624         t_gen_raise_exception(dc, EXCP_BREAKPOINT);
625         break;
626     case 7:
627         LOG_DIS("scall\n");
628         tcg_gen_movi_tl(cpu_pc, dc->pc);
629         t_gen_raise_exception(dc, EXCP_SYSTEMCALL);
630         break;
631     default:
632         qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode @0x%x", dc->pc);
633         t_gen_illegal_insn(dc);
634         break;
635     }
636 }
637
638 static void dec_rcsr(DisasContext *dc)
639 {
640     LOG_DIS("rcsr r%d, %d\n", dc->r2, dc->csr);
641
642     switch (dc->csr) {
643     case CSR_IE:
644         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_ie);
645         break;
646     case CSR_IM:
647         gen_helper_rcsr_im(cpu_R[dc->r2], cpu_env);
648         break;
649     case CSR_IP:
650         gen_helper_rcsr_ip(cpu_R[dc->r2], cpu_env);
651         break;
652     case CSR_CC:
653         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cc);
654         break;
655     case CSR_CFG:
656         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cfg);
657         break;
658     case CSR_EBA:
659         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_eba);
660         break;
661     case CSR_DC:
662         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_dc);
663         break;
664     case CSR_DEBA:
665         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_deba);
666         break;
667     case CSR_JTX:
668         gen_helper_rcsr_jtx(cpu_R[dc->r2], cpu_env);
669         break;
670     case CSR_JRX:
671         gen_helper_rcsr_jrx(cpu_R[dc->r2], cpu_env);
672         break;
673     case CSR_ICC:
674     case CSR_DCC:
675     case CSR_BP0:
676     case CSR_BP1:
677     case CSR_BP2:
678     case CSR_BP3:
679     case CSR_WP0:
680     case CSR_WP1:
681     case CSR_WP2:
682     case CSR_WP3:
683         qemu_log_mask(LOG_GUEST_ERROR, "invalid read access csr=%x\n", dc->csr);
684         break;
685     default:
686         qemu_log_mask(LOG_GUEST_ERROR, "read_csr: unknown csr=%x\n", dc->csr);
687         break;
688     }
689 }
690
691 static void dec_sb(DisasContext *dc)
692 {
693     TCGv t0;
694
695     LOG_DIS("sb (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
696
697     t0 = tcg_temp_new();
698     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
699     tcg_gen_qemu_st8(cpu_R[dc->r1], t0, MEM_INDEX);
700     tcg_temp_free(t0);
701 }
702
703 static void dec_sextb(DisasContext *dc)
704 {
705     LOG_DIS("sextb r%d, r%d\n", dc->r2, dc->r0);
706
707     if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
708         qemu_log_mask(LOG_GUEST_ERROR,
709                       "hardware sign extender is not available\n");
710         t_gen_illegal_insn(dc);
711         return;
712     }
713
714     tcg_gen_ext8s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
715 }
716
717 static void dec_sexth(DisasContext *dc)
718 {
719     LOG_DIS("sexth r%d, r%d\n", dc->r2, dc->r0);
720
721     if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
722         qemu_log_mask(LOG_GUEST_ERROR,
723                       "hardware sign extender is not available\n");
724         t_gen_illegal_insn(dc);
725         return;
726     }
727
728     tcg_gen_ext16s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
729 }
730
731 static void dec_sh(DisasContext *dc)
732 {
733     TCGv t0;
734
735     LOG_DIS("sh (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
736
737     t0 = tcg_temp_new();
738     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
739     tcg_gen_qemu_st16(cpu_R[dc->r1], t0, MEM_INDEX);
740     tcg_temp_free(t0);
741 }
742
743 static void dec_sl(DisasContext *dc)
744 {
745     if (dc->format == OP_FMT_RI) {
746         LOG_DIS("sli r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
747     } else {
748         LOG_DIS("sl r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
749     }
750
751     if (!(dc->features & LM32_FEATURE_SHIFT)) {
752         qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n");
753         t_gen_illegal_insn(dc);
754         return;
755     }
756
757     if (dc->format == OP_FMT_RI) {
758         tcg_gen_shli_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
759     } else {
760         TCGv t0 = tcg_temp_new();
761         tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
762         tcg_gen_shl_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
763         tcg_temp_free(t0);
764     }
765 }
766
767 static void dec_sr(DisasContext *dc)
768 {
769     if (dc->format == OP_FMT_RI) {
770         LOG_DIS("sri r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
771     } else {
772         LOG_DIS("sr r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
773     }
774
775     /* The real CPU (w/o hardware shifter) only supports right shift by exactly
776      * one bit */
777     if (dc->format == OP_FMT_RI) {
778         if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
779             qemu_log_mask(LOG_GUEST_ERROR,
780                     "hardware shifter is not available\n");
781             t_gen_illegal_insn(dc);
782             return;
783         }
784         tcg_gen_sari_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
785     } else {
786         TCGLabel *l1 = gen_new_label();
787         TCGLabel *l2 = gen_new_label();
788         TCGv t0 = tcg_temp_local_new();
789         tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
790
791         if (!(dc->features & LM32_FEATURE_SHIFT)) {
792             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
793             t_gen_illegal_insn(dc);
794             tcg_gen_br(l2);
795         }
796
797         gen_set_label(l1);
798         tcg_gen_sar_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
799         gen_set_label(l2);
800
801         tcg_temp_free(t0);
802     }
803 }
804
805 static void dec_sru(DisasContext *dc)
806 {
807     if (dc->format == OP_FMT_RI) {
808         LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
809     } else {
810         LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
811     }
812
813     if (dc->format == OP_FMT_RI) {
814         if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
815             qemu_log_mask(LOG_GUEST_ERROR,
816                     "hardware shifter is not available\n");
817             t_gen_illegal_insn(dc);
818             return;
819         }
820         tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
821     } else {
822         TCGLabel *l1 = gen_new_label();
823         TCGLabel *l2 = gen_new_label();
824         TCGv t0 = tcg_temp_local_new();
825         tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
826
827         if (!(dc->features & LM32_FEATURE_SHIFT)) {
828             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
829             t_gen_illegal_insn(dc);
830             tcg_gen_br(l2);
831         }
832
833         gen_set_label(l1);
834         tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
835         gen_set_label(l2);
836
837         tcg_temp_free(t0);
838     }
839 }
840
841 static void dec_sub(DisasContext *dc)
842 {
843     LOG_DIS("sub r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
844
845     tcg_gen_sub_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
846 }
847
848 static void dec_sw(DisasContext *dc)
849 {
850     TCGv t0;
851
852     LOG_DIS("sw (r%d+%d), r%d\n", dc->r0, sign_extend(dc->imm16, 16), dc->r1);
853
854     t0 = tcg_temp_new();
855     tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
856     tcg_gen_qemu_st32(cpu_R[dc->r1], t0, MEM_INDEX);
857     tcg_temp_free(t0);
858 }
859
860 static void dec_user(DisasContext *dc)
861 {
862     LOG_DIS("user");
863
864     qemu_log_mask(LOG_GUEST_ERROR, "user instruction undefined\n");
865     t_gen_illegal_insn(dc);
866 }
867
868 static void dec_wcsr(DisasContext *dc)
869 {
870     int no;
871
872     LOG_DIS("wcsr %d, r%d\n", dc->csr, dc->r1);
873
874     switch (dc->csr) {
875     case CSR_IE:
876         tcg_gen_mov_tl(cpu_ie, cpu_R[dc->r1]);
877         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
878         dc->is_jmp = DISAS_UPDATE;
879         break;
880     case CSR_IM:
881         /* mark as an io operation because it could cause an interrupt */
882         if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
883             gen_io_start();
884         }
885         gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
886         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
887         if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
888             gen_io_end();
889         }
890         dc->is_jmp = DISAS_UPDATE;
891         break;
892     case CSR_IP:
893         /* mark as an io operation because it could cause an interrupt */
894         if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
895             gen_io_start();
896         }
897         gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
898         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
899         if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
900             gen_io_end();
901         }
902         dc->is_jmp = DISAS_UPDATE;
903         break;
904     case CSR_ICC:
905         /* TODO */
906         break;
907     case CSR_DCC:
908         /* TODO */
909         break;
910     case CSR_EBA:
911         tcg_gen_mov_tl(cpu_eba, cpu_R[dc->r1]);
912         break;
913     case CSR_DEBA:
914         tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);
915         break;
916     case CSR_JTX:
917         gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);
918         break;
919     case CSR_JRX:
920         gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
921         break;
922     case CSR_DC:
923         gen_helper_wcsr_dc(cpu_env, cpu_R[dc->r1]);
924         break;
925     case CSR_BP0:
926     case CSR_BP1:
927     case CSR_BP2:
928     case CSR_BP3:
929         no = dc->csr - CSR_BP0;
930         if (dc->num_breakpoints <= no) {
931             qemu_log_mask(LOG_GUEST_ERROR,
932                           "breakpoint #%i is not available\n", no);
933             t_gen_illegal_insn(dc);
934             break;
935         }
936         gen_helper_wcsr_bp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
937         break;
938     case CSR_WP0:
939     case CSR_WP1:
940     case CSR_WP2:
941     case CSR_WP3:
942         no = dc->csr - CSR_WP0;
943         if (dc->num_watchpoints <= no) {
944             qemu_log_mask(LOG_GUEST_ERROR,
945                           "watchpoint #%i is not available\n", no);
946             t_gen_illegal_insn(dc);
947             break;
948         }
949         gen_helper_wcsr_wp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
950         break;
951     case CSR_CC:
952     case CSR_CFG:
953         qemu_log_mask(LOG_GUEST_ERROR, "invalid write access csr=%x\n",
954                       dc->csr);
955         break;
956     default:
957         qemu_log_mask(LOG_GUEST_ERROR, "write_csr: unknown csr=%x\n",
958                       dc->csr);
959         break;
960     }
961 }
962
963 static void dec_xnor(DisasContext *dc)
964 {
965     if (dc->format == OP_FMT_RI) {
966         LOG_DIS("xnori r%d, r%d, %d\n", dc->r1, dc->r0,
967                 zero_extend(dc->imm16, 16));
968     } else {
969         if (dc->r1 == R_R0) {
970             LOG_DIS("not r%d, r%d\n", dc->r2, dc->r0);
971         } else {
972             LOG_DIS("xnor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
973         }
974     }
975
976     if (dc->format == OP_FMT_RI) {
977         tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
978                 zero_extend(dc->imm16, 16));
979         tcg_gen_not_tl(cpu_R[dc->r1], cpu_R[dc->r1]);
980     } else {
981         tcg_gen_eqv_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
982     }
983 }
984
985 static void dec_xor(DisasContext *dc)
986 {
987     if (dc->format == OP_FMT_RI) {
988         LOG_DIS("xori r%d, r%d, %d\n", dc->r1, dc->r0,
989                 zero_extend(dc->imm16, 16));
990     } else {
991         LOG_DIS("xor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
992     }
993
994     if (dc->format == OP_FMT_RI) {
995         tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
996                 zero_extend(dc->imm16, 16));
997     } else {
998         tcg_gen_xor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
999     }
1000 }
1001
1002 static void dec_ill(DisasContext *dc)
1003 {
1004     qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode 0x%02x\n", dc->opcode);
1005     t_gen_illegal_insn(dc);
1006 }
1007
1008 typedef void (*DecoderInfo)(DisasContext *dc);
1009 static const DecoderInfo decinfo[] = {
1010     dec_sru, dec_nor, dec_mul, dec_sh, dec_lb, dec_sr, dec_xor, dec_lh,
1011     dec_and, dec_xnor, dec_lw, dec_lhu, dec_sb, dec_add, dec_or, dec_sl,
1012     dec_lbu, dec_be, dec_bg, dec_bge, dec_bgeu, dec_bgu, dec_sw, dec_bne,
1013     dec_andhi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_orhi,
1014     dec_cmpne,
1015     dec_sru, dec_nor, dec_mul, dec_divu, dec_rcsr, dec_sr, dec_xor, dec_ill,
1016     dec_and, dec_xnor, dec_ill, dec_scall, dec_sextb, dec_add, dec_or, dec_sl,
1017     dec_b, dec_modu, dec_sub, dec_user, dec_wcsr, dec_ill, dec_call, dec_sexth,
1018     dec_bi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_calli,
1019     dec_cmpne
1020 };
1021
1022 static inline void decode(DisasContext *dc, uint32_t ir)
1023 {
1024     dc->ir = ir;
1025     LOG_DIS("%8.8x\t", dc->ir);
1026
1027     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
1028
1029     dc->imm5 = EXTRACT_FIELD(ir, 0, 4);
1030     dc->imm16 = EXTRACT_FIELD(ir, 0, 15);
1031     dc->imm26 = EXTRACT_FIELD(ir, 0, 25);
1032
1033     dc->csr = EXTRACT_FIELD(ir, 21, 25);
1034     dc->r0 = EXTRACT_FIELD(ir, 21, 25);
1035     dc->r1 = EXTRACT_FIELD(ir, 16, 20);
1036     dc->r2 = EXTRACT_FIELD(ir, 11, 15);
1037
1038     /* bit 31 seems to indicate insn type.  */
1039     if (ir & (1 << 31)) {
1040         dc->format = OP_FMT_RR;
1041     } else {
1042         dc->format = OP_FMT_RI;
1043     }
1044
1045     assert(ARRAY_SIZE(decinfo) == 64);
1046     assert(dc->opcode < 64);
1047
1048     decinfo[dc->opcode](dc);
1049 }
1050
1051 /* generate intermediate code for basic block 'tb'.  */
1052 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
1053 {
1054     CPULM32State *env = cs->env_ptr;
1055     LM32CPU *cpu = lm32_env_get_cpu(env);
1056     struct DisasContext ctx, *dc = &ctx;
1057     uint32_t pc_start;
1058     uint32_t next_page_start;
1059     int num_insns;
1060     int max_insns;
1061
1062     pc_start = tb->pc;
1063     dc->features = cpu->features;
1064     dc->num_breakpoints = cpu->num_breakpoints;
1065     dc->num_watchpoints = cpu->num_watchpoints;
1066     dc->tb = tb;
1067
1068     dc->is_jmp = DISAS_NEXT;
1069     dc->pc = pc_start;
1070     dc->singlestep_enabled = cs->singlestep_enabled;
1071
1072     if (pc_start & 3) {
1073         qemu_log_mask(LOG_GUEST_ERROR,
1074                       "unaligned PC=%x. Ignoring lowest bits.\n", pc_start);
1075         pc_start &= ~3;
1076     }
1077
1078     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1079     num_insns = 0;
1080     max_insns = tb_cflags(tb) & CF_COUNT_MASK;
1081     if (max_insns == 0) {
1082         max_insns = CF_COUNT_MASK;
1083     }
1084     if (max_insns > TCG_MAX_INSNS) {
1085         max_insns = TCG_MAX_INSNS;
1086     }
1087
1088     gen_tb_start(tb);
1089     do {
1090         tcg_gen_insn_start(dc->pc);
1091         num_insns++;
1092
1093         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
1094             tcg_gen_movi_tl(cpu_pc, dc->pc);
1095             t_gen_raise_exception(dc, EXCP_DEBUG);
1096             dc->is_jmp = DISAS_UPDATE;
1097             /* The address covered by the breakpoint must be included in
1098                [tb->pc, tb->pc + tb->size) in order to for it to be
1099                properly cleared -- thus we increment the PC here so that
1100                the logic setting tb->size below does the right thing.  */
1101             dc->pc += 4;
1102             break;
1103         }
1104
1105         /* Pretty disas.  */
1106         LOG_DIS("%8.8x:\t", dc->pc);
1107
1108         if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
1109             gen_io_start();
1110         }
1111
1112         decode(dc, cpu_ldl_code(env, dc->pc));
1113         dc->pc += 4;
1114     } while (!dc->is_jmp
1115          && !tcg_op_buf_full()
1116          && !cs->singlestep_enabled
1117          && !singlestep
1118          && (dc->pc < next_page_start)
1119          && num_insns < max_insns);
1120
1121     if (tb_cflags(tb) & CF_LAST_IO) {
1122         gen_io_end();
1123     }
1124
1125     if (unlikely(cs->singlestep_enabled)) {
1126         if (dc->is_jmp == DISAS_NEXT) {
1127             tcg_gen_movi_tl(cpu_pc, dc->pc);
1128         }
1129         t_gen_raise_exception(dc, EXCP_DEBUG);
1130     } else {
1131         switch (dc->is_jmp) {
1132         case DISAS_NEXT:
1133             gen_goto_tb(dc, 1, dc->pc);
1134             break;
1135         default:
1136         case DISAS_JUMP:
1137         case DISAS_UPDATE:
1138             /* indicate that the hash table must be used
1139                to find the next TB */
1140             tcg_gen_exit_tb(0);
1141             break;
1142         case DISAS_TB_JUMP:
1143             /* nothing more to generate */
1144             break;
1145         }
1146     }
1147
1148     gen_tb_end(tb, num_insns);
1149
1150     tb->size = dc->pc - pc_start;
1151     tb->icount = num_insns;
1152
1153 #ifdef DEBUG_DISAS
1154     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1155         && qemu_log_in_addr_range(pc_start)) {
1156         qemu_log_lock();
1157         qemu_log("\n");
1158         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
1159         qemu_log("\nisize=%d osize=%d\n",
1160                  dc->pc - pc_start, tcg_op_buf_count());
1161         qemu_log_unlock();
1162     }
1163 #endif
1164 }
1165
1166 void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
1167                          int flags)
1168 {
1169     LM32CPU *cpu = LM32_CPU(cs);
1170     CPULM32State *env = &cpu->env;
1171     int i;
1172
1173     if (!env || !f) {
1174         return;
1175     }
1176
1177     cpu_fprintf(f, "IN: PC=%x %s\n",
1178                 env->pc, lookup_symbol(env->pc));
1179
1180     cpu_fprintf(f, "ie=%8.8x (IE=%x EIE=%x BIE=%x) im=%8.8x ip=%8.8x\n",
1181              env->ie,
1182              (env->ie & IE_IE) ? 1 : 0,
1183              (env->ie & IE_EIE) ? 1 : 0,
1184              (env->ie & IE_BIE) ? 1 : 0,
1185              lm32_pic_get_im(env->pic_state),
1186              lm32_pic_get_ip(env->pic_state));
1187     cpu_fprintf(f, "eba=%8.8x deba=%8.8x\n",
1188              env->eba,
1189              env->deba);
1190
1191     for (i = 0; i < 32; i++) {
1192         cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
1193         if ((i + 1) % 4 == 0) {
1194             cpu_fprintf(f, "\n");
1195         }
1196     }
1197     cpu_fprintf(f, "\n\n");
1198 }
1199
1200 void restore_state_to_opc(CPULM32State *env, TranslationBlock *tb,
1201                           target_ulong *data)
1202 {
1203     env->pc = data[0];
1204 }
1205
1206 void lm32_translate_init(void)
1207 {
1208     int i;
1209
1210     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
1211         cpu_R[i] = tcg_global_mem_new(cpu_env,
1212                           offsetof(CPULM32State, regs[i]),
1213                           regnames[i]);
1214     }
1215
1216     for (i = 0; i < ARRAY_SIZE(cpu_bp); i++) {
1217         cpu_bp[i] = tcg_global_mem_new(cpu_env,
1218                           offsetof(CPULM32State, bp[i]),
1219                           regnames[32+i]);
1220     }
1221
1222     for (i = 0; i < ARRAY_SIZE(cpu_wp); i++) {
1223         cpu_wp[i] = tcg_global_mem_new(cpu_env,
1224                           offsetof(CPULM32State, wp[i]),
1225                           regnames[36+i]);
1226     }
1227
1228     cpu_pc = tcg_global_mem_new(cpu_env,
1229                     offsetof(CPULM32State, pc),
1230                     "pc");
1231     cpu_ie = tcg_global_mem_new(cpu_env,
1232                     offsetof(CPULM32State, ie),
1233                     "ie");
1234     cpu_icc = tcg_global_mem_new(cpu_env,
1235                     offsetof(CPULM32State, icc),
1236                     "icc");
1237     cpu_dcc = tcg_global_mem_new(cpu_env,
1238                     offsetof(CPULM32State, dcc),
1239                     "dcc");
1240     cpu_cc = tcg_global_mem_new(cpu_env,
1241                     offsetof(CPULM32State, cc),
1242                     "cc");
1243     cpu_cfg = tcg_global_mem_new(cpu_env,
1244                     offsetof(CPULM32State, cfg),
1245                     "cfg");
1246     cpu_eba = tcg_global_mem_new(cpu_env,
1247                     offsetof(CPULM32State, eba),
1248                     "eba");
1249     cpu_dc = tcg_global_mem_new(cpu_env,
1250                     offsetof(CPULM32State, dc),
1251                     "dc");
1252     cpu_deba = tcg_global_mem_new(cpu_env,
1253                     offsetof(CPULM32State, deba),
1254                     "deba");
1255 }
1256
This page took 0.100933 seconds and 4 git commands to generate.