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