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

1.1       root        1: /*
                      2:  *  Xilinx MicroBlaze emulation for qemu: main translation routines.
                      3:  *
                      4:  *  Copyright (c) 2009 Edgar E. Iglesias.
                      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 "exec-all.h"
                     29: #include "disas.h"
                     30: #include "tcg-op.h"
                     31: #include "helper.h"
                     32: #include "microblaze-decode.h"
                     33: #include "qemu-common.h"
                     34: 
                     35: #define GEN_HELPER 1
                     36: #include "helper.h"
                     37: 
                     38: #define SIM_COMPAT 0
                     39: #define DISAS_GNU 1
                     40: #define DISAS_MB 1
                     41: #if DISAS_MB && !SIM_COMPAT
                     42: #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
                     43: #else
                     44: #  define LOG_DIS(...) do { } while (0)
                     45: #endif
                     46: 
                     47: #define D(x)
                     48: 
                     49: #define EXTRACT_FIELD(src, start, end) \
                     50:             (((src) >> start) & ((1 << (end - start + 1)) - 1))
                     51: 
                     52: static TCGv env_debug;
                     53: static TCGv_ptr cpu_env;
                     54: static TCGv cpu_R[32];
                     55: static TCGv cpu_SR[18];
                     56: static TCGv env_imm;
                     57: static TCGv env_btaken;
                     58: static TCGv env_btarget;
                     59: static TCGv env_iflags;
                     60: 
                     61: #include "gen-icount.h"
                     62: 
                     63: /* This is the state at translation time.  */
                     64: typedef struct DisasContext {
                     65:     CPUState *env;
                     66:     target_ulong pc, ppc;
                     67:     target_ulong cache_pc;
                     68: 
                     69:     /* Decoder.  */
                     70:     int type_b;
                     71:     uint32_t ir;
                     72:     uint8_t opcode;
                     73:     uint8_t rd, ra, rb;
                     74:     uint16_t imm;
                     75: 
                     76:     unsigned int cpustate_changed;
                     77:     unsigned int delayed_branch;
                     78:     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
                     79:     unsigned int clear_imm;
                     80:     int is_jmp;
                     81: 
                     82: #define JMP_NOJMP    0
                     83: #define JMP_DIRECT   1
                     84: #define JMP_INDIRECT 2
                     85:     unsigned int jmp;
                     86:     uint32_t jmp_pc;
                     87: 
                     88:     int abort_at_next_insn;
                     89:     int nr_nops;
                     90:     struct TranslationBlock *tb;
                     91:     int singlestep_enabled;
                     92: } DisasContext;
                     93: 
1.1.1.2 ! root       94: static const char *regnames[] =
1.1       root       95: {
                     96:     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
                     97:     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
                     98:     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
                     99:     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
                    100: };
                    101: 
1.1.1.2 ! root      102: static const char *special_regnames[] =
1.1       root      103: {
                    104:     "rpc", "rmsr", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
                    105:     "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
                    106:     "sr16", "sr17", "sr18"
                    107: };
                    108: 
                    109: /* Sign extend at translation time.  */
                    110: static inline int sign_extend(unsigned int val, unsigned int width)
                    111: {
                    112:         int sval;
                    113: 
                    114:         /* LSL.  */
                    115:         val <<= 31 - width;
                    116:         sval = val;
                    117:         /* ASR.  */
                    118:         sval >>= 31 - width;
                    119:         return sval;
                    120: }
                    121: 
                    122: static inline void t_sync_flags(DisasContext *dc)
                    123: {
                    124:     /* Synch the tb dependant flags between translator and runtime.  */
                    125:     if (dc->tb_flags != dc->synced_flags) {
                    126:         tcg_gen_movi_tl(env_iflags, dc->tb_flags);
                    127:         dc->synced_flags = dc->tb_flags;
                    128:     }
                    129: }
                    130: 
                    131: static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
                    132: {
                    133:     TCGv_i32 tmp = tcg_const_i32(index);
                    134: 
                    135:     t_sync_flags(dc);
                    136:     tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
                    137:     gen_helper_raise_exception(tmp);
                    138:     tcg_temp_free_i32(tmp);
                    139:     dc->is_jmp = DISAS_UPDATE;
                    140: }
                    141: 
                    142: static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
                    143: {
                    144:     TranslationBlock *tb;
                    145:     tb = dc->tb;
                    146:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
                    147:         tcg_gen_goto_tb(n);
                    148:         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
                    149:         tcg_gen_exit_tb((long)tb + n);
                    150:     } else {
                    151:         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
                    152:         tcg_gen_exit_tb(0);
                    153:     }
                    154: }
                    155: 
                    156: static inline TCGv *dec_alu_op_b(DisasContext *dc)
                    157: {
                    158:     if (dc->type_b) {
                    159:         if (dc->tb_flags & IMM_FLAG)
                    160:             tcg_gen_ori_tl(env_imm, env_imm, dc->imm);
                    161:         else
                    162:             tcg_gen_movi_tl(env_imm, (int32_t)((int16_t)dc->imm));
                    163:         return &env_imm;
                    164:     } else
                    165:         return &cpu_R[dc->rb];
                    166: }
                    167: 
                    168: static void dec_add(DisasContext *dc)
                    169: {
                    170:     unsigned int k, c;
                    171: 
                    172:     k = dc->opcode & 4;
                    173:     c = dc->opcode & 2;
                    174: 
                    175:     LOG_DIS("add%s%s%s r%d r%d r%d\n",
                    176:             dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
                    177:             dc->rd, dc->ra, dc->rb);
                    178: 
                    179:     if (k && !c && dc->rd)
                    180:         tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    181:     else if (dc->rd)
                    182:         gen_helper_addkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                    183:                          tcg_const_tl(k), tcg_const_tl(c));
                    184:     else {
                    185:         TCGv d = tcg_temp_new();
                    186:         gen_helper_addkc(d, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                    187:                          tcg_const_tl(k), tcg_const_tl(c));
                    188:         tcg_temp_free(d);
                    189:     }
                    190: }
                    191: 
                    192: static void dec_sub(DisasContext *dc)
                    193: {
                    194:     unsigned int u, cmp, k, c;
                    195: 
                    196:     u = dc->imm & 2;
                    197:     k = dc->opcode & 4;
                    198:     c = dc->opcode & 2;
                    199:     cmp = (dc->imm & 1) && (!dc->type_b) && k;
                    200: 
                    201:     if (cmp) {
                    202:         LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir);
                    203:         if (dc->rd) {
                    204:             if (u)
                    205:                 gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    206:             else
                    207:                 gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    208:         }
                    209:     } else {
                    210:         LOG_DIS("sub%s%s r%d, r%d r%d\n",
                    211:                  k ? "k" : "",  c ? "c" : "", dc->rd, dc->ra, dc->rb);
                    212: 
                    213:         if (!k || c) {
                    214:             TCGv t;
                    215:             t = tcg_temp_new();
                    216:             if (dc->rd)
                    217:                 gen_helper_subkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                    218:                                  tcg_const_tl(k), tcg_const_tl(c));
                    219:             else
                    220:                 gen_helper_subkc(t, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                    221:                                  tcg_const_tl(k), tcg_const_tl(c));
                    222:             tcg_temp_free(t);
                    223:         }
                    224:         else if (dc->rd)
                    225:             tcg_gen_sub_tl(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
                    226:     }
                    227: }
                    228: 
                    229: static void dec_pattern(DisasContext *dc)
                    230: {
                    231:     unsigned int mode;
                    232:     int l1;
                    233: 
1.1.1.2 ! root      234:     if ((dc->tb_flags & MSR_EE_FLAG)
        !           235:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !           236:           && !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
        !           237:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           238:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           239:     }
        !           240: 
1.1       root      241:     mode = dc->opcode & 3;
                    242:     switch (mode) {
                    243:         case 0:
                    244:             /* pcmpbf.  */
                    245:             LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    246:             if (dc->rd)
                    247:                 gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    248:             break;
                    249:         case 2:
                    250:             LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    251:             if (dc->rd) {
                    252:                 TCGv t0 = tcg_temp_local_new();
                    253:                 l1 = gen_new_label();
                    254:                 tcg_gen_movi_tl(t0, 1);
                    255:                 tcg_gen_brcond_tl(TCG_COND_EQ,
                    256:                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
                    257:                 tcg_gen_movi_tl(t0, 0);
                    258:                 gen_set_label(l1);
                    259:                 tcg_gen_mov_tl(cpu_R[dc->rd], t0);
                    260:                 tcg_temp_free(t0);
                    261:             }
                    262:             break;
                    263:         case 3:
                    264:             LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    265:             l1 = gen_new_label();
                    266:             if (dc->rd) {
                    267:                 TCGv t0 = tcg_temp_local_new();
                    268:                 tcg_gen_movi_tl(t0, 1);
                    269:                 tcg_gen_brcond_tl(TCG_COND_NE,
                    270:                                   cpu_R[dc->ra], cpu_R[dc->rb], l1);
                    271:                 tcg_gen_movi_tl(t0, 0);
                    272:                 gen_set_label(l1);
                    273:                 tcg_gen_mov_tl(cpu_R[dc->rd], t0);
                    274:                 tcg_temp_free(t0);
                    275:             }
                    276:             break;
                    277:         default:
                    278:             cpu_abort(dc->env,
                    279:                       "unsupported pattern insn opcode=%x\n", dc->opcode);
                    280:             break;
                    281:     }
                    282: }
                    283: 
                    284: static void dec_and(DisasContext *dc)
                    285: {
                    286:     unsigned int not;
                    287: 
                    288:     if (!dc->type_b && (dc->imm & (1 << 10))) {
                    289:         dec_pattern(dc);
                    290:         return;
                    291:     }
                    292: 
                    293:     not = dc->opcode & (1 << 1);
                    294:     LOG_DIS("and%s\n", not ? "n" : "");
                    295: 
                    296:     if (!dc->rd)
                    297:         return;
                    298: 
                    299:     if (not) {
                    300:         TCGv t = tcg_temp_new();
                    301:         tcg_gen_not_tl(t, *(dec_alu_op_b(dc)));
                    302:         tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], t);
                    303:         tcg_temp_free(t);
                    304:     } else
                    305:         tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    306: }
                    307: 
                    308: static void dec_or(DisasContext *dc)
                    309: {
                    310:     if (!dc->type_b && (dc->imm & (1 << 10))) {
                    311:         dec_pattern(dc);
                    312:         return;
                    313:     }
                    314: 
                    315:     LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
                    316:     if (dc->rd)
                    317:         tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    318: }
                    319: 
                    320: static void dec_xor(DisasContext *dc)
                    321: {
                    322:     if (!dc->type_b && (dc->imm & (1 << 10))) {
                    323:         dec_pattern(dc);
                    324:         return;
                    325:     }
                    326: 
                    327:     LOG_DIS("xor r%d\n", dc->rd);
                    328:     if (dc->rd)
                    329:         tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    330: }
                    331: 
                    332: static void read_carry(DisasContext *dc, TCGv d)
                    333: {
                    334:     tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
                    335: }
                    336: 
                    337: static void write_carry(DisasContext *dc, TCGv v)
                    338: {
                    339:     TCGv t0 = tcg_temp_new();
                    340:     tcg_gen_shli_tl(t0, v, 31);
                    341:     tcg_gen_sari_tl(t0, t0, 31);
                    342:     tcg_gen_mov_tl(env_debug, t0);
                    343:     tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC));
                    344:     tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR],
                    345:                     ~(MSR_C | MSR_CC));
                    346:     tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0);
                    347:     tcg_temp_free(t0);
                    348: }
                    349: 
                    350: 
                    351: static inline void msr_read(DisasContext *dc, TCGv d)
                    352: {
                    353:     tcg_gen_mov_tl(d, cpu_SR[SR_MSR]);
                    354: }
                    355: 
                    356: static inline void msr_write(DisasContext *dc, TCGv v)
                    357: {
                    358:     dc->cpustate_changed = 1;
                    359:     tcg_gen_mov_tl(cpu_SR[SR_MSR], v);
                    360:     /* PVR, we have a processor version register.  */
                    361:     tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
                    362: }
                    363: 
                    364: static void dec_msr(DisasContext *dc)
                    365: {
                    366:     TCGv t0, t1;
                    367:     unsigned int sr, to, rn;
1.1.1.2 ! root      368:     int mem_index = cpu_mmu_index(dc->env);
1.1       root      369: 
                    370:     sr = dc->imm & ((1 << 14) - 1);
                    371:     to = dc->imm & (1 << 14);
                    372:     dc->type_b = 1;
                    373:     if (to)
                    374:         dc->cpustate_changed = 1;
                    375: 
                    376:     /* msrclr and msrset.  */
                    377:     if (!(dc->imm & (1 << 15))) {
                    378:         unsigned int clr = dc->ir & (1 << 16);
                    379: 
                    380:         LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
                    381:                 dc->rd, dc->imm);
1.1.1.2 ! root      382: 
        !           383:         if (!(dc->env->pvr.regs[2] & PVR2_USE_MSR_INSTR)) {
        !           384:             /* nop??? */
        !           385:             return;
        !           386:         }
        !           387: 
        !           388:         if ((dc->tb_flags & MSR_EE_FLAG)
        !           389:             && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) {
        !           390:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !           391:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           392:             return;
        !           393:         }
        !           394: 
1.1       root      395:         if (dc->rd)
                    396:             msr_read(dc, cpu_R[dc->rd]);
                    397: 
                    398:         t0 = tcg_temp_new();
                    399:         t1 = tcg_temp_new();
                    400:         msr_read(dc, t0);
                    401:         tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc)));
                    402: 
                    403:         if (clr) {
                    404:             tcg_gen_not_tl(t1, t1);
                    405:             tcg_gen_and_tl(t0, t0, t1);
                    406:         } else
                    407:             tcg_gen_or_tl(t0, t0, t1);
                    408:         msr_write(dc, t0);
                    409:         tcg_temp_free(t0);
                    410:         tcg_temp_free(t1);
                    411:        tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
                    412:         dc->is_jmp = DISAS_UPDATE;
                    413:         return;
                    414:     }
                    415: 
1.1.1.2 ! root      416:     if (to) {
        !           417:         if ((dc->tb_flags & MSR_EE_FLAG)
        !           418:              && mem_index == MMU_USER_IDX) {
        !           419:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !           420:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           421:             return;
        !           422:         }
        !           423:     }
        !           424: 
1.1       root      425: #if !defined(CONFIG_USER_ONLY)
                    426:     /* Catch read/writes to the mmu block.  */
                    427:     if ((sr & ~0xff) == 0x1000) {
                    428:         sr &= 7;
                    429:         LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
                    430:         if (to)
                    431:             gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]);
                    432:         else
                    433:             gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr));
                    434:         return;
                    435:     }
                    436: #endif
                    437: 
                    438:     if (to) {
                    439:         LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
                    440:         switch (sr) {
                    441:             case 0:
                    442:                 break;
                    443:             case 1:
                    444:                 msr_write(dc, cpu_R[dc->ra]);
                    445:                 break;
                    446:             case 0x3:
                    447:                 tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]);
                    448:                 break;
                    449:             case 0x5:
                    450:                 tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]);
                    451:                 break;
                    452:             case 0x7:
                    453:                 /* Ignored at the moment.  */
                    454:                 break;
                    455:             default:
                    456:                 cpu_abort(dc->env, "unknown mts reg %x\n", sr);
                    457:                 break;
                    458:         }
                    459:     } else {
                    460:         LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);
                    461: 
                    462:         switch (sr) {
                    463:             case 0:
                    464:                 tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
                    465:                 break;
                    466:             case 1:
                    467:                 msr_read(dc, cpu_R[dc->rd]);
                    468:                 break;
                    469:             case 0x3:
                    470:                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]);
                    471:                 break;
                    472:             case 0x5:
                    473:                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]);
                    474:                 break;
                    475:              case 0x7:
                    476:                 tcg_gen_movi_tl(cpu_R[dc->rd], 0);
                    477:                 break;
                    478:             case 0xb:
                    479:                 tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]);
                    480:                 break;
                    481:             case 0x2000:
                    482:             case 0x2001:
                    483:             case 0x2002:
                    484:             case 0x2003:
                    485:             case 0x2004:
                    486:             case 0x2005:
                    487:             case 0x2006:
                    488:             case 0x2007:
                    489:             case 0x2008:
                    490:             case 0x2009:
                    491:             case 0x200a:
                    492:             case 0x200b:
                    493:             case 0x200c:
                    494:                 rn = sr & 0xf;
                    495:                 tcg_gen_ld_tl(cpu_R[dc->rd],
                    496:                               cpu_env, offsetof(CPUState, pvr.regs[rn]));
                    497:                 break;
                    498:             default:
                    499:                 cpu_abort(dc->env, "unknown mfs reg %x\n", sr);
                    500:                 break;
                    501:         }
                    502:     }
1.1.1.2 ! root      503: 
        !           504:     if (dc->rd == 0) {
        !           505:         tcg_gen_movi_tl(cpu_R[0], 0);
        !           506:     }
1.1       root      507: }
                    508: 
                    509: /* 64-bit signed mul, lower result in d and upper in d2.  */
                    510: static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
                    511: {
                    512:     TCGv_i64 t0, t1;
                    513: 
                    514:     t0 = tcg_temp_new_i64();
                    515:     t1 = tcg_temp_new_i64();
                    516: 
                    517:     tcg_gen_ext_i32_i64(t0, a);
                    518:     tcg_gen_ext_i32_i64(t1, b);
                    519:     tcg_gen_mul_i64(t0, t0, t1);
                    520: 
                    521:     tcg_gen_trunc_i64_i32(d, t0);
                    522:     tcg_gen_shri_i64(t0, t0, 32);
                    523:     tcg_gen_trunc_i64_i32(d2, t0);
                    524: 
                    525:     tcg_temp_free_i64(t0);
                    526:     tcg_temp_free_i64(t1);
                    527: }
                    528: 
                    529: /* 64-bit unsigned muls, lower result in d and upper in d2.  */
                    530: static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
                    531: {
                    532:     TCGv_i64 t0, t1;
                    533: 
                    534:     t0 = tcg_temp_new_i64();
                    535:     t1 = tcg_temp_new_i64();
                    536: 
                    537:     tcg_gen_extu_i32_i64(t0, a);
                    538:     tcg_gen_extu_i32_i64(t1, b);
                    539:     tcg_gen_mul_i64(t0, t0, t1);
                    540: 
                    541:     tcg_gen_trunc_i64_i32(d, t0);
                    542:     tcg_gen_shri_i64(t0, t0, 32);
                    543:     tcg_gen_trunc_i64_i32(d2, t0);
                    544: 
                    545:     tcg_temp_free_i64(t0);
                    546:     tcg_temp_free_i64(t1);
                    547: }
                    548: 
                    549: /* Multiplier unit.  */
                    550: static void dec_mul(DisasContext *dc)
                    551: {
                    552:     TCGv d[2];
                    553:     unsigned int subcode;
                    554: 
1.1.1.2 ! root      555:     if ((dc->tb_flags & MSR_EE_FLAG)
        !           556:          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !           557:          && !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
        !           558:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           559:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           560:         return;
        !           561:     }
        !           562: 
1.1       root      563:     subcode = dc->imm & 3;
                    564:     d[0] = tcg_temp_new();
                    565:     d[1] = tcg_temp_new();
                    566: 
                    567:     if (dc->type_b) {
                    568:         LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
                    569:         t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    570:         goto done;
                    571:     }
                    572: 
1.1.1.2 ! root      573:     /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
        !           574:     if (subcode >= 1 && subcode <= 3
        !           575:         && !((dc->env->pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
        !           576:         /* nop??? */
        !           577:     }
        !           578: 
1.1       root      579:     switch (subcode) {
                    580:         case 0:
                    581:             LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    582:             t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
                    583:             break;
                    584:         case 1:
                    585:             LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    586:             t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    587:             break;
                    588:         case 2:
                    589:             LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    590:             t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    591:             break;
                    592:         case 3:
                    593:             LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
                    594:             t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
                    595:             break;
                    596:         default:
                    597:             cpu_abort(dc->env, "unknown MUL insn %x\n", subcode);
                    598:             break;
                    599:     }
                    600: done:
                    601:     tcg_temp_free(d[0]);
                    602:     tcg_temp_free(d[1]);
                    603: }
                    604: 
                    605: /* Div unit.  */
                    606: static void dec_div(DisasContext *dc)
                    607: {
                    608:     unsigned int u;
                    609: 
                    610:     u = dc->imm & 2; 
                    611:     LOG_DIS("div\n");
                    612: 
1.1.1.2 ! root      613:     if ((dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !           614:           && !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) {
        !           615:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           616:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           617:     }
        !           618: 
1.1       root      619:     if (u)
                    620:         gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
                    621:     else
                    622:         gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
                    623:     if (!dc->rd)
                    624:         tcg_gen_movi_tl(cpu_R[dc->rd], 0);
                    625: }
                    626: 
                    627: static void dec_barrel(DisasContext *dc)
                    628: {
                    629:     TCGv t0;
                    630:     unsigned int s, t;
                    631: 
1.1.1.2 ! root      632:     if ((dc->tb_flags & MSR_EE_FLAG)
        !           633:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !           634:           && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
        !           635:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           636:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           637:         return;
        !           638:     }
        !           639: 
1.1       root      640:     s = dc->imm & (1 << 10);
                    641:     t = dc->imm & (1 << 9);
                    642: 
                    643:     LOG_DIS("bs%s%s r%d r%d r%d\n",
                    644:             s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
                    645: 
                    646:     t0 = tcg_temp_new();
                    647: 
                    648:     tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
                    649:     tcg_gen_andi_tl(t0, t0, 31);
                    650: 
                    651:     if (s)
                    652:         tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
                    653:     else {
                    654:         if (t)
                    655:             tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
                    656:         else
                    657:             tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
                    658:     }
                    659: }
                    660: 
                    661: static void dec_bit(DisasContext *dc)
                    662: {
                    663:     TCGv t0, t1;
                    664:     unsigned int op;
1.1.1.2 ! root      665:     int mem_index = cpu_mmu_index(dc->env);
1.1       root      666: 
                    667:     op = dc->ir & ((1 << 8) - 1);
                    668:     switch (op) {
                    669:         case 0x21:
                    670:             /* src.  */
                    671:             t0 = tcg_temp_new();
                    672: 
                    673:             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
                    674:             tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
                    675:             if (dc->rd) {
                    676:                 t1 = tcg_temp_new();
                    677:                 read_carry(dc, t1);
                    678:                 tcg_gen_shli_tl(t1, t1, 31);
                    679: 
                    680:                 tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                    681:                 tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t1);
                    682:                 tcg_temp_free(t1);
                    683:             }
                    684: 
                    685:             /* Update carry.  */
                    686:             write_carry(dc, t0);
                    687:             tcg_temp_free(t0);
                    688:             break;
                    689: 
                    690:         case 0x1:
                    691:         case 0x41:
                    692:             /* srl.  */
                    693:             t0 = tcg_temp_new();
                    694:             LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
                    695: 
                    696:             /* Update carry.  */
                    697:             tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
                    698:             write_carry(dc, t0);
                    699:             tcg_temp_free(t0);
                    700:             if (dc->rd) {
                    701:                 if (op == 0x41)
                    702:                     tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                    703:                 else
                    704:                     tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                    705:             }
                    706:             break;
                    707:         case 0x60:
                    708:             LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
                    709:             tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
                    710:             break;
                    711:         case 0x61:
                    712:             LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
                    713:             tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
                    714:             break;
                    715:         case 0x64:
                    716:             /* wdc.  */
                    717:             LOG_DIS("wdc r%d\n", dc->ra);
1.1.1.2 ! root      718:             if ((dc->tb_flags & MSR_EE_FLAG)
        !           719:                  && mem_index == MMU_USER_IDX) {
        !           720:                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !           721:                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           722:                 return;
        !           723:             }
1.1       root      724:             break;
                    725:         case 0x68:
                    726:             /* wic.  */
                    727:             LOG_DIS("wic r%d\n", dc->ra);
1.1.1.2 ! root      728:             if ((dc->tb_flags & MSR_EE_FLAG)
        !           729:                  && mem_index == MMU_USER_IDX) {
        !           730:                 tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !           731:                 t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           732:                 return;
        !           733:             }
1.1       root      734:             break;
                    735:         default:
                    736:             cpu_abort(dc->env, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
                    737:                      dc->pc, op, dc->rd, dc->ra, dc->rb);
                    738:             break;
                    739:     }
                    740: }
                    741: 
                    742: static inline void sync_jmpstate(DisasContext *dc)
                    743: {
                    744:     if (dc->jmp == JMP_DIRECT) {
                    745:             dc->jmp = JMP_INDIRECT;
                    746:             tcg_gen_movi_tl(env_btaken, 1);
                    747:             tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
                    748:     }
                    749: }
                    750: 
                    751: static void dec_imm(DisasContext *dc)
                    752: {
                    753:     LOG_DIS("imm %x\n", dc->imm << 16);
                    754:     tcg_gen_movi_tl(env_imm, (dc->imm << 16));
                    755:     dc->tb_flags |= IMM_FLAG;
                    756:     dc->clear_imm = 0;
                    757: }
                    758: 
                    759: static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
                    760:                             unsigned int size)
                    761: {
                    762:     int mem_index = cpu_mmu_index(dc->env);
                    763: 
                    764:     if (size == 1) {
                    765:         tcg_gen_qemu_ld8u(dst, addr, mem_index);
                    766:     } else if (size == 2) {
                    767:         tcg_gen_qemu_ld16u(dst, addr, mem_index);
                    768:     } else if (size == 4) {
                    769:         tcg_gen_qemu_ld32u(dst, addr, mem_index);
                    770:     } else
                    771:         cpu_abort(dc->env, "Incorrect load size %d\n", size);
                    772: }
                    773: 
                    774: static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
                    775: {
                    776:     unsigned int extimm = dc->tb_flags & IMM_FLAG;
                    777: 
                    778:     /* Treat the fast cases first.  */
                    779:     if (!dc->type_b) {
                    780:         *t = tcg_temp_new();
                    781:         tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
                    782:         return t;
                    783:     }
                    784:     /* Immediate.  */
                    785:     if (!extimm) {
                    786:         if (dc->imm == 0) {
                    787:             return &cpu_R[dc->ra];
                    788:         }
                    789:         *t = tcg_temp_new();
                    790:         tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm));
                    791:         tcg_gen_add_tl(*t, cpu_R[dc->ra], *t);
                    792:     } else {
                    793:         *t = tcg_temp_new();
                    794:         tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                    795:     }
                    796: 
                    797:     return t;
                    798: }
                    799: 
                    800: static void dec_load(DisasContext *dc)
                    801: {
                    802:     TCGv t, *addr;
                    803:     unsigned int size;
                    804: 
                    805:     size = 1 << (dc->opcode & 3);
1.1.1.2 ! root      806:     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
        !           807:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        !           808:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           809:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           810:         return;
        !           811:     }
1.1       root      812: 
                    813:     LOG_DIS("l %x %d\n", dc->opcode, size);
                    814:     t_sync_flags(dc);
                    815:     addr = compute_ldst_addr(dc, &t);
                    816: 
                    817:     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
                    818:     sync_jmpstate(dc);
1.1.1.2 ! root      819: 
        !           820:     /* Verify alignment if needed.  */
        !           821:     if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
        !           822:         TCGv v = tcg_temp_new();
        !           823: 
        !           824:         /*
        !           825:          * Microblaze gives MMU faults priority over faults due to
        !           826:          * unaligned addresses. That's why we speculatively do the load
        !           827:          * into v. If the load succeeds, we verify alignment of the
        !           828:          * address and if that succeeds we write into the destination reg.
        !           829:          */
        !           830:         gen_load(dc, v, *addr, size);
        !           831: 
        !           832:         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
        !           833:         gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
        !           834:                             tcg_const_tl(0), tcg_const_tl(size - 1));
        !           835:         if (dc->rd)
        !           836:             tcg_gen_mov_tl(cpu_R[dc->rd], v);
        !           837:         tcg_temp_free(v);
        !           838:     } else {
        !           839:         if (dc->rd) {
        !           840:             gen_load(dc, cpu_R[dc->rd], *addr, size);
        !           841:         } else {
        !           842:             gen_load(dc, env_imm, *addr, size);
        !           843:         }
1.1       root      844:     }
                    845: 
                    846:     if (addr == &t)
                    847:         tcg_temp_free(t);
                    848: }
                    849: 
                    850: static void gen_store(DisasContext *dc, TCGv addr, TCGv val,
                    851:                       unsigned int size)
                    852: {
                    853:     int mem_index = cpu_mmu_index(dc->env);
                    854: 
                    855:     if (size == 1)
                    856:         tcg_gen_qemu_st8(val, addr, mem_index);
                    857:     else if (size == 2) {
                    858:         tcg_gen_qemu_st16(val, addr, mem_index);
                    859:     } else if (size == 4) {
                    860:         tcg_gen_qemu_st32(val, addr, mem_index);
                    861:     } else
                    862:         cpu_abort(dc->env, "Incorrect store size %d\n", size);
                    863: }
                    864: 
                    865: static void dec_store(DisasContext *dc)
                    866: {
                    867:     TCGv t, *addr;
                    868:     unsigned int size;
                    869: 
                    870:     size = 1 << (dc->opcode & 3);
                    871: 
1.1.1.2 ! root      872:     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
        !           873:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        !           874:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !           875:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !           876:         return;
        !           877:     }
        !           878: 
1.1       root      879:     LOG_DIS("s%d%s\n", size, dc->type_b ? "i" : "");
                    880:     t_sync_flags(dc);
                    881:     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
                    882:     sync_jmpstate(dc);
                    883:     addr = compute_ldst_addr(dc, &t);
1.1.1.2 ! root      884: 
1.1       root      885:     gen_store(dc, *addr, cpu_R[dc->rd], size);
1.1.1.2 ! root      886: 
        !           887:     /* Verify alignment if needed.  */
        !           888:     if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
        !           889:         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
        !           890:         /* FIXME: if the alignment is wrong, we should restore the value
        !           891:          *        in memory.
        !           892:          */
        !           893:         gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
        !           894:                             tcg_const_tl(1), tcg_const_tl(size - 1));
        !           895:     }
        !           896: 
1.1       root      897:     if (addr == &t)
                    898:         tcg_temp_free(t);
                    899: }
                    900: 
                    901: static inline void eval_cc(DisasContext *dc, unsigned int cc,
                    902:                            TCGv d, TCGv a, TCGv b)
                    903: {
                    904:     int l1;
                    905: 
                    906:     switch (cc) {
                    907:         case CC_EQ:
                    908:             l1 = gen_new_label();
                    909:             tcg_gen_movi_tl(env_btaken, 1);
                    910:             tcg_gen_brcond_tl(TCG_COND_EQ, a, b, l1);
                    911:             tcg_gen_movi_tl(env_btaken, 0);
                    912:             gen_set_label(l1);
                    913:             break;
                    914:         case CC_NE:
                    915:             l1 = gen_new_label();
                    916:             tcg_gen_movi_tl(env_btaken, 1);
                    917:             tcg_gen_brcond_tl(TCG_COND_NE, a, b, l1);
                    918:             tcg_gen_movi_tl(env_btaken, 0);
                    919:             gen_set_label(l1);
                    920:             break;
                    921:         case CC_LT:
                    922:             l1 = gen_new_label();
                    923:             tcg_gen_movi_tl(env_btaken, 1);
                    924:             tcg_gen_brcond_tl(TCG_COND_LT, a, b, l1);
                    925:             tcg_gen_movi_tl(env_btaken, 0);
                    926:             gen_set_label(l1);
                    927:             break;
                    928:         case CC_LE:
                    929:             l1 = gen_new_label();
                    930:             tcg_gen_movi_tl(env_btaken, 1);
                    931:             tcg_gen_brcond_tl(TCG_COND_LE, a, b, l1);
                    932:             tcg_gen_movi_tl(env_btaken, 0);
                    933:             gen_set_label(l1);
                    934:             break;
                    935:         case CC_GE:
                    936:             l1 = gen_new_label();
                    937:             tcg_gen_movi_tl(env_btaken, 1);
                    938:             tcg_gen_brcond_tl(TCG_COND_GE, a, b, l1);
                    939:             tcg_gen_movi_tl(env_btaken, 0);
                    940:             gen_set_label(l1);
                    941:             break;
                    942:         case CC_GT:
                    943:             l1 = gen_new_label();
                    944:             tcg_gen_movi_tl(env_btaken, 1);
                    945:             tcg_gen_brcond_tl(TCG_COND_GT, a, b, l1);
                    946:             tcg_gen_movi_tl(env_btaken, 0);
                    947:             gen_set_label(l1);
                    948:             break;
                    949:         default:
                    950:             cpu_abort(dc->env, "Unknown condition code %x.\n", cc);
                    951:             break;
                    952:     }
                    953: }
                    954: 
                    955: static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false)
                    956: {
                    957:     int l1;
                    958: 
                    959:     l1 = gen_new_label();
                    960:     /* Conditional jmp.  */
                    961:     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);
                    962:     tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
                    963:     tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);
                    964:     gen_set_label(l1);
                    965: }
                    966: 
                    967: static void dec_bcc(DisasContext *dc)
                    968: {
                    969:     unsigned int cc;
                    970:     unsigned int dslot;
                    971: 
                    972:     cc = EXTRACT_FIELD(dc->ir, 21, 23);
                    973:     dslot = dc->ir & (1 << 25);
                    974:     LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);
                    975: 
                    976:     dc->delayed_branch = 1;
                    977:     if (dslot) {
                    978:         dc->delayed_branch = 2;
                    979:         dc->tb_flags |= D_FLAG;
                    980:         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                    981:                       cpu_env, offsetof(CPUState, bimm));
                    982:     }
                    983: 
                    984:     tcg_gen_movi_tl(env_btarget, dc->pc);
                    985:     tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
                    986:     eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
                    987:     dc->jmp = JMP_INDIRECT;
                    988: }
                    989: 
                    990: static void dec_br(DisasContext *dc)
                    991: {
                    992:     unsigned int dslot, link, abs;
                    993: 
                    994:     dslot = dc->ir & (1 << 20);
                    995:     abs = dc->ir & (1 << 19);
                    996:     link = dc->ir & (1 << 18);
                    997:     LOG_DIS("br%s%s%s%s imm=%x\n",
                    998:              abs ? "a" : "", link ? "l" : "",
                    999:              dc->type_b ? "i" : "", dslot ? "d" : "",
                   1000:              dc->imm);
                   1001: 
                   1002:     dc->delayed_branch = 1;
                   1003:     if (dslot) {
                   1004:         dc->delayed_branch = 2;
                   1005:         dc->tb_flags |= D_FLAG;
                   1006:         tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                   1007:                       cpu_env, offsetof(CPUState, bimm));
                   1008:     }
                   1009:     if (link && dc->rd)
                   1010:         tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
                   1011: 
                   1012:     dc->jmp = JMP_INDIRECT;
                   1013:     if (abs) {
                   1014:         tcg_gen_movi_tl(env_btaken, 1);
                   1015:         tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
                   1016:         if (link && !(dc->tb_flags & IMM_FLAG)
                   1017:             && (dc->imm == 8 || dc->imm == 0x18))
                   1018:             t_gen_raise_exception(dc, EXCP_BREAK);
                   1019:         if (dc->imm == 0)
                   1020:             t_gen_raise_exception(dc, EXCP_DEBUG);
                   1021:     } else {
                   1022:         if (dc->tb_flags & IMM_FLAG) {
                   1023:             tcg_gen_movi_tl(env_btaken, 1);
                   1024:             tcg_gen_movi_tl(env_btarget, dc->pc);
                   1025:             tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
                   1026:         } else {
                   1027:             dc->jmp = JMP_DIRECT;
                   1028:             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
                   1029:         }
                   1030:     }
                   1031: }
                   1032: 
                   1033: static inline void do_rti(DisasContext *dc)
                   1034: {
                   1035:     TCGv t0, t1;
                   1036:     t0 = tcg_temp_new();
                   1037:     t1 = tcg_temp_new();
                   1038:     tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
                   1039:     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE);
                   1040:     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
                   1041: 
                   1042:     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
                   1043:     tcg_gen_or_tl(t1, t1, t0);
                   1044:     msr_write(dc, t1);
                   1045:     tcg_temp_free(t1);
                   1046:     tcg_temp_free(t0);
                   1047:     dc->tb_flags &= ~DRTI_FLAG;
                   1048: }
                   1049: 
                   1050: static inline void do_rtb(DisasContext *dc)
                   1051: {
                   1052:     TCGv t0, t1;
                   1053:     t0 = tcg_temp_new();
                   1054:     t1 = tcg_temp_new();
                   1055:     tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP);
                   1056:     tcg_gen_shri_tl(t0, t1, 1);
                   1057:     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
                   1058: 
                   1059:     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
                   1060:     tcg_gen_or_tl(t1, t1, t0);
                   1061:     msr_write(dc, t1);
                   1062:     tcg_temp_free(t1);
                   1063:     tcg_temp_free(t0);
                   1064:     dc->tb_flags &= ~DRTB_FLAG;
                   1065: }
                   1066: 
                   1067: static inline void do_rte(DisasContext *dc)
                   1068: {
                   1069:     TCGv t0, t1;
                   1070:     t0 = tcg_temp_new();
                   1071:     t1 = tcg_temp_new();
                   1072: 
                   1073:     tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE);
                   1074:     tcg_gen_andi_tl(t1, t1, ~MSR_EIP);
                   1075:     tcg_gen_shri_tl(t0, t1, 1);
                   1076:     tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));
                   1077: 
                   1078:     tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
                   1079:     tcg_gen_or_tl(t1, t1, t0);
                   1080:     msr_write(dc, t1);
                   1081:     tcg_temp_free(t1);
                   1082:     tcg_temp_free(t0);
                   1083:     dc->tb_flags &= ~DRTE_FLAG;
                   1084: }
                   1085: 
                   1086: static void dec_rts(DisasContext *dc)
                   1087: {
                   1088:     unsigned int b_bit, i_bit, e_bit;
1.1.1.2 ! root     1089:     int mem_index = cpu_mmu_index(dc->env);
1.1       root     1090: 
                   1091:     i_bit = dc->ir & (1 << 21);
                   1092:     b_bit = dc->ir & (1 << 22);
                   1093:     e_bit = dc->ir & (1 << 23);
                   1094: 
                   1095:     dc->delayed_branch = 2;
                   1096:     dc->tb_flags |= D_FLAG;
                   1097:     tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                   1098:                   cpu_env, offsetof(CPUState, bimm));
                   1099: 
                   1100:     if (i_bit) {
                   1101:         LOG_DIS("rtid ir=%x\n", dc->ir);
1.1.1.2 ! root     1102:         if ((dc->tb_flags & MSR_EE_FLAG)
        !          1103:              && mem_index == MMU_USER_IDX) {
        !          1104:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !          1105:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1106:         }
1.1       root     1107:         dc->tb_flags |= DRTI_FLAG;
                   1108:     } else if (b_bit) {
                   1109:         LOG_DIS("rtbd ir=%x\n", dc->ir);
1.1.1.2 ! root     1110:         if ((dc->tb_flags & MSR_EE_FLAG)
        !          1111:              && mem_index == MMU_USER_IDX) {
        !          1112:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !          1113:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1114:         }
1.1       root     1115:         dc->tb_flags |= DRTB_FLAG;
                   1116:     } else if (e_bit) {
                   1117:         LOG_DIS("rted ir=%x\n", dc->ir);
1.1.1.2 ! root     1118:         if ((dc->tb_flags & MSR_EE_FLAG)
        !          1119:              && mem_index == MMU_USER_IDX) {
        !          1120:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
        !          1121:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1122:         }
1.1       root     1123:         dc->tb_flags |= DRTE_FLAG;
                   1124:     } else
                   1125:         LOG_DIS("rts ir=%x\n", dc->ir);
                   1126: 
                   1127:     tcg_gen_movi_tl(env_btaken, 1);
                   1128:     tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
                   1129: }
                   1130: 
1.1.1.2 ! root     1131: static void dec_fpu(DisasContext *dc)
        !          1132: {
        !          1133:     if ((dc->tb_flags & MSR_EE_FLAG)
        !          1134:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !          1135:           && !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) {
        !          1136:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
        !          1137:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1138:         return;
        !          1139:     }
        !          1140: 
        !          1141:     qemu_log ("unimplemented FPU insn pc=%x opc=%x\n", dc->pc, dc->opcode);
        !          1142:     dc->abort_at_next_insn = 1;
        !          1143: }
        !          1144: 
1.1       root     1145: static void dec_null(DisasContext *dc)
                   1146: {
1.1.1.2 ! root     1147:     if ((dc->tb_flags & MSR_EE_FLAG)
        !          1148:           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        !          1149:         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !          1150:         t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1151:         return;
        !          1152:     }
1.1       root     1153:     qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
                   1154:     dc->abort_at_next_insn = 1;
                   1155: }
                   1156: 
                   1157: static struct decoder_info {
                   1158:     struct {
                   1159:         uint32_t bits;
                   1160:         uint32_t mask;
                   1161:     };
                   1162:     void (*dec)(DisasContext *dc);
                   1163: } decinfo[] = {
                   1164:     {DEC_ADD, dec_add},
                   1165:     {DEC_SUB, dec_sub},
                   1166:     {DEC_AND, dec_and},
                   1167:     {DEC_XOR, dec_xor},
                   1168:     {DEC_OR, dec_or},
                   1169:     {DEC_BIT, dec_bit},
                   1170:     {DEC_BARREL, dec_barrel},
                   1171:     {DEC_LD, dec_load},
                   1172:     {DEC_ST, dec_store},
                   1173:     {DEC_IMM, dec_imm},
                   1174:     {DEC_BR, dec_br},
                   1175:     {DEC_BCC, dec_bcc},
                   1176:     {DEC_RTS, dec_rts},
1.1.1.2 ! root     1177:     {DEC_FPU, dec_fpu},
1.1       root     1178:     {DEC_MUL, dec_mul},
                   1179:     {DEC_DIV, dec_div},
                   1180:     {DEC_MSR, dec_msr},
                   1181:     {{0, 0}, dec_null}
                   1182: };
                   1183: 
                   1184: static inline void decode(DisasContext *dc)
                   1185: {
                   1186:     uint32_t ir;
                   1187:     int i;
                   1188: 
                   1189:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   1190:         tcg_gen_debug_insn_start(dc->pc);
                   1191: 
                   1192:     dc->ir = ir = ldl_code(dc->pc);
                   1193:     LOG_DIS("%8.8x\t", dc->ir);
                   1194: 
                   1195:     if (dc->ir)
                   1196:         dc->nr_nops = 0;
                   1197:     else {
1.1.1.2 ! root     1198:         if ((dc->tb_flags & MSR_EE_FLAG)
        !          1199:               && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
        !          1200:               && (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
        !          1201:             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        !          1202:             t_gen_raise_exception(dc, EXCP_HW_EXCP);
        !          1203:             return;
        !          1204:         }
        !          1205: 
1.1       root     1206:         LOG_DIS("nr_nops=%d\t", dc->nr_nops);
                   1207:         dc->nr_nops++;
                   1208:         if (dc->nr_nops > 4)
                   1209:             cpu_abort(dc->env, "fetching nop sequence\n");
                   1210:     }
                   1211:     /* bit 2 seems to indicate insn type.  */
                   1212:     dc->type_b = ir & (1 << 29);
                   1213: 
                   1214:     dc->opcode = EXTRACT_FIELD(ir, 26, 31);
                   1215:     dc->rd = EXTRACT_FIELD(ir, 21, 25);
                   1216:     dc->ra = EXTRACT_FIELD(ir, 16, 20);
                   1217:     dc->rb = EXTRACT_FIELD(ir, 11, 15);
                   1218:     dc->imm = EXTRACT_FIELD(ir, 0, 15);
                   1219: 
                   1220:     /* Large switch for all insns.  */
                   1221:     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
                   1222:         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
                   1223:             decinfo[i].dec(dc);
                   1224:             break;
                   1225:         }
                   1226:     }
                   1227: }
                   1228: 
                   1229: static void check_breakpoint(CPUState *env, DisasContext *dc)
                   1230: {
                   1231:     CPUBreakpoint *bp;
                   1232: 
1.1.1.2 ! root     1233:     if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
        !          1234:         QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1       root     1235:             if (bp->pc == dc->pc) {
                   1236:                 t_gen_raise_exception(dc, EXCP_DEBUG);
                   1237:                 dc->is_jmp = DISAS_UPDATE;
                   1238:              }
                   1239:         }
                   1240:     }
                   1241: }
                   1242: 
                   1243: /* generate intermediate code for basic block 'tb'.  */
                   1244: static void
                   1245: gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                   1246:                                int search_pc)
                   1247: {
                   1248:     uint16_t *gen_opc_end;
                   1249:     uint32_t pc_start;
                   1250:     int j, lj;
                   1251:     struct DisasContext ctx;
                   1252:     struct DisasContext *dc = &ctx;
                   1253:     uint32_t next_page_start, org_flags;
                   1254:     target_ulong npc;
                   1255:     int num_insns;
                   1256:     int max_insns;
                   1257: 
                   1258:     qemu_log_try_set_file(stderr);
                   1259: 
                   1260:     pc_start = tb->pc;
                   1261:     dc->env = env;
                   1262:     dc->tb = tb;
                   1263:     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
                   1264: 
                   1265:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   1266: 
                   1267:     dc->is_jmp = DISAS_NEXT;
                   1268:     dc->jmp = 0;
                   1269:     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
                   1270:     dc->ppc = pc_start;
                   1271:     dc->pc = pc_start;
                   1272:     dc->cache_pc = -1;
                   1273:     dc->singlestep_enabled = env->singlestep_enabled;
                   1274:     dc->cpustate_changed = 0;
                   1275:     dc->abort_at_next_insn = 0;
                   1276:     dc->nr_nops = 0;
                   1277: 
                   1278:     if (pc_start & 3)
                   1279:         cpu_abort(env, "Microblaze: unaligned PC=%x\n", pc_start);
                   1280: 
                   1281:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   1282: #if !SIM_COMPAT
                   1283:         qemu_log("--------------\n");
                   1284:         log_cpu_state(env, 0);
                   1285: #endif
                   1286:     }
                   1287: 
                   1288:     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
                   1289:     lj = -1;
                   1290:     num_insns = 0;
                   1291:     max_insns = tb->cflags & CF_COUNT_MASK;
                   1292:     if (max_insns == 0)
                   1293:         max_insns = CF_COUNT_MASK;
                   1294: 
                   1295:     gen_icount_start();
                   1296:     do
                   1297:     {
                   1298: #if SIM_COMPAT
                   1299:         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   1300:             tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
                   1301:             gen_helper_debug();
                   1302:         }
                   1303: #endif
                   1304:         check_breakpoint(env, dc);
                   1305: 
                   1306:         if (search_pc) {
                   1307:             j = gen_opc_ptr - gen_opc_buf;
                   1308:             if (lj < j) {
                   1309:                 lj++;
                   1310:                 while (lj < j)
                   1311:                     gen_opc_instr_start[lj++] = 0;
                   1312:             }
                   1313:             gen_opc_pc[lj] = dc->pc;
                   1314:             gen_opc_instr_start[lj] = 1;
                   1315:                         gen_opc_icount[lj] = num_insns;
                   1316:         }
                   1317: 
                   1318:         /* Pretty disas.  */
                   1319:         LOG_DIS("%8.8x:\t", dc->pc);
                   1320: 
                   1321:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   1322:             gen_io_start();
                   1323: 
                   1324:         dc->clear_imm = 1;
                   1325:        decode(dc);
                   1326:         if (dc->clear_imm)
                   1327:             dc->tb_flags &= ~IMM_FLAG;
                   1328:         dc->ppc = dc->pc;
                   1329:         dc->pc += 4;
                   1330:         num_insns++;
                   1331: 
                   1332:         if (dc->delayed_branch) {
                   1333:             dc->delayed_branch--;
                   1334:             if (!dc->delayed_branch) {
                   1335:                 if (dc->tb_flags & DRTI_FLAG)
                   1336:                     do_rti(dc);
                   1337:                  if (dc->tb_flags & DRTB_FLAG)
                   1338:                     do_rtb(dc);
                   1339:                 if (dc->tb_flags & DRTE_FLAG)
                   1340:                     do_rte(dc);
                   1341:                 /* Clear the delay slot flag.  */
                   1342:                 dc->tb_flags &= ~D_FLAG;
                   1343:                 /* If it is a direct jump, try direct chaining.  */
                   1344:                 if (dc->jmp != JMP_DIRECT) {
                   1345:                     eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
                   1346:                     dc->is_jmp = DISAS_JUMP;
                   1347:                 }
                   1348:                 break;
                   1349:             }
                   1350:         }
                   1351:         if (env->singlestep_enabled)
                   1352:             break;
                   1353:     } while (!dc->is_jmp && !dc->cpustate_changed
                   1354:          && gen_opc_ptr < gen_opc_end
                   1355:                  && !singlestep
                   1356:          && (dc->pc < next_page_start)
                   1357:                  && num_insns < max_insns);
                   1358: 
                   1359:     npc = dc->pc;
                   1360:     if (dc->jmp == JMP_DIRECT) {
                   1361:         if (dc->tb_flags & D_FLAG) {
                   1362:             dc->is_jmp = DISAS_UPDATE;
                   1363:             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
                   1364:             sync_jmpstate(dc);
                   1365:         } else
                   1366:             npc = dc->jmp_pc;
                   1367:     }
                   1368: 
                   1369:     if (tb->cflags & CF_LAST_IO)
                   1370:         gen_io_end();
                   1371:     /* Force an update if the per-tb cpu state has changed.  */
                   1372:     if (dc->is_jmp == DISAS_NEXT
                   1373:         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
                   1374:         dc->is_jmp = DISAS_UPDATE;
                   1375:         tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
                   1376:     }
                   1377:     t_sync_flags(dc);
                   1378: 
                   1379:     if (unlikely(env->singlestep_enabled)) {
                   1380:         t_gen_raise_exception(dc, EXCP_DEBUG);
                   1381:         if (dc->is_jmp == DISAS_NEXT)
                   1382:             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
                   1383:     } else {
                   1384:         switch(dc->is_jmp) {
                   1385:             case DISAS_NEXT:
                   1386:                 gen_goto_tb(dc, 1, npc);
                   1387:                 break;
                   1388:             default:
                   1389:             case DISAS_JUMP:
                   1390:             case DISAS_UPDATE:
                   1391:                 /* indicate that the hash table must be used
                   1392:                    to find the next TB */
                   1393:                 tcg_gen_exit_tb(0);
                   1394:                 break;
                   1395:             case DISAS_TB_JUMP:
                   1396:                 /* nothing more to generate */
                   1397:                 break;
                   1398:         }
                   1399:     }
                   1400:     gen_icount_end(tb, num_insns);
                   1401:     *gen_opc_ptr = INDEX_op_end;
                   1402:     if (search_pc) {
                   1403:         j = gen_opc_ptr - gen_opc_buf;
                   1404:         lj++;
                   1405:         while (lj <= j)
                   1406:             gen_opc_instr_start[lj++] = 0;
                   1407:     } else {
                   1408:         tb->size = dc->pc - pc_start;
                   1409:                 tb->icount = num_insns;
                   1410:     }
                   1411: 
                   1412: #ifdef DEBUG_DISAS
                   1413: #if !SIM_COMPAT
                   1414:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   1415:         qemu_log("\n");
                   1416: #if DISAS_GNU
                   1417:         log_target_disas(pc_start, dc->pc - pc_start, 0);
                   1418: #endif
                   1419:         qemu_log("\nisize=%d osize=%zd\n",
                   1420:             dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
                   1421:     }
                   1422: #endif
                   1423: #endif
                   1424:     assert(!dc->abort_at_next_insn);
                   1425: }
                   1426: 
                   1427: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
                   1428: {
                   1429:     gen_intermediate_code_internal(env, tb, 0);
                   1430: }
                   1431: 
                   1432: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
                   1433: {
                   1434:     gen_intermediate_code_internal(env, tb, 1);
                   1435: }
                   1436: 
                   1437: void cpu_dump_state (CPUState *env, FILE *f,
                   1438:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   1439:                      int flags)
                   1440: {
                   1441:     int i;
                   1442: 
                   1443:     if (!env || !f)
                   1444:         return;
                   1445: 
                   1446:     cpu_fprintf(f, "IN: PC=%x %s\n",
                   1447:                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
                   1448:     cpu_fprintf(f, "rmsr=%x resr=%x debug[%x] imm=%x iflags=%x\n",
                   1449:              env->sregs[SR_MSR], env->sregs[SR_ESR],
                   1450:              env->debug, env->imm, env->iflags);
                   1451:     cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s)\n",
                   1452:              env->btaken, env->btarget,
                   1453:              (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
                   1454:              (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel");
                   1455:     for (i = 0; i < 32; i++) {
                   1456:         cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
                   1457:         if ((i + 1) % 4 == 0)
                   1458:             cpu_fprintf(f, "\n");
                   1459:         }
                   1460:     cpu_fprintf(f, "\n\n");
                   1461: }
                   1462: 
                   1463: CPUState *cpu_mb_init (const char *cpu_model)
                   1464: {
                   1465:     CPUState *env;
                   1466:     static int tcg_initialized = 0;
                   1467:     int i;
                   1468: 
                   1469:     env = qemu_mallocz(sizeof(CPUState));
                   1470: 
                   1471:     cpu_exec_init(env);
                   1472:     cpu_reset(env);
                   1473: 
                   1474: 
                   1475:     if (tcg_initialized)
                   1476:         return env;
                   1477: 
                   1478:     tcg_initialized = 1;
                   1479: 
                   1480:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
                   1481: 
                   1482:     env_debug = tcg_global_mem_new(TCG_AREG0, 
                   1483:                     offsetof(CPUState, debug),
                   1484:                     "debug0");
                   1485:     env_iflags = tcg_global_mem_new(TCG_AREG0, 
                   1486:                     offsetof(CPUState, iflags),
                   1487:                     "iflags");
                   1488:     env_imm = tcg_global_mem_new(TCG_AREG0, 
                   1489:                     offsetof(CPUState, imm),
                   1490:                     "imm");
                   1491:     env_btarget = tcg_global_mem_new(TCG_AREG0,
                   1492:                      offsetof(CPUState, btarget),
                   1493:                      "btarget");
                   1494:     env_btaken = tcg_global_mem_new(TCG_AREG0,
                   1495:                      offsetof(CPUState, btaken),
                   1496:                      "btaken");
                   1497:     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
                   1498:         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
                   1499:                           offsetof(CPUState, regs[i]),
                   1500:                           regnames[i]);
                   1501:     }
                   1502:     for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
                   1503:         cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
                   1504:                           offsetof(CPUState, sregs[i]),
                   1505:                           special_regnames[i]);
                   1506:     }
                   1507: #define GEN_HELPER 2
                   1508: #include "helper.h"
                   1509: 
                   1510:     return env;
                   1511: }
                   1512: 
                   1513: void cpu_reset (CPUState *env)
                   1514: {
                   1515:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                   1516:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                   1517:         log_cpu_state(env, 0);
                   1518:     }
                   1519: 
                   1520:     memset(env, 0, offsetof(CPUMBState, breakpoints));
                   1521:     tlb_flush(env, 1);
                   1522: 
1.1.1.2 ! root     1523:     env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
        !          1524:                        | PVR0_USE_BARREL_MASK \
        !          1525:                        | PVR0_USE_DIV_MASK \
        !          1526:                        | PVR0_USE_HW_MUL_MASK \
        !          1527:                        | PVR0_USE_EXC_MASK \
        !          1528:                        | PVR0_USE_ICACHE_MASK \
        !          1529:                        | PVR0_USE_DCACHE_MASK \
        !          1530:                        | PVR0_USE_MMU \
        !          1531:                        | (0xb << 8);
        !          1532:     env->pvr.regs[2] = PVR2_D_OPB_MASK \
        !          1533:                         | PVR2_D_LMB_MASK \
        !          1534:                         | PVR2_I_OPB_MASK \
        !          1535:                         | PVR2_I_LMB_MASK \
        !          1536:                         | PVR2_USE_MSR_INSTR \
        !          1537:                         | PVR2_USE_PCMP_INSTR \
        !          1538:                         | PVR2_USE_BARREL_MASK \
        !          1539:                         | PVR2_USE_DIV_MASK \
        !          1540:                         | PVR2_USE_HW_MUL_MASK \
        !          1541:                         | PVR2_USE_MUL64_MASK \
        !          1542:                         | 0;
        !          1543:     env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family.  */
        !          1544:     env->pvr.regs[11] = PVR11_USE_MMU | (16 << 17);
        !          1545: 
1.1       root     1546:     env->sregs[SR_MSR] = 0;
                   1547: #if defined(CONFIG_USER_ONLY)
                   1548:     /* start in user mode with interrupts enabled.  */
                   1549:     env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp.  */
                   1550: #else
                   1551:     mmu_init(&env->mmu);
1.1.1.2 ! root     1552:     env->mmu.c_mmu = 3;
        !          1553:     env->mmu.c_mmu_tlb_access = 3;
        !          1554:     env->mmu.c_mmu_zones = 16;
1.1       root     1555: #endif
                   1556: }
                   1557: 
                   1558: void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
                   1559:                  unsigned long searched_pc, int pc_pos, void *puc)
                   1560: {
                   1561:     env->sregs[SR_PC] = gen_opc_pc[pc_pos];
                   1562: }

unix.superglobalmegacorp.com

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