qemu/target/microblaze/translate.c
<<
>>
Prefs
   1/*
   2 *  Xilinx MicroBlaze emulation for qemu: main translation routines.
   3 *
   4 *  Copyright (c) 2009 Edgar E. Iglesias.
   5 *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "cpu.h"
  23#include "disas/disas.h"
  24#include "exec/exec-all.h"
  25#include "tcg-op.h"
  26#include "exec/helper-proto.h"
  27#include "microblaze-decode.h"
  28#include "exec/cpu_ldst.h"
  29#include "exec/helper-gen.h"
  30#include "exec/translator.h"
  31#include "qemu/qemu-print.h"
  32
  33#include "trace-tcg.h"
  34#include "exec/log.h"
  35
  36
  37#define SIM_COMPAT 0
  38#define DISAS_GNU 1
  39#define DISAS_MB 1
  40#if DISAS_MB && !SIM_COMPAT
  41#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
  42#else
  43#  define LOG_DIS(...) do { } while (0)
  44#endif
  45
  46#define D(x)
  47
  48#define EXTRACT_FIELD(src, start, end) \
  49            (((src) >> start) & ((1 << (end - start + 1)) - 1))
  50
  51/* is_jmp field values */
  52#define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
  53#define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
  54#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
  55
  56static TCGv_i32 env_debug;
  57static TCGv_i32 cpu_R[32];
  58static TCGv_i64 cpu_SR[14];
  59static TCGv_i32 env_imm;
  60static TCGv_i32 env_btaken;
  61static TCGv_i64 env_btarget;
  62static TCGv_i32 env_iflags;
  63static TCGv env_res_addr;
  64static TCGv_i32 env_res_val;
  65
  66#include "exec/gen-icount.h"
  67
  68/* This is the state at translation time.  */
  69typedef struct DisasContext {
  70    MicroBlazeCPU *cpu;
  71    uint32_t pc;
  72
  73    /* Decoder.  */
  74    int type_b;
  75    uint32_t ir;
  76    uint8_t opcode;
  77    uint8_t rd, ra, rb;
  78    uint16_t imm;
  79
  80    unsigned int cpustate_changed;
  81    unsigned int delayed_branch;
  82    unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
  83    unsigned int clear_imm;
  84    int is_jmp;
  85
  86#define JMP_NOJMP     0
  87#define JMP_DIRECT    1
  88#define JMP_DIRECT_CC 2
  89#define JMP_INDIRECT  3
  90    unsigned int jmp;
  91    uint32_t jmp_pc;
  92
  93    int abort_at_next_insn;
  94    struct TranslationBlock *tb;
  95    int singlestep_enabled;
  96} DisasContext;
  97
  98static const char *regnames[] =
  99{
 100    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
 101    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
 102    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
 103    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
 104};
 105
 106static const char *special_regnames[] =
 107{
 108    "rpc", "rmsr", "sr2", "rear", "sr4", "resr", "sr6", "rfsr",
 109    "sr8", "sr9", "sr10", "rbtr", "sr12", "redr"
 110};
 111
 112static inline void t_sync_flags(DisasContext *dc)
 113{
 114    /* Synch the tb dependent flags between translator and runtime.  */
 115    if (dc->tb_flags != dc->synced_flags) {
 116        tcg_gen_movi_i32(env_iflags, dc->tb_flags);
 117        dc->synced_flags = dc->tb_flags;
 118    }
 119}
 120
 121static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
 122{
 123    TCGv_i32 tmp = tcg_const_i32(index);
 124
 125    t_sync_flags(dc);
 126    tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
 127    gen_helper_raise_exception(cpu_env, tmp);
 128    tcg_temp_free_i32(tmp);
 129    dc->is_jmp = DISAS_UPDATE;
 130}
 131
 132static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
 133{
 134#ifndef CONFIG_USER_ONLY
 135    return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 136#else
 137    return true;
 138#endif
 139}
 140
 141static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 142{
 143    if (use_goto_tb(dc, dest)) {
 144        tcg_gen_goto_tb(n);
 145        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
 146        tcg_gen_exit_tb(dc->tb, n);
 147    } else {
 148        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
 149        tcg_gen_exit_tb(NULL, 0);
 150    }
 151}
 152
 153static void read_carry(DisasContext *dc, TCGv_i32 d)
 154{
 155    tcg_gen_extrl_i64_i32(d, cpu_SR[SR_MSR]);
 156    tcg_gen_shri_i32(d, d, 31);
 157}
 158
 159/*
 160 * write_carry sets the carry bits in MSR based on bit 0 of v.
 161 * v[31:1] are ignored.
 162 */
 163static void write_carry(DisasContext *dc, TCGv_i32 v)
 164{
 165    TCGv_i64 t0 = tcg_temp_new_i64();
 166    tcg_gen_extu_i32_i64(t0, v);
 167    /* Deposit bit 0 into MSR_C and the alias MSR_CC.  */
 168    tcg_gen_deposit_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0, 2, 1);
 169    tcg_gen_deposit_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0, 31, 1);
 170    tcg_temp_free_i64(t0);
 171}
 172
 173static void write_carryi(DisasContext *dc, bool carry)
 174{
 175    TCGv_i32 t0 = tcg_temp_new_i32();
 176    tcg_gen_movi_i32(t0, carry);
 177    write_carry(dc, t0);
 178    tcg_temp_free_i32(t0);
 179}
 180
 181/*
 182 * Returns true if the insn an illegal operation.
 183 * If exceptions are enabled, an exception is raised.
 184 */
 185static bool trap_illegal(DisasContext *dc, bool cond)
 186{
 187    if (cond && (dc->tb_flags & MSR_EE_FLAG)
 188        && (dc->cpu->env.pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
 189        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
 190        t_gen_raise_exception(dc, EXCP_HW_EXCP);
 191    }
 192    return cond;
 193}
 194
 195/*
 196 * Returns true if the insn is illegal in userspace.
 197 * If exceptions are enabled, an exception is raised.
 198 */
 199static bool trap_userspace(DisasContext *dc, bool cond)
 200{
 201    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
 202    bool cond_user = cond && mem_index == MMU_USER_IDX;
 203
 204    if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
 205        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
 206        t_gen_raise_exception(dc, EXCP_HW_EXCP);
 207    }
 208    return cond_user;
 209}
 210
 211/* True if ALU operand b is a small immediate that may deserve
 212   faster treatment.  */
 213static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
 214{
 215    /* Immediate insn without the imm prefix ?  */
 216    return dc->type_b && !(dc->tb_flags & IMM_FLAG);
 217}
 218
 219static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
 220{
 221    if (dc->type_b) {
 222        if (dc->tb_flags & IMM_FLAG)
 223            tcg_gen_ori_i32(env_imm, env_imm, dc->imm);
 224        else
 225            tcg_gen_movi_i32(env_imm, (int32_t)((int16_t)dc->imm));
 226        return &env_imm;
 227    } else
 228        return &cpu_R[dc->rb];
 229}
 230
 231static void dec_add(DisasContext *dc)
 232{
 233    unsigned int k, c;
 234    TCGv_i32 cf;
 235
 236    k = dc->opcode & 4;
 237    c = dc->opcode & 2;
 238
 239    LOG_DIS("add%s%s%s r%d r%d r%d\n",
 240            dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
 241            dc->rd, dc->ra, dc->rb);
 242
 243    /* Take care of the easy cases first.  */
 244    if (k) {
 245        /* k - keep carry, no need to update MSR.  */
 246        /* If rd == r0, it's a nop.  */
 247        if (dc->rd) {
 248            tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 249
 250            if (c) {
 251                /* c - Add carry into the result.  */
 252                cf = tcg_temp_new_i32();
 253
 254                read_carry(dc, cf);
 255                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
 256                tcg_temp_free_i32(cf);
 257            }
 258        }
 259        return;
 260    }
 261
 262    /* From now on, we can assume k is zero.  So we need to update MSR.  */
 263    /* Extract carry.  */
 264    cf = tcg_temp_new_i32();
 265    if (c) {
 266        read_carry(dc, cf);
 267    } else {
 268        tcg_gen_movi_i32(cf, 0);
 269    }
 270
 271    if (dc->rd) {
 272        TCGv_i32 ncf = tcg_temp_new_i32();
 273        gen_helper_carry(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
 274        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 275        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
 276        write_carry(dc, ncf);
 277        tcg_temp_free_i32(ncf);
 278    } else {
 279        gen_helper_carry(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
 280        write_carry(dc, cf);
 281    }
 282    tcg_temp_free_i32(cf);
 283}
 284
 285static void dec_sub(DisasContext *dc)
 286{
 287    unsigned int u, cmp, k, c;
 288    TCGv_i32 cf, na;
 289
 290    u = dc->imm & 2;
 291    k = dc->opcode & 4;
 292    c = dc->opcode & 2;
 293    cmp = (dc->imm & 1) && (!dc->type_b) && k;
 294
 295    if (cmp) {
 296        LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir);
 297        if (dc->rd) {
 298            if (u)
 299                gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
 300            else
 301                gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
 302        }
 303        return;
 304    }
 305
 306    LOG_DIS("sub%s%s r%d, r%d r%d\n",
 307             k ? "k" : "",  c ? "c" : "", dc->rd, dc->ra, dc->rb);
 308
 309    /* Take care of the easy cases first.  */
 310    if (k) {
 311        /* k - keep carry, no need to update MSR.  */
 312        /* If rd == r0, it's a nop.  */
 313        if (dc->rd) {
 314            tcg_gen_sub_i32(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
 315
 316            if (c) {
 317                /* c - Add carry into the result.  */
 318                cf = tcg_temp_new_i32();
 319
 320                read_carry(dc, cf);
 321                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
 322                tcg_temp_free_i32(cf);
 323            }
 324        }
 325        return;
 326    }
 327
 328    /* From now on, we can assume k is zero.  So we need to update MSR.  */
 329    /* Extract carry. And complement a into na.  */
 330    cf = tcg_temp_new_i32();
 331    na = tcg_temp_new_i32();
 332    if (c) {
 333        read_carry(dc, cf);
 334    } else {
 335        tcg_gen_movi_i32(cf, 1);
 336    }
 337
 338    /* d = b + ~a + c. carry defaults to 1.  */
 339    tcg_gen_not_i32(na, cpu_R[dc->ra]);
 340
 341    if (dc->rd) {
 342        TCGv_i32 ncf = tcg_temp_new_i32();
 343        gen_helper_carry(ncf, na, *(dec_alu_op_b(dc)), cf);
 344        tcg_gen_add_i32(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
 345        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
 346        write_carry(dc, ncf);
 347        tcg_temp_free_i32(ncf);
 348    } else {
 349        gen_helper_carry(cf, na, *(dec_alu_op_b(dc)), cf);
 350        write_carry(dc, cf);
 351    }
 352    tcg_temp_free_i32(cf);
 353    tcg_temp_free_i32(na);
 354}
 355
 356static void dec_pattern(DisasContext *dc)
 357{
 358    unsigned int mode;
 359
 360    if (trap_illegal(dc, !dc->cpu->cfg.use_pcmp_instr)) {
 361        return;
 362    }
 363
 364    mode = dc->opcode & 3;
 365    switch (mode) {
 366        case 0:
 367            /* pcmpbf.  */
 368            LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 369            if (dc->rd)
 370                gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
 371            break;
 372        case 2:
 373            LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 374            if (dc->rd) {
 375                tcg_gen_setcond_i32(TCG_COND_EQ, cpu_R[dc->rd],
 376                                   cpu_R[dc->ra], cpu_R[dc->rb]);
 377            }
 378            break;
 379        case 3:
 380            LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 381            if (dc->rd) {
 382                tcg_gen_setcond_i32(TCG_COND_NE, cpu_R[dc->rd],
 383                                   cpu_R[dc->ra], cpu_R[dc->rb]);
 384            }
 385            break;
 386        default:
 387            cpu_abort(CPU(dc->cpu),
 388                      "unsupported pattern insn opcode=%x\n", dc->opcode);
 389            break;
 390    }
 391}
 392
 393static void dec_and(DisasContext *dc)
 394{
 395    unsigned int not;
 396
 397    if (!dc->type_b && (dc->imm & (1 << 10))) {
 398        dec_pattern(dc);
 399        return;
 400    }
 401
 402    not = dc->opcode & (1 << 1);
 403    LOG_DIS("and%s\n", not ? "n" : "");
 404
 405    if (!dc->rd)
 406        return;
 407
 408    if (not) {
 409        tcg_gen_andc_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 410    } else
 411        tcg_gen_and_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 412}
 413
 414static void dec_or(DisasContext *dc)
 415{
 416    if (!dc->type_b && (dc->imm & (1 << 10))) {
 417        dec_pattern(dc);
 418        return;
 419    }
 420
 421    LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
 422    if (dc->rd)
 423        tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 424}
 425
 426static void dec_xor(DisasContext *dc)
 427{
 428    if (!dc->type_b && (dc->imm & (1 << 10))) {
 429        dec_pattern(dc);
 430        return;
 431    }
 432
 433    LOG_DIS("xor r%d\n", dc->rd);
 434    if (dc->rd)
 435        tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 436}
 437
 438static inline void msr_read(DisasContext *dc, TCGv_i32 d)
 439{
 440    tcg_gen_extrl_i64_i32(d, cpu_SR[SR_MSR]);
 441}
 442
 443static inline void msr_write(DisasContext *dc, TCGv_i32 v)
 444{
 445    TCGv_i64 t;
 446
 447    t = tcg_temp_new_i64();
 448    dc->cpustate_changed = 1;
 449    /* PVR bit is not writable.  */
 450    tcg_gen_extu_i32_i64(t, v);
 451    tcg_gen_andi_i64(t, t, ~MSR_PVR);
 452    tcg_gen_andi_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
 453    tcg_gen_or_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t);
 454    tcg_temp_free_i64(t);
 455}
 456
 457static void dec_msr(DisasContext *dc)
 458{
 459    CPUState *cs = CPU(dc->cpu);
 460    TCGv_i32 t0, t1;
 461    unsigned int sr, rn;
 462    bool to, clrset, extended = false;
 463
 464    sr = extract32(dc->imm, 0, 14);
 465    to = extract32(dc->imm, 14, 1);
 466    clrset = extract32(dc->imm, 15, 1) == 0;
 467    dc->type_b = 1;
 468    if (to) {
 469        dc->cpustate_changed = 1;
 470    }
 471
 472    /* Extended MSRs are only available if addr_size > 32.  */
 473    if (dc->cpu->cfg.addr_size > 32) {
 474        /* The E-bit is encoded differently for To/From MSR.  */
 475        static const unsigned int e_bit[] = { 19, 24 };
 476
 477        extended = extract32(dc->imm, e_bit[to], 1);
 478    }
 479
 480    /* msrclr and msrset.  */
 481    if (clrset) {
 482        bool clr = extract32(dc->ir, 16, 1);
 483
 484        LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
 485                dc->rd, dc->imm);
 486
 487        if (!dc->cpu->cfg.use_msr_instr) {
 488            /* nop??? */
 489            return;
 490        }
 491
 492        if (trap_userspace(dc, dc->imm != 4 && dc->imm != 0)) {
 493            return;
 494        }
 495
 496        if (dc->rd)
 497            msr_read(dc, cpu_R[dc->rd]);
 498
 499        t0 = tcg_temp_new_i32();
 500        t1 = tcg_temp_new_i32();
 501        msr_read(dc, t0);
 502        tcg_gen_mov_i32(t1, *(dec_alu_op_b(dc)));
 503
 504        if (clr) {
 505            tcg_gen_not_i32(t1, t1);
 506            tcg_gen_and_i32(t0, t0, t1);
 507        } else
 508            tcg_gen_or_i32(t0, t0, t1);
 509        msr_write(dc, t0);
 510        tcg_temp_free_i32(t0);
 511        tcg_temp_free_i32(t1);
 512        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc + 4);
 513        dc->is_jmp = DISAS_UPDATE;
 514        return;
 515    }
 516
 517    if (trap_userspace(dc, to)) {
 518        return;
 519    }
 520
 521#if !defined(CONFIG_USER_ONLY)
 522    /* Catch read/writes to the mmu block.  */
 523    if ((sr & ~0xff) == 0x1000) {
 524        TCGv_i32 tmp_ext = tcg_const_i32(extended);
 525        TCGv_i32 tmp_sr;
 526
 527        sr &= 7;
 528        tmp_sr = tcg_const_i32(sr);
 529        LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
 530        if (to) {
 531            gen_helper_mmu_write(cpu_env, tmp_ext, tmp_sr, cpu_R[dc->ra]);
 532        } else {
 533            gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tmp_ext, tmp_sr);
 534        }
 535        tcg_temp_free_i32(tmp_sr);
 536        tcg_temp_free_i32(tmp_ext);
 537        return;
 538    }
 539#endif
 540
 541    if (to) {
 542        LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
 543        switch (sr) {
 544            case 0:
 545                break;
 546            case 1:
 547                msr_write(dc, cpu_R[dc->ra]);
 548                break;
 549            case SR_EAR:
 550            case SR_ESR:
 551            case SR_FSR:
 552                tcg_gen_extu_i32_i64(cpu_SR[sr], cpu_R[dc->ra]);
 553                break;
 554            case 0x800:
 555                tcg_gen_st_i32(cpu_R[dc->ra],
 556                               cpu_env, offsetof(CPUMBState, slr));
 557                break;
 558            case 0x802:
 559                tcg_gen_st_i32(cpu_R[dc->ra],
 560                               cpu_env, offsetof(CPUMBState, shr));
 561                break;
 562            default:
 563                cpu_abort(CPU(dc->cpu), "unknown mts reg %x\n", sr);
 564                break;
 565        }
 566    } else {
 567        LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);
 568
 569        switch (sr) {
 570            case 0:
 571                tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
 572                break;
 573            case 1:
 574                msr_read(dc, cpu_R[dc->rd]);
 575                break;
 576            case SR_EAR:
 577                if (extended) {
 578                    tcg_gen_extrh_i64_i32(cpu_R[dc->rd], cpu_SR[sr]);
 579                    break;
 580                }
 581            case SR_ESR:
 582            case SR_FSR:
 583            case SR_BTR:
 584                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_SR[sr]);
 585                break;
 586            case 0x800:
 587                tcg_gen_ld_i32(cpu_R[dc->rd],
 588                               cpu_env, offsetof(CPUMBState, slr));
 589                break;
 590            case 0x802:
 591                tcg_gen_ld_i32(cpu_R[dc->rd],
 592                               cpu_env, offsetof(CPUMBState, shr));
 593                break;
 594            case 0x2000 ... 0x200c:
 595                rn = sr & 0xf;
 596                tcg_gen_ld_i32(cpu_R[dc->rd],
 597                              cpu_env, offsetof(CPUMBState, pvr.regs[rn]));
 598                break;
 599            default:
 600                cpu_abort(cs, "unknown mfs reg %x\n", sr);
 601                break;
 602        }
 603    }
 604
 605    if (dc->rd == 0) {
 606        tcg_gen_movi_i32(cpu_R[0], 0);
 607    }
 608}
 609
 610/* Multiplier unit.  */
 611static void dec_mul(DisasContext *dc)
 612{
 613    TCGv_i32 tmp;
 614    unsigned int subcode;
 615
 616    if (trap_illegal(dc, !dc->cpu->cfg.use_hw_mul)) {
 617        return;
 618    }
 619
 620    subcode = dc->imm & 3;
 621
 622    if (dc->type_b) {
 623        LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
 624        tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 625        return;
 626    }
 627
 628    /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
 629    if (subcode >= 1 && subcode <= 3 && dc->cpu->cfg.use_hw_mul < 2) {
 630        /* nop??? */
 631    }
 632
 633    tmp = tcg_temp_new_i32();
 634    switch (subcode) {
 635        case 0:
 636            LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 637            tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
 638            break;
 639        case 1:
 640            LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 641            tcg_gen_muls2_i32(tmp, cpu_R[dc->rd],
 642                              cpu_R[dc->ra], cpu_R[dc->rb]);
 643            break;
 644        case 2:
 645            LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 646            tcg_gen_mulsu2_i32(tmp, cpu_R[dc->rd],
 647                               cpu_R[dc->ra], cpu_R[dc->rb]);
 648            break;
 649        case 3:
 650            LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
 651            tcg_gen_mulu2_i32(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
 652            break;
 653        default:
 654            cpu_abort(CPU(dc->cpu), "unknown MUL insn %x\n", subcode);
 655            break;
 656    }
 657    tcg_temp_free_i32(tmp);
 658}
 659
 660/* Div unit.  */
 661static void dec_div(DisasContext *dc)
 662{
 663    unsigned int u;
 664
 665    u = dc->imm & 2; 
 666    LOG_DIS("div\n");
 667
 668    if (trap_illegal(dc, !dc->cpu->cfg.use_div)) {
 669        return;
 670    }
 671
 672    if (u)
 673        gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
 674                        cpu_R[dc->ra]);
 675    else
 676        gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
 677                        cpu_R[dc->ra]);
 678    if (!dc->rd)
 679        tcg_gen_movi_i32(cpu_R[dc->rd], 0);
 680}
 681
 682static void dec_barrel(DisasContext *dc)
 683{
 684    TCGv_i32 t0;
 685    unsigned int imm_w, imm_s;
 686    bool s, t, e = false, i = false;
 687
 688    if (trap_illegal(dc, !dc->cpu->cfg.use_barrel)) {
 689        return;
 690    }
 691
 692    if (dc->type_b) {
 693        /* Insert and extract are only available in immediate mode.  */
 694        i = extract32(dc->imm, 15, 1);
 695        e = extract32(dc->imm, 14, 1);
 696    }
 697    s = extract32(dc->imm, 10, 1);
 698    t = extract32(dc->imm, 9, 1);
 699    imm_w = extract32(dc->imm, 6, 5);
 700    imm_s = extract32(dc->imm, 0, 5);
 701
 702    LOG_DIS("bs%s%s%s r%d r%d r%d\n",
 703            e ? "e" : "",
 704            s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
 705
 706    if (e) {
 707        if (imm_w + imm_s > 32 || imm_w == 0) {
 708            /* These inputs have an undefined behavior.  */
 709            qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
 710                          imm_w, imm_s);
 711        } else {
 712            tcg_gen_extract_i32(cpu_R[dc->rd], cpu_R[dc->ra], imm_s, imm_w);
 713        }
 714    } else if (i) {
 715        int width = imm_w - imm_s + 1;
 716
 717        if (imm_w < imm_s) {
 718            /* These inputs have an undefined behavior.  */
 719            qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
 720                          imm_w, imm_s);
 721        } else {
 722            tcg_gen_deposit_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_R[dc->ra],
 723                                imm_s, width);
 724        }
 725    } else {
 726        t0 = tcg_temp_new_i32();
 727
 728        tcg_gen_mov_i32(t0, *(dec_alu_op_b(dc)));
 729        tcg_gen_andi_i32(t0, t0, 31);
 730
 731        if (s) {
 732            tcg_gen_shl_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
 733        } else {
 734            if (t) {
 735                tcg_gen_sar_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
 736            } else {
 737                tcg_gen_shr_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
 738            }
 739        }
 740        tcg_temp_free_i32(t0);
 741    }
 742}
 743
 744static void dec_bit(DisasContext *dc)
 745{
 746    CPUState *cs = CPU(dc->cpu);
 747    TCGv_i32 t0;
 748    unsigned int op;
 749
 750    op = dc->ir & ((1 << 9) - 1);
 751    switch (op) {
 752        case 0x21:
 753            /* src.  */
 754            t0 = tcg_temp_new_i32();
 755
 756            LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
 757            tcg_gen_extrl_i64_i32(t0, cpu_SR[SR_MSR]);
 758            tcg_gen_andi_i32(t0, t0, MSR_CC);
 759            write_carry(dc, cpu_R[dc->ra]);
 760            if (dc->rd) {
 761                tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
 762                tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->rd], t0);
 763            }
 764            tcg_temp_free_i32(t0);
 765            break;
 766
 767        case 0x1:
 768        case 0x41:
 769            /* srl.  */
 770            LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
 771
 772            /* Update carry. Note that write carry only looks at the LSB.  */
 773            write_carry(dc, cpu_R[dc->ra]);
 774            if (dc->rd) {
 775                if (op == 0x41)
 776                    tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
 777                else
 778                    tcg_gen_sari_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
 779            }
 780            break;
 781        case 0x60:
 782            LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
 783            tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
 784            break;
 785        case 0x61:
 786            LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
 787            tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
 788            break;
 789        case 0x64:
 790        case 0x66:
 791        case 0x74:
 792        case 0x76:
 793            /* wdc.  */
 794            LOG_DIS("wdc r%d\n", dc->ra);
 795            trap_userspace(dc, true);
 796            break;
 797        case 0x68:
 798            /* wic.  */
 799            LOG_DIS("wic r%d\n", dc->ra);
 800            trap_userspace(dc, true);
 801            break;
 802        case 0xe0:
 803            if (trap_illegal(dc, !dc->cpu->cfg.use_pcmp_instr)) {
 804                return;
 805            }
 806            if (dc->cpu->cfg.use_pcmp_instr) {
 807                tcg_gen_clzi_i32(cpu_R[dc->rd], cpu_R[dc->ra], 32);
 808            }
 809            break;
 810        case 0x1e0:
 811            /* swapb */
 812            LOG_DIS("swapb r%d r%d\n", dc->rd, dc->ra);
 813            tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
 814            break;
 815        case 0x1e2:
 816            /*swaph */
 817            LOG_DIS("swaph r%d r%d\n", dc->rd, dc->ra);
 818            tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16);
 819            break;
 820        default:
 821            cpu_abort(cs, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
 822                      dc->pc, op, dc->rd, dc->ra, dc->rb);
 823            break;
 824    }
 825}
 826
 827static inline void sync_jmpstate(DisasContext *dc)
 828{
 829    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
 830        if (dc->jmp == JMP_DIRECT) {
 831            tcg_gen_movi_i32(env_btaken, 1);
 832        }
 833        dc->jmp = JMP_INDIRECT;
 834        tcg_gen_movi_i64(env_btarget, dc->jmp_pc);
 835    }
 836}
 837
 838static void dec_imm(DisasContext *dc)
 839{
 840    LOG_DIS("imm %x\n", dc->imm << 16);
 841    tcg_gen_movi_i32(env_imm, (dc->imm << 16));
 842    dc->tb_flags |= IMM_FLAG;
 843    dc->clear_imm = 0;
 844}
 845
 846static inline void compute_ldst_addr(DisasContext *dc, bool ea, TCGv t)
 847{
 848    bool extimm = dc->tb_flags & IMM_FLAG;
 849    /* Should be set to true if r1 is used by loadstores.  */
 850    bool stackprot = false;
 851    TCGv_i32 t32;
 852
 853    /* All load/stores use ra.  */
 854    if (dc->ra == 1 && dc->cpu->cfg.stackprot) {
 855        stackprot = true;
 856    }
 857
 858    /* Treat the common cases first.  */
 859    if (!dc->type_b) {
 860        if (ea) {
 861            int addr_size = dc->cpu->cfg.addr_size;
 862
 863            if (addr_size == 32) {
 864                tcg_gen_extu_i32_tl(t, cpu_R[dc->rb]);
 865                return;
 866            }
 867
 868            tcg_gen_concat_i32_i64(t, cpu_R[dc->rb], cpu_R[dc->ra]);
 869            if (addr_size < 64) {
 870                /* Mask off out of range bits.  */
 871                tcg_gen_andi_i64(t, t, MAKE_64BIT_MASK(0, addr_size));
 872            }
 873            return;
 874        }
 875
 876        /* If any of the regs is r0, set t to the value of the other reg.  */
 877        if (dc->ra == 0) {
 878            tcg_gen_extu_i32_tl(t, cpu_R[dc->rb]);
 879            return;
 880        } else if (dc->rb == 0) {
 881            tcg_gen_extu_i32_tl(t, cpu_R[dc->ra]);
 882            return;
 883        }
 884
 885        if (dc->rb == 1 && dc->cpu->cfg.stackprot) {
 886            stackprot = true;
 887        }
 888
 889        t32 = tcg_temp_new_i32();
 890        tcg_gen_add_i32(t32, cpu_R[dc->ra], cpu_R[dc->rb]);
 891        tcg_gen_extu_i32_tl(t, t32);
 892        tcg_temp_free_i32(t32);
 893
 894        if (stackprot) {
 895            gen_helper_stackprot(cpu_env, t);
 896        }
 897        return;
 898    }
 899    /* Immediate.  */
 900    t32 = tcg_temp_new_i32();
 901    if (!extimm) {
 902        tcg_gen_addi_i32(t32, cpu_R[dc->ra], (int16_t)dc->imm);
 903    } else {
 904        tcg_gen_add_i32(t32, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 905    }
 906    tcg_gen_extu_i32_tl(t, t32);
 907    tcg_temp_free_i32(t32);
 908
 909    if (stackprot) {
 910        gen_helper_stackprot(cpu_env, t);
 911    }
 912    return;
 913}
 914
 915static void dec_load(DisasContext *dc)
 916{
 917    TCGv_i32 v;
 918    TCGv addr;
 919    unsigned int size;
 920    bool rev = false, ex = false, ea = false;
 921    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
 922    TCGMemOp mop;
 923
 924    mop = dc->opcode & 3;
 925    size = 1 << mop;
 926    if (!dc->type_b) {
 927        ea = extract32(dc->ir, 7, 1);
 928        rev = extract32(dc->ir, 9, 1);
 929        ex = extract32(dc->ir, 10, 1);
 930    }
 931    mop |= MO_TE;
 932    if (rev) {
 933        mop ^= MO_BSWAP;
 934    }
 935
 936    if (trap_illegal(dc, size > 4)) {
 937        return;
 938    }
 939
 940    if (trap_userspace(dc, ea)) {
 941        return;
 942    }
 943
 944    LOG_DIS("l%d%s%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
 945                                                        ex ? "x" : "",
 946                                                        ea ? "ea" : "");
 947
 948    t_sync_flags(dc);
 949    addr = tcg_temp_new();
 950    compute_ldst_addr(dc, ea, addr);
 951    /* Extended addressing bypasses the MMU.  */
 952    mem_index = ea ? MMU_NOMMU_IDX : mem_index;
 953
 954    /*
 955     * When doing reverse accesses we need to do two things.
 956     *
 957     * 1. Reverse the address wrt endianness.
 958     * 2. Byteswap the data lanes on the way back into the CPU core.
 959     */
 960    if (rev && size != 4) {
 961        /* Endian reverse the address. t is addr.  */
 962        switch (size) {
 963            case 1:
 964            {
 965                /* 00 -> 11
 966                   01 -> 10
 967                   10 -> 10
 968                   11 -> 00 */
 969                TCGv low = tcg_temp_new();
 970
 971                tcg_gen_andi_tl(low, addr, 3);
 972                tcg_gen_sub_tl(low, tcg_const_tl(3), low);
 973                tcg_gen_andi_tl(addr, addr, ~3);
 974                tcg_gen_or_tl(addr, addr, low);
 975                tcg_temp_free(low);
 976                break;
 977            }
 978
 979            case 2:
 980                /* 00 -> 10
 981                   10 -> 00.  */
 982                tcg_gen_xori_tl(addr, addr, 2);
 983                break;
 984            default:
 985                cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
 986                break;
 987        }
 988    }
 989
 990    /* lwx does not throw unaligned access errors, so force alignment */
 991    if (ex) {
 992        tcg_gen_andi_tl(addr, addr, ~3);
 993    }
 994
 995    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
 996    sync_jmpstate(dc);
 997
 998    /* Verify alignment if needed.  */
 999    /*
1000     * Microblaze gives MMU faults priority over faults due to
1001     * unaligned addresses. That's why we speculatively do the load
1002     * into v. If the load succeeds, we verify alignment of the
1003     * address and if that succeeds we write into the destination reg.
1004     */
1005    v = tcg_temp_new_i32();
1006    tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
1007
1008    if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
1009        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
1010        gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
1011                            tcg_const_i32(0), tcg_const_i32(size - 1));
1012    }
1013
1014    if (ex) {
1015        tcg_gen_mov_tl(env_res_addr, addr);
1016        tcg_gen_mov_i32(env_res_val, v);
1017    }
1018    if (dc->rd) {
1019        tcg_gen_mov_i32(cpu_R[dc->rd], v);
1020    }
1021    tcg_temp_free_i32(v);
1022
1023    if (ex) { /* lwx */
1024        /* no support for AXI exclusive so always clear C */
1025        write_carryi(dc, 0);
1026    }
1027
1028    tcg_temp_free(addr);
1029}
1030
1031static void dec_store(DisasContext *dc)
1032{
1033    TCGv addr;
1034    TCGLabel *swx_skip = NULL;
1035    unsigned int size;
1036    bool rev = false, ex = false, ea = false;
1037    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
1038    TCGMemOp mop;
1039
1040    mop = dc->opcode & 3;
1041    size = 1 << mop;
1042    if (!dc->type_b) {
1043        ea = extract32(dc->ir, 7, 1);
1044        rev = extract32(dc->ir, 9, 1);
1045        ex = extract32(dc->ir, 10, 1);
1046    }
1047    mop |= MO_TE;
1048    if (rev) {
1049        mop ^= MO_BSWAP;
1050    }
1051
1052    if (trap_illegal(dc, size > 4)) {
1053        return;
1054    }
1055
1056    trap_userspace(dc, ea);
1057
1058    LOG_DIS("s%d%s%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
1059                                                        ex ? "x" : "",
1060                                                        ea ? "ea" : "");
1061    t_sync_flags(dc);
1062    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
1063    sync_jmpstate(dc);
1064    /* SWX needs a temp_local.  */
1065    addr = ex ? tcg_temp_local_new() : tcg_temp_new();
1066    compute_ldst_addr(dc, ea, addr);
1067    /* Extended addressing bypasses the MMU.  */
1068    mem_index = ea ? MMU_NOMMU_IDX : mem_index;
1069
1070    if (ex) { /* swx */
1071        TCGv_i32 tval;
1072
1073        /* swx does not throw unaligned access errors, so force alignment */
1074        tcg_gen_andi_tl(addr, addr, ~3);
1075
1076        write_carryi(dc, 1);
1077        swx_skip = gen_new_label();
1078        tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, addr, swx_skip);
1079
1080        /* Compare the value loaded at lwx with current contents of
1081           the reserved location.
1082           FIXME: This only works for system emulation where we can expect
1083           this compare and the following write to be atomic. For user
1084           emulation we need to add atomicity between threads.  */
1085        tval = tcg_temp_new_i32();
1086        tcg_gen_qemu_ld_i32(tval, addr, cpu_mmu_index(&dc->cpu->env, false),
1087                            MO_TEUL);
1088        tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip);
1089        write_carryi(dc, 0);
1090        tcg_temp_free_i32(tval);
1091    }
1092
1093    if (rev && size != 4) {
1094        /* Endian reverse the address. t is addr.  */
1095        switch (size) {
1096            case 1:
1097            {
1098                /* 00 -> 11
1099                   01 -> 10
1100                   10 -> 10
1101                   11 -> 00 */
1102                TCGv low = tcg_temp_new();
1103
1104                tcg_gen_andi_tl(low, addr, 3);
1105                tcg_gen_sub_tl(low, tcg_const_tl(3), low);
1106                tcg_gen_andi_tl(addr, addr, ~3);
1107                tcg_gen_or_tl(addr, addr, low);
1108                tcg_temp_free(low);
1109                break;
1110            }
1111
1112            case 2:
1113                /* 00 -> 10
1114                   10 -> 00.  */
1115                /* Force addr into the temp.  */
1116                tcg_gen_xori_tl(addr, addr, 2);
1117                break;
1118            default:
1119                cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
1120                break;
1121        }
1122    }
1123    tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop);
1124
1125    /* Verify alignment if needed.  */
1126    if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
1127        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
1128        /* FIXME: if the alignment is wrong, we should restore the value
1129         *        in memory. One possible way to achieve this is to probe
1130         *        the MMU prior to the memaccess, thay way we could put
1131         *        the alignment checks in between the probe and the mem
1132         *        access.
1133         */
1134        gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
1135                            tcg_const_i32(1), tcg_const_i32(size - 1));
1136    }
1137
1138    if (ex) {
1139        gen_set_label(swx_skip);
1140    }
1141
1142    tcg_temp_free(addr);
1143}
1144
1145static inline void eval_cc(DisasContext *dc, unsigned int cc,
1146                           TCGv_i32 d, TCGv_i32 a)
1147{
1148    static const int mb_to_tcg_cc[] = {
1149        [CC_EQ] = TCG_COND_EQ,
1150        [CC_NE] = TCG_COND_NE,
1151        [CC_LT] = TCG_COND_LT,
1152        [CC_LE] = TCG_COND_LE,
1153        [CC_GE] = TCG_COND_GE,
1154        [CC_GT] = TCG_COND_GT,
1155    };
1156
1157    switch (cc) {
1158    case CC_EQ:
1159    case CC_NE:
1160    case CC_LT:
1161    case CC_LE:
1162    case CC_GE:
1163    case CC_GT:
1164        tcg_gen_setcondi_i32(mb_to_tcg_cc[cc], d, a, 0);
1165        break;
1166    default:
1167        cpu_abort(CPU(dc->cpu), "Unknown condition code %x.\n", cc);
1168        break;
1169    }
1170}
1171
1172static void eval_cond_jmp(DisasContext *dc, TCGv_i64 pc_true, TCGv_i64 pc_false)
1173{
1174    TCGv_i64 tmp_btaken = tcg_temp_new_i64();
1175    TCGv_i64 tmp_zero = tcg_const_i64(0);
1176
1177    tcg_gen_extu_i32_i64(tmp_btaken, env_btaken);
1178    tcg_gen_movcond_i64(TCG_COND_NE, cpu_SR[SR_PC],
1179                        tmp_btaken, tmp_zero,
1180                        pc_true, pc_false);
1181
1182    tcg_temp_free_i64(tmp_btaken);
1183    tcg_temp_free_i64(tmp_zero);
1184}
1185
1186static void dec_bcc(DisasContext *dc)
1187{
1188    unsigned int cc;
1189    unsigned int dslot;
1190
1191    cc = EXTRACT_FIELD(dc->ir, 21, 23);
1192    dslot = dc->ir & (1 << 25);
1193    LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);
1194
1195    dc->delayed_branch = 1;
1196    if (dslot) {
1197        dc->delayed_branch = 2;
1198        dc->tb_flags |= D_FLAG;
1199        tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1200                      cpu_env, offsetof(CPUMBState, bimm));
1201    }
1202
1203    if (dec_alu_op_b_is_small_imm(dc)) {
1204        int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
1205
1206        tcg_gen_movi_i64(env_btarget, dc->pc + offset);
1207        dc->jmp = JMP_DIRECT_CC;
1208        dc->jmp_pc = dc->pc + offset;
1209    } else {
1210        dc->jmp = JMP_INDIRECT;
1211        tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
1212        tcg_gen_addi_i64(env_btarget, env_btarget, dc->pc);
1213        tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
1214    }
1215    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra]);
1216}
1217
1218static void dec_br(DisasContext *dc)
1219{
1220    unsigned int dslot, link, abs, mbar;
1221
1222    dslot = dc->ir & (1 << 20);
1223    abs = dc->ir & (1 << 19);
1224    link = dc->ir & (1 << 18);
1225
1226    /* Memory barrier.  */
1227    mbar = (dc->ir >> 16) & 31;
1228    if (mbar == 2 && dc->imm == 4) {
1229        /* mbar IMM & 16 decodes to sleep.  */
1230        if (dc->rd & 16) {
1231            TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
1232            TCGv_i32 tmp_1 = tcg_const_i32(1);
1233
1234            LOG_DIS("sleep\n");
1235
1236            t_sync_flags(dc);
1237            tcg_gen_st_i32(tmp_1, cpu_env,
1238                           -offsetof(MicroBlazeCPU, env)
1239                           +offsetof(CPUState, halted));
1240            tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc + 4);
1241            gen_helper_raise_exception(cpu_env, tmp_hlt);
1242            tcg_temp_free_i32(tmp_hlt);
1243            tcg_temp_free_i32(tmp_1);
1244            return;
1245        }
1246        LOG_DIS("mbar %d\n", dc->rd);
1247        /* Break the TB.  */
1248        dc->cpustate_changed = 1;
1249        return;
1250    }
1251
1252    LOG_DIS("br%s%s%s%s imm=%x\n",
1253             abs ? "a" : "", link ? "l" : "",
1254             dc->type_b ? "i" : "", dslot ? "d" : "",
1255             dc->imm);
1256
1257    dc->delayed_branch = 1;
1258    if (dslot) {
1259        dc->delayed_branch = 2;
1260        dc->tb_flags |= D_FLAG;
1261        tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1262                      cpu_env, offsetof(CPUMBState, bimm));
1263    }
1264    if (link && dc->rd)
1265        tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
1266
1267    dc->jmp = JMP_INDIRECT;
1268    if (abs) {
1269        tcg_gen_movi_i32(env_btaken, 1);
1270        tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
1271        if (link && !dslot) {
1272            if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
1273                t_gen_raise_exception(dc, EXCP_BREAK);
1274            if (dc->imm == 0) {
1275                if (trap_userspace(dc, true)) {
1276                    return;
1277                }
1278
1279                t_gen_raise_exception(dc, EXCP_DEBUG);
1280            }
1281        }
1282    } else {
1283        if (dec_alu_op_b_is_small_imm(dc)) {
1284            dc->jmp = JMP_DIRECT;
1285            dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
1286        } else {
1287            tcg_gen_movi_i32(env_btaken, 1);
1288            tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
1289            tcg_gen_addi_i64(env_btarget, env_btarget, dc->pc);
1290            tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
1291        }
1292    }
1293}
1294
1295static inline void do_rti(DisasContext *dc)
1296{
1297    TCGv_i32 t0, t1;
1298    t0 = tcg_temp_new_i32();
1299    t1 = tcg_temp_new_i32();
1300    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
1301    tcg_gen_shri_i32(t0, t1, 1);
1302    tcg_gen_ori_i32(t1, t1, MSR_IE);
1303    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
1304
1305    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
1306    tcg_gen_or_i32(t1, t1, t0);
1307    msr_write(dc, t1);
1308    tcg_temp_free_i32(t1);
1309    tcg_temp_free_i32(t0);
1310    dc->tb_flags &= ~DRTI_FLAG;
1311}
1312
1313static inline void do_rtb(DisasContext *dc)
1314{
1315    TCGv_i32 t0, t1;
1316    t0 = tcg_temp_new_i32();
1317    t1 = tcg_temp_new_i32();
1318    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
1319    tcg_gen_andi_i32(t1, t1, ~MSR_BIP);
1320    tcg_gen_shri_i32(t0, t1, 1);
1321    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
1322
1323    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
1324    tcg_gen_or_i32(t1, t1, t0);
1325    msr_write(dc, t1);
1326    tcg_temp_free_i32(t1);
1327    tcg_temp_free_i32(t0);
1328    dc->tb_flags &= ~DRTB_FLAG;
1329}
1330
1331static inline void do_rte(DisasContext *dc)
1332{
1333    TCGv_i32 t0, t1;
1334    t0 = tcg_temp_new_i32();
1335    t1 = tcg_temp_new_i32();
1336
1337    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
1338    tcg_gen_ori_i32(t1, t1, MSR_EE);
1339    tcg_gen_andi_i32(t1, t1, ~MSR_EIP);
1340    tcg_gen_shri_i32(t0, t1, 1);
1341    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
1342
1343    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
1344    tcg_gen_or_i32(t1, t1, t0);
1345    msr_write(dc, t1);
1346    tcg_temp_free_i32(t1);
1347    tcg_temp_free_i32(t0);
1348    dc->tb_flags &= ~DRTE_FLAG;
1349}
1350
1351static void dec_rts(DisasContext *dc)
1352{
1353    unsigned int b_bit, i_bit, e_bit;
1354    TCGv_i64 tmp64;
1355
1356    i_bit = dc->ir & (1 << 21);
1357    b_bit = dc->ir & (1 << 22);
1358    e_bit = dc->ir & (1 << 23);
1359
1360    if (trap_userspace(dc, i_bit || b_bit || e_bit)) {
1361        return;
1362    }
1363
1364    dc->delayed_branch = 2;
1365    dc->tb_flags |= D_FLAG;
1366    tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
1367                  cpu_env, offsetof(CPUMBState, bimm));
1368
1369    if (i_bit) {
1370        LOG_DIS("rtid ir=%x\n", dc->ir);
1371        dc->tb_flags |= DRTI_FLAG;
1372    } else if (b_bit) {
1373        LOG_DIS("rtbd ir=%x\n", dc->ir);
1374        dc->tb_flags |= DRTB_FLAG;
1375    } else if (e_bit) {
1376        LOG_DIS("rted ir=%x\n", dc->ir);
1377        dc->tb_flags |= DRTE_FLAG;
1378    } else
1379        LOG_DIS("rts ir=%x\n", dc->ir);
1380
1381    dc->jmp = JMP_INDIRECT;
1382    tcg_gen_movi_i32(env_btaken, 1);
1383
1384    tmp64 = tcg_temp_new_i64();
1385    tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
1386    tcg_gen_extu_i32_i64(tmp64, cpu_R[dc->ra]);
1387    tcg_gen_add_i64(env_btarget, env_btarget, tmp64);
1388    tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
1389    tcg_temp_free_i64(tmp64);
1390}
1391
1392static int dec_check_fpuv2(DisasContext *dc)
1393{
1394    if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
1395        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_FPU);
1396        t_gen_raise_exception(dc, EXCP_HW_EXCP);
1397    }
1398    return (dc->cpu->cfg.use_fpu == 2) ? 0 : PVR2_USE_FPU2_MASK;
1399}
1400
1401static void dec_fpu(DisasContext *dc)
1402{
1403    unsigned int fpu_insn;
1404
1405    if (trap_illegal(dc, !dc->cpu->cfg.use_fpu)) {
1406        return;
1407    }
1408
1409    fpu_insn = (dc->ir >> 7) & 7;
1410
1411    switch (fpu_insn) {
1412        case 0:
1413            gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1414                            cpu_R[dc->rb]);
1415            break;
1416
1417        case 1:
1418            gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1419                             cpu_R[dc->rb]);
1420            break;
1421
1422        case 2:
1423            gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1424                            cpu_R[dc->rb]);
1425            break;
1426
1427        case 3:
1428            gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
1429                            cpu_R[dc->rb]);
1430            break;
1431
1432        case 4:
1433            switch ((dc->ir >> 4) & 7) {
1434                case 0:
1435                    gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
1436                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1437                    break;
1438                case 1:
1439                    gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
1440                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1441                    break;
1442                case 2:
1443                    gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
1444                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1445                    break;
1446                case 3:
1447                    gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
1448                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1449                    break;
1450                case 4:
1451                    gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
1452                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1453                    break;
1454                case 5:
1455                    gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
1456                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1457                    break;
1458                case 6:
1459                    gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
1460                                       cpu_R[dc->ra], cpu_R[dc->rb]);
1461                    break;
1462                default:
1463                    qemu_log_mask(LOG_UNIMP,
1464                                  "unimplemented fcmp fpu_insn=%x pc=%x"
1465                                  " opc=%x\n",
1466                                  fpu_insn, dc->pc, dc->opcode);
1467                    dc->abort_at_next_insn = 1;
1468                    break;
1469            }
1470            break;
1471
1472        case 5:
1473            if (!dec_check_fpuv2(dc)) {
1474                return;
1475            }
1476            gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1477            break;
1478
1479        case 6:
1480            if (!dec_check_fpuv2(dc)) {
1481                return;
1482            }
1483            gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1484            break;
1485
1486        case 7:
1487            if (!dec_check_fpuv2(dc)) {
1488                return;
1489            }
1490            gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
1491            break;
1492
1493        default:
1494            qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
1495                          " opc=%x\n",
1496                          fpu_insn, dc->pc, dc->opcode);
1497            dc->abort_at_next_insn = 1;
1498            break;
1499    }
1500}
1501
1502static void dec_null(DisasContext *dc)
1503{
1504    if (trap_illegal(dc, true)) {
1505        return;
1506    }
1507    qemu_log_mask(LOG_GUEST_ERROR, "unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
1508    dc->abort_at_next_insn = 1;
1509}
1510
1511/* Insns connected to FSL or AXI stream attached devices.  */
1512static void dec_stream(DisasContext *dc)
1513{
1514    TCGv_i32 t_id, t_ctrl;
1515    int ctrl;
1516
1517    LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
1518            dc->type_b ? "" : "d", dc->imm);
1519
1520    if (trap_userspace(dc, true)) {
1521        return;
1522    }
1523
1524    t_id = tcg_temp_new_i32();
1525    if (dc->type_b) {
1526        tcg_gen_movi_i32(t_id, dc->imm & 0xf);
1527        ctrl = dc->imm >> 10;
1528    } else {
1529        tcg_gen_andi_i32(t_id, cpu_R[dc->rb], 0xf);
1530        ctrl = dc->imm >> 5;
1531    }
1532
1533    t_ctrl = tcg_const_i32(ctrl);
1534
1535    if (dc->rd == 0) {
1536        gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
1537    } else {
1538        gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
1539    }
1540    tcg_temp_free_i32(t_id);
1541    tcg_temp_free_i32(t_ctrl);
1542}
1543
1544static struct decoder_info {
1545    struct {
1546        uint32_t bits;
1547        uint32_t mask;
1548    };
1549    void (*dec)(DisasContext *dc);
1550} decinfo[] = {
1551    {DEC_ADD, dec_add},
1552    {DEC_SUB, dec_sub},
1553    {DEC_AND, dec_and},
1554    {DEC_XOR, dec_xor},
1555    {DEC_OR, dec_or},
1556    {DEC_BIT, dec_bit},
1557    {DEC_BARREL, dec_barrel},
1558    {DEC_LD, dec_load},
1559    {DEC_ST, dec_store},
1560    {DEC_IMM, dec_imm},
1561    {DEC_BR, dec_br},
1562    {DEC_BCC, dec_bcc},
1563    {DEC_RTS, dec_rts},
1564    {DEC_FPU, dec_fpu},
1565    {DEC_MUL, dec_mul},
1566    {DEC_DIV, dec_div},
1567    {DEC_MSR, dec_msr},
1568    {DEC_STREAM, dec_stream},
1569    {{0, 0}, dec_null}
1570};
1571
1572static inline void decode(DisasContext *dc, uint32_t ir)
1573{
1574    int i;
1575
1576    dc->ir = ir;
1577    LOG_DIS("%8.8x\t", dc->ir);
1578
1579    if (ir == 0) {
1580        trap_illegal(dc, dc->cpu->env.pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK);
1581        /* Don't decode nop/zero instructions any further.  */
1582        return;
1583    }
1584
1585    /* bit 2 seems to indicate insn type.  */
1586    dc->type_b = ir & (1 << 29);
1587
1588    dc->opcode = EXTRACT_FIELD(ir, 26, 31);
1589    dc->rd = EXTRACT_FIELD(ir, 21, 25);
1590    dc->ra = EXTRACT_FIELD(ir, 16, 20);
1591    dc->rb = EXTRACT_FIELD(ir, 11, 15);
1592    dc->imm = EXTRACT_FIELD(ir, 0, 15);
1593
1594    /* Large switch for all insns.  */
1595    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
1596        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
1597            decinfo[i].dec(dc);
1598            break;
1599        }
1600    }
1601}
1602
1603/* generate intermediate code for basic block 'tb'.  */
1604void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
1605{
1606    CPUMBState *env = cs->env_ptr;
1607    MicroBlazeCPU *cpu = env_archcpu(env);
1608    uint32_t pc_start;
1609    struct DisasContext ctx;
1610    struct DisasContext *dc = &ctx;
1611    uint32_t page_start, org_flags;
1612    uint32_t npc;
1613    int num_insns;
1614
1615    pc_start = tb->pc;
1616    dc->cpu = cpu;
1617    dc->tb = tb;
1618    org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
1619
1620    dc->is_jmp = DISAS_NEXT;
1621    dc->jmp = 0;
1622    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
1623    if (dc->delayed_branch) {
1624        dc->jmp = JMP_INDIRECT;
1625    }
1626    dc->pc = pc_start;
1627    dc->singlestep_enabled = cs->singlestep_enabled;
1628    dc->cpustate_changed = 0;
1629    dc->abort_at_next_insn = 0;
1630
1631    if (pc_start & 3) {
1632        cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
1633    }
1634
1635    page_start = pc_start & TARGET_PAGE_MASK;
1636    num_insns = 0;
1637
1638    gen_tb_start(tb);
1639    do
1640    {
1641        tcg_gen_insn_start(dc->pc);
1642        num_insns++;
1643
1644#if SIM_COMPAT
1645        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1646            tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
1647            gen_helper_debug();
1648        }
1649#endif
1650
1651        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
1652            t_gen_raise_exception(dc, EXCP_DEBUG);
1653            dc->is_jmp = DISAS_UPDATE;
1654            /* The address covered by the breakpoint must be included in
1655               [tb->pc, tb->pc + tb->size) in order to for it to be
1656               properly cleared -- thus we increment the PC here so that
1657               the logic setting tb->size below does the right thing.  */
1658            dc->pc += 4;
1659            break;
1660        }
1661
1662        /* Pretty disas.  */
1663        LOG_DIS("%8.8x:\t", dc->pc);
1664
1665        if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
1666            gen_io_start();
1667        }
1668
1669        dc->clear_imm = 1;
1670        decode(dc, cpu_ldl_code(env, dc->pc));
1671        if (dc->clear_imm)
1672            dc->tb_flags &= ~IMM_FLAG;
1673        dc->pc += 4;
1674
1675        if (dc->delayed_branch) {
1676            dc->delayed_branch--;
1677            if (!dc->delayed_branch) {
1678                if (dc->tb_flags & DRTI_FLAG)
1679                    do_rti(dc);
1680                 if (dc->tb_flags & DRTB_FLAG)
1681                    do_rtb(dc);
1682                if (dc->tb_flags & DRTE_FLAG)
1683                    do_rte(dc);
1684                /* Clear the delay slot flag.  */
1685                dc->tb_flags &= ~D_FLAG;
1686                /* If it is a direct jump, try direct chaining.  */
1687                if (dc->jmp == JMP_INDIRECT) {
1688                    eval_cond_jmp(dc, env_btarget, tcg_const_i64(dc->pc));
1689                    dc->is_jmp = DISAS_JUMP;
1690                } else if (dc->jmp == JMP_DIRECT) {
1691                    t_sync_flags(dc);
1692                    gen_goto_tb(dc, 0, dc->jmp_pc);
1693                    dc->is_jmp = DISAS_TB_JUMP;
1694                } else if (dc->jmp == JMP_DIRECT_CC) {
1695                    TCGLabel *l1 = gen_new_label();
1696                    t_sync_flags(dc);
1697                    /* Conditional jmp.  */
1698                    tcg_gen_brcondi_i32(TCG_COND_NE, env_btaken, 0, l1);
1699                    gen_goto_tb(dc, 1, dc->pc);
1700                    gen_set_label(l1);
1701                    gen_goto_tb(dc, 0, dc->jmp_pc);
1702
1703                    dc->is_jmp = DISAS_TB_JUMP;
1704                }
1705                break;
1706            }
1707        }
1708        if (cs->singlestep_enabled) {
1709            break;
1710        }
1711    } while (!dc->is_jmp && !dc->cpustate_changed
1712             && !tcg_op_buf_full()
1713             && !singlestep
1714             && (dc->pc - page_start < TARGET_PAGE_SIZE)
1715             && num_insns < max_insns);
1716
1717    npc = dc->pc;
1718    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1719        if (dc->tb_flags & D_FLAG) {
1720            dc->is_jmp = DISAS_UPDATE;
1721            tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
1722            sync_jmpstate(dc);
1723        } else
1724            npc = dc->jmp_pc;
1725    }
1726
1727    if (tb_cflags(tb) & CF_LAST_IO)
1728        gen_io_end();
1729    /* Force an update if the per-tb cpu state has changed.  */
1730    if (dc->is_jmp == DISAS_NEXT
1731        && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
1732        dc->is_jmp = DISAS_UPDATE;
1733        tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
1734    }
1735    t_sync_flags(dc);
1736
1737    if (unlikely(cs->singlestep_enabled)) {
1738        TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
1739
1740        if (dc->is_jmp != DISAS_JUMP) {
1741            tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
1742        }
1743        gen_helper_raise_exception(cpu_env, tmp);
1744        tcg_temp_free_i32(tmp);
1745    } else {
1746        switch(dc->is_jmp) {
1747            case DISAS_NEXT:
1748                gen_goto_tb(dc, 1, npc);
1749                break;
1750            default:
1751            case DISAS_JUMP:
1752            case DISAS_UPDATE:
1753                /* indicate that the hash table must be used
1754                   to find the next TB */
1755                tcg_gen_exit_tb(NULL, 0);
1756                break;
1757            case DISAS_TB_JUMP:
1758                /* nothing more to generate */
1759                break;
1760        }
1761    }
1762    gen_tb_end(tb, num_insns);
1763
1764    tb->size = dc->pc - pc_start;
1765    tb->icount = num_insns;
1766
1767#ifdef DEBUG_DISAS
1768#if !SIM_COMPAT
1769    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1770        && qemu_log_in_addr_range(pc_start)) {
1771        qemu_log_lock();
1772        qemu_log("--------------\n");
1773        log_target_disas(cs, pc_start, dc->pc - pc_start);
1774        qemu_log_unlock();
1775    }
1776#endif
1777#endif
1778    assert(!dc->abort_at_next_insn);
1779}
1780
1781void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1782{
1783    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
1784    CPUMBState *env = &cpu->env;
1785    int i;
1786
1787    if (!env) {
1788        return;
1789    }
1790
1791    qemu_fprintf(f, "IN: PC=%" PRIx64 " %s\n",
1792                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
1793    qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
1794                 "debug=%x imm=%x iflags=%x fsr=%" PRIx64 "\n",
1795                 env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
1796                 env->debug, env->imm, env->iflags, env->sregs[SR_FSR]);
1797    qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
1798                 "eip=%d ie=%d\n",
1799                 env->btaken, env->btarget,
1800                 (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
1801                 (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
1802                 (bool)(env->sregs[SR_MSR] & MSR_EIP),
1803                 (bool)(env->sregs[SR_MSR] & MSR_IE));
1804
1805    for (i = 0; i < 32; i++) {
1806        qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
1807        if ((i + 1) % 4 == 0)
1808            qemu_fprintf(f, "\n");
1809        }
1810    qemu_fprintf(f, "\n\n");
1811}
1812
1813void mb_tcg_init(void)
1814{
1815    int i;
1816
1817    env_debug = tcg_global_mem_new_i32(cpu_env,
1818                    offsetof(CPUMBState, debug),
1819                    "debug0");
1820    env_iflags = tcg_global_mem_new_i32(cpu_env,
1821                    offsetof(CPUMBState, iflags),
1822                    "iflags");
1823    env_imm = tcg_global_mem_new_i32(cpu_env,
1824                    offsetof(CPUMBState, imm),
1825                    "imm");
1826    env_btarget = tcg_global_mem_new_i64(cpu_env,
1827                     offsetof(CPUMBState, btarget),
1828                     "btarget");
1829    env_btaken = tcg_global_mem_new_i32(cpu_env,
1830                     offsetof(CPUMBState, btaken),
1831                     "btaken");
1832    env_res_addr = tcg_global_mem_new(cpu_env,
1833                     offsetof(CPUMBState, res_addr),
1834                     "res_addr");
1835    env_res_val = tcg_global_mem_new_i32(cpu_env,
1836                     offsetof(CPUMBState, res_val),
1837                     "res_val");
1838    for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
1839        cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
1840                          offsetof(CPUMBState, regs[i]),
1841                          regnames[i]);
1842    }
1843    for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
1844        cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
1845                          offsetof(CPUMBState, sregs[i]),
1846                          special_regnames[i]);
1847    }
1848}
1849
1850void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
1851                          target_ulong *data)
1852{
1853    env->sregs[SR_PC] = data[0];
1854}
1855