Hello, This patch contains the main changes. It contains modifcations to the target-i386/translate.c file. Those modifications are meant to generate TCG instructions to maintain the correct value for the variables fpop, fpip, fpdp, fpds and fpcs in the cpu state.
Best regards, Jaume translate.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 194 insertions(+), 8 deletions(-) signed-off: jaume.mar...@gmail.com diff --git a/target-i386/translate.c b/target-i386/translate.c index 6fcd824..8e490de 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -58,6 +58,9 @@ #endif //#define MACRO_TEST 1 +#define IS_PROTECTED_MODE(s) (s->pe && !s->vm86) +#define FP_EP_VALID 0x80000000 +#define FP_EP_INVALID 0 /* global register indexes */ static TCGv_ptr cpu_env; @@ -65,6 +68,11 @@ static TCGv cpu_A0; static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT; static TCGv_i32 cpu_cc_op; static TCGv cpu_regs[CPU_NB_REGS]; +static TCGv_i32 cpu_fpop; +static TCGv cpu_fpip; +static TCGv cpu_fpdp; +static TCGv_i32 cpu_fpds; +static TCGv_i32 cpu_fpcs; /* local temps */ static TCGv cpu_T[2]; /* local register indexes (only used inside old micro ops) */ @@ -74,6 +82,9 @@ static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32; static TCGv_i64 cpu_tmp1_i64; static uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; +static uint16_t gen_opc_fp_op[OPC_BUF_SIZE]; +static uint16_t gen_opc_fp_cs[OPC_BUF_SIZE]; +static target_ulong gen_opc_fp_ip[OPC_BUF_SIZE]; #include "exec/gen-icount.h" @@ -104,6 +115,10 @@ typedef struct DisasContext { int ss32; /* 32 bit stack segment */ CCOp cc_op; /* current CC operation */ bool cc_op_dirty; + uint16_t fp_op; + bool fp_ep_dirty; + target_ulong fp_ip; + uint16_t fp_cs; int addseg; /* non zero if either DS/ES/SS have a non zero base */ int f_st; /* currently unused */ int vm86; /* vm86 mode */ @@ -208,6 +223,62 @@ static const uint8_t cc_op_live[CC_OP_NB] = { [CC_OP_CLR] = 0, }; +static inline bool instr_is_x87_nc(int modrm, int b) +{ + int op, mod, rm; + switch (b) { + case 0xd8 ... 0xdf: + /* floats */ + op = ((b & 7) << 3) | ((modrm >> 3) & 7); + mod = (modrm >> 6) & 3; + rm = modrm & 7; + if (mod != 3) { + /* memory */ + switch (op) { + case 0x0c: /* fldenv */ + case 0x0d: /* fldcw */ + case 0x0e: /* fstenv, fnstenv */ + case 0x0f: /* fstcw, fnstcw */ + case 0x2c: /* frstor */ + case 0x2e: /* fsave, fnsave */ + case 0x2f: /* fstsw, fnstsw */ + return false; + default: + return true; + } + } else { + /* register */ + switch (op) { + case 0x0a: + return false; /* fnop, Illegal op */ + case 0x0e: /* fdecstp, fincstp */ + case 0x28: /* ffree */ + return false; + case 0x1c: + switch (rm) { + case 1: /* feni */ + return true; + case 2: /* fclex, fnclex */ + case 3: /* finit, fninit */ + return false; + case 4: /* fsetpm */ + return true; + default: /* Illegal op */ + return false; + } + case 0x3c: + return false; /* fstsw, fnstsw, Illegal op */ + default: + return true; + } + } + /*case 0x9b: // fwait, wait + return false;*/ + default: + return false; + } +} + static void set_cc_op(DisasContext *s, CCOp op) { int dead; @@ -253,6 +324,23 @@ static void gen_update_cc_op(DisasContext *s) } } +static void set_ep(DisasContext *s, int fp_op, int fp_ip, int fp_cs) { + s->fp_op = FP_EP_VALID | fp_op; + s->fp_ip = fp_ip; + s->fp_cs = fp_cs; + s->fp_ep_dirty = true; +} + +static void gen_update_ep(DisasContext *s) +{ + if (s->fp_ep_dirty) { + tcg_gen_movi_i32(cpu_fpop, s->fp_op); + tcg_gen_movi_tl(cpu_fpip, s->fp_ip); + tcg_gen_movi_i32(cpu_fpcs, s->fp_cs); + s->fp_ep_dirty = false; + } +} + #ifdef TARGET_X86_64 #define NB_OP_SIZES 4 @@ -666,6 +754,7 @@ static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip, state_saved = 0; if (s->pe && (s->cpl > s->iopl || s->vm86)) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); state_saved = 1; tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); @@ -686,6 +775,7 @@ static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip, if(s->flags & HF_SVMI_MASK) { if (!state_saved) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); } svm_flags |= (1 << (4 + ot)); @@ -1097,6 +1187,7 @@ static inline void gen_jcc1(DisasContext *s, int b, int l1) CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]); gen_update_cc_op(s); + gen_update_ep(s); if (cc.mask != -1) { tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask); cc.reg = cpu_T[0]; @@ -1580,14 +1671,14 @@ static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right) t0 = tcg_const_i32(0); t1 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t1, cpu_T[1]); - tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX); + tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX); tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS); tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0, cpu_tmp2_i32, cpu_tmp3_i32); tcg_temp_free_i32(t0); tcg_temp_free_i32(t1); - /* The CC_OP value is no longer predictable. */ + /* The CC_OP value is no longer predictable. */ set_cc_op(s, CC_OP_DYNAMIC); } @@ -1863,7 +1954,7 @@ static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c) } } -static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) +static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, int b) { target_long disp; int havesib; @@ -1871,6 +1962,7 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) int index; int scale; int mod, rm, code, override, must_add_seg; + int curr_instr_is_x87_nc; TCGv sum; override = s->override; @@ -1950,6 +2042,13 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) tcg_gen_addi_tl(cpu_A0, sum, disp); } + curr_instr_is_x87_nc = instr_is_x87_nc(modrm, b); + if (curr_instr_is_x87_nc) { + tcg_gen_mov_tl(cpu_fpdp, cpu_A0); + if (s->aflag == MO_32) { + tcg_gen_ext32u_tl(cpu_fpdp, cpu_fpdp); + } + } if (must_add_seg) { if (override < 0) { if (base == R_EBP || base == R_ESP) { @@ -1961,6 +2060,12 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[override].base)); + + if (curr_instr_is_x87_nc) { + tcg_gen_ld_i32(cpu_fpds, cpu_env, + offsetof(CPUX86State, segs[override].selector)); + } + if (CODE64(s)) { if (s->aflag == MO_32) { tcg_gen_ext32u_tl(cpu_A0, cpu_A0); @@ -1970,6 +2075,11 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) } tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); + } else { + if (curr_instr_is_x87_nc) { + tcg_gen_ld_i32(cpu_fpds, cpu_env, + offsetof(CPUX86State, segs[R_DS].selector)); + } } if (s->aflag == MO_32) { @@ -2039,8 +2149,22 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) override = R_DS; } } + if (instr_is_x87_nc(modrm, b)) { + tcg_gen_mov_tl(cpu_fpdp, cpu_A0); + tcg_gen_ld_i32(cpu_fpds, cpu_env, + offsetof(CPUX86State, segs[override].selector)); + } gen_op_addl_A0_seg(s, override); + } else { + if (instr_is_x87_nc(modrm, b)) { + tcg_gen_mov_tl(cpu_fpdp, cpu_A0); + tcg_gen_ld_i32(cpu_fpds, cpu_env, + offsetof(CPUX86State, segs[R_DS].selector)); + } } +#ifdef TARGET_X86_64 + tcg_gen_andi_tl(cpu_fpdp, cpu_fpdp, 0xffffffff); +#endif break; default: @@ -2130,7 +2254,7 @@ static void gen_add_A0_ds_seg(DisasContext *s) /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == OR_TMP0 */ static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, - TCGMemOp ot, int reg, int is_store) + TCGMemOp ot, int reg, int is_store, int b) { int mod, rm; @@ -2297,6 +2421,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) if (s->pe && !s->vm86) { /* XXX: optimize by finding processor state dynamically */ gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32); @@ -2326,6 +2451,7 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start, if (likely(!(s->flags & HF_SVMI_MASK))) return; gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type), tcg_const_i64(param)); @@ -2513,6 +2639,7 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno)); s->is_jmp = DISAS_TB_JUMP; @@ -2524,6 +2651,7 @@ static void gen_interrupt(DisasContext *s, int intno, target_ulong cur_eip, target_ulong next_eip) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno), tcg_const_i32(next_eip - cur_eip)); @@ -2533,6 +2661,7 @@ static void gen_interrupt(DisasContext *s, int intno, static void gen_debug(DisasContext *s, target_ulong cur_eip) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(cur_eip); gen_helper_debug(cpu_env); s->is_jmp = DISAS_TB_JUMP; @@ -2543,6 +2672,7 @@ static void gen_debug(DisasContext *s, target_ulong cur_eip) static void gen_eob(DisasContext *s) { gen_update_cc_op(s); + gen_update_ep(s); if (s->tb->flags & HF_INHIBIT_IRQ_MASK) { gen_helper_reset_inhibit_irq(cpu_env); } @@ -2564,6 +2694,7 @@ static void gen_eob(DisasContext *s) static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num) { gen_update_cc_op(s); + gen_update_ep(s); set_cc_op(s, CC_OP_DYNAMIC); if (s->jmp_opt) { gen_goto_tb(s, tb_num, eip); @@ -4404,6 +4535,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, int modrm, reg, rm, mod, op, opreg, val; target_ulong next_eip, tval; int rex_w, rex_r; + int fp_op, fp_ip, fp_cs; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(pc_start); @@ -4946,6 +5078,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, do_lcall: if (s->pe && !s->vm86) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1], @@ -4973,6 +5106,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, do_ljmp: if (s->pe && !s->vm86) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1], @@ -5832,7 +5966,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x0c: /* fldenv mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); + gen_helper_fldenv(cpu_env, cpu_A0, + tcg_const_i32(dflag == MO_32), + tcg_const_i32(IS_PROTECTED_MODE(s))); break; case 0x0d: /* fldcw mem */ tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, @@ -5841,8 +5977,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0x0e: /* fnstenv mem */ gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); + gen_helper_fstenv(cpu_env, cpu_A0, + tcg_const_i32(dflag == MO_32), + tcg_const_i32(IS_PROTECTED_MODE(s))); break; case 0x0f: /* fnstcw mem */ gen_helper_fnstcw(cpu_tmp2_i32, cpu_env); @@ -5863,12 +6002,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x2c: /* frstor mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); + gen_helper_frstor(cpu_env, cpu_A0, + tcg_const_i32(dflag == MO_32), + tcg_const_i32(IS_PROTECTED_MODE(s))); break; case 0x2e: /* fnsave mem */ gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); + gen_helper_fsave(cpu_env, cpu_A0, + tcg_const_i32(dflag == MO_32), + tcg_const_i32(IS_PROTECTED_MODE(s))); break; case 0x2f: /* fnstsw mem */ gen_helper_fnstsw(cpu_tmp2_i32, cpu_env); @@ -6209,6 +6353,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; } } + if (instr_is_x87_nc(modrm, b)) { + fp_op = ((b & 0x7) << 8) | (modrm & 0xff); + fp_ip = pc_start - s->cs_base; + fp_cs = env->segs[R_CS].selector; + set_ep(s, fp_op, fp_ip, fp_cs); + } break; /************************/ /* string ops */ @@ -6393,6 +6543,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, do_lret: if (s->pe && !s->vm86) { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1), tcg_const_i32(val)); @@ -6430,6 +6581,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } } else { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1), tcg_const_i32(s->pc - s->cs_base)); @@ -6884,6 +7036,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); } else { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_fwait(cpu_env); } @@ -6903,6 +7056,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) goto illegal_op; gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start)); break; @@ -7095,6 +7249,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1)); gen_eob(s); @@ -7104,6 +7259,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x105: /* syscall */ /* XXX: is it usable in real mode ? */ gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start)); gen_eob(s); @@ -7113,6 +7269,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1)); /* condition codes are modified only in long mode */ @@ -7133,6 +7290,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start)); s->is_jmp = DISAS_TB_JUMP; @@ -7241,6 +7399,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, s->cpl != 0) goto illegal_op; gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start)); gen_eob(s); @@ -7446,6 +7606,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) goto illegal_op; gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); if (use_icount) gen_io_start(); @@ -7624,6 +7785,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 4: case 8: gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(pc_start - s->cs_base); if (b & 2) { gen_op_mov_v_reg(ot, cpu_T[0], rm); @@ -7704,6 +7866,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, op = (modrm >> 3) & 7; switch(op) { case 0: /* fxsave */ + gen_update_ep(s); if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || (s->prefix & PREFIX_LOCK)) goto illegal_op; @@ -7783,6 +7951,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (!(s->flags & HF_SMM_MASK)) goto illegal_op; gen_update_cc_op(s); + gen_update_ep(s); gen_jmp_im(s->pc - s->cs_base); gen_helper_rsm(cpu_env); gen_eob(s); @@ -7880,6 +8049,17 @@ void optimize_flags_init(void) cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2), "cc_src2"); + cpu_fpop = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUX86State, fpop), "fpop"); + cpu_fpip = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, fpip), + "fpip"); + cpu_fpdp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, fpdp), + "fpdp"); + cpu_fpds = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUX86State, fpds), + "fpds"); + cpu_fpcs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUX86State, fpcs), + "fpcs"); + for (i = 0; i < CPU_NB_REGS; ++i) { cpu_regs[i] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, regs[i]), @@ -7924,6 +8104,8 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, dc->singlestep_enabled = cs->singlestep_enabled; dc->cc_op = CC_OP_DYNAMIC; dc->cc_op_dirty = false; + dc->fp_op = FP_EP_INVALID; + dc->fp_ep_dirty = false; dc->cs_base = cs_base; dc->tb = tb; dc->popl_esp_hack = 0; @@ -7997,6 +8179,9 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, } tcg_ctx.gen_opc_pc[lj] = pc_ptr; gen_opc_cc_op[lj] = dc->cc_op; + gen_opc_fp_op[lj] = dc->fp_op; + gen_opc_fp_ip[lj] = dc->fp_ip; + gen_opc_fp_cs[lj] = dc->fp_cs; tcg_ctx.gen_opc_instr_start[lj] = 1; tcg_ctx.gen_opc_icount[lj] = num_insns; } @@ -8080,6 +8265,7 @@ void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb) void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos) { int cc_op; + uint16_t fp_op; #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OP)) { int i; @@ -8099,4 +8285,10 @@ void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos) cc_op = gen_opc_cc_op[pc_pos]; if (cc_op != CC_OP_DYNAMIC) env->cc_op = cc_op; + fp_op = gen_opc_fp_op[pc_pos]; + if (fp_op & FP_EP_VALID) { + tcg_gen_movi_i32(cpu_fpop, fp_op); + tcg_gen_movi_tl(cpu_fpip, gen_opc_fp_ip[pc_pos]); + tcg_gen_movi_i32(cpu_fpcs, gen_opc_fp_cs[pc_pos]); + } }