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

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.