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

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

unix.superglobalmegacorp.com

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