Annotation of qemu/target-lm32/translate.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com