1139c1837SPaolo Bonzini/* 2139c1837SPaolo Bonzini * translate-fp.c 3139c1837SPaolo Bonzini * 4139c1837SPaolo Bonzini * Standard FPU translation 5139c1837SPaolo Bonzini */ 6139c1837SPaolo Bonzini 7139c1837SPaolo Bonzinistatic inline void gen_reset_fpstatus(void) 8139c1837SPaolo Bonzini{ 9ad75a51eSRichard Henderson gen_helper_reset_fpstatus(tcg_env); 10139c1837SPaolo Bonzini} 11139c1837SPaolo Bonzini 12139c1837SPaolo Bonzinistatic inline void gen_compute_fprf_float64(TCGv_i64 arg) 13139c1837SPaolo Bonzini{ 14ad75a51eSRichard Henderson gen_helper_compute_fprf_float64(tcg_env, arg); 15ad75a51eSRichard Henderson gen_helper_float_check_status(tcg_env); 16139c1837SPaolo Bonzini} 17139c1837SPaolo Bonzini 18139c1837SPaolo Bonzini#if defined(TARGET_PPC64) 19139c1837SPaolo Bonzinistatic void gen_set_cr1_from_fpscr(DisasContext *ctx) 20139c1837SPaolo Bonzini{ 21139c1837SPaolo Bonzini TCGv_i32 tmp = tcg_temp_new_i32(); 22139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(tmp, cpu_fpscr); 23139c1837SPaolo Bonzini tcg_gen_shri_i32(cpu_crf[1], tmp, 28); 24139c1837SPaolo Bonzini} 25139c1837SPaolo Bonzini#else 26139c1837SPaolo Bonzinistatic void gen_set_cr1_from_fpscr(DisasContext *ctx) 27139c1837SPaolo Bonzini{ 28139c1837SPaolo Bonzini tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28); 29139c1837SPaolo Bonzini} 30139c1837SPaolo Bonzini#endif 31139c1837SPaolo Bonzini 32139c1837SPaolo Bonzini/*** Floating-Point arithmetic ***/ 33*177fcc06SChinmay Rathstatic bool do_helper_acb(DisasContext *ctx, arg_A *a, 34*177fcc06SChinmay Rath void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64, 35*177fcc06SChinmay Rath TCGv_i64, TCGv_i64)) 36*177fcc06SChinmay Rath{ 37*177fcc06SChinmay Rath TCGv_i64 t0, t1, t2, t3; 38*177fcc06SChinmay Rath REQUIRE_INSNS_FLAGS(ctx, FLOAT); 39*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 40*177fcc06SChinmay Rath t0 = tcg_temp_new_i64(); 41*177fcc06SChinmay Rath t1 = tcg_temp_new_i64(); 42*177fcc06SChinmay Rath t2 = tcg_temp_new_i64(); 43*177fcc06SChinmay Rath t3 = tcg_temp_new_i64(); 44*177fcc06SChinmay Rath gen_reset_fpstatus(); 45*177fcc06SChinmay Rath get_fpr(t0, a->fra); 46*177fcc06SChinmay Rath get_fpr(t1, a->frc); 47*177fcc06SChinmay Rath get_fpr(t2, a->frb); 48*177fcc06SChinmay Rath helper(t3, tcg_env, t0, t1, t2); 49*177fcc06SChinmay Rath set_fpr(a->frt, t3); 50*177fcc06SChinmay Rath gen_compute_fprf_float64(t3); 51*177fcc06SChinmay Rath if (unlikely(a->rc)) { 52*177fcc06SChinmay Rath gen_set_cr1_from_fpscr(ctx); 53*177fcc06SChinmay Rath } 54*177fcc06SChinmay Rath return true; 55139c1837SPaolo Bonzini} 56139c1837SPaolo Bonzini 57*177fcc06SChinmay Rathstatic bool do_helper_ab(DisasContext *ctx, arg_A_tab *a, 58*177fcc06SChinmay Rath void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64, 59*177fcc06SChinmay Rath TCGv_i64)) 60*177fcc06SChinmay Rath{ 61*177fcc06SChinmay Rath TCGv_i64 t0, t1, t2; 62*177fcc06SChinmay Rath REQUIRE_INSNS_FLAGS(ctx, FLOAT); 63*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 64*177fcc06SChinmay Rath t0 = tcg_temp_new_i64(); 65*177fcc06SChinmay Rath t1 = tcg_temp_new_i64(); 66*177fcc06SChinmay Rath t2 = tcg_temp_new_i64(); 67*177fcc06SChinmay Rath gen_reset_fpstatus(); 68*177fcc06SChinmay Rath get_fpr(t0, a->fra); 69*177fcc06SChinmay Rath get_fpr(t1, a->frb); 70*177fcc06SChinmay Rath helper(t2, tcg_env, t0, t1); 71*177fcc06SChinmay Rath set_fpr(a->frt, t2); 72*177fcc06SChinmay Rath gen_compute_fprf_float64(t2); 73*177fcc06SChinmay Rath if (unlikely(a->rc)) { 74*177fcc06SChinmay Rath gen_set_cr1_from_fpscr(ctx); 75139c1837SPaolo Bonzini } 76*177fcc06SChinmay Rath return true; 77139c1837SPaolo Bonzini} 78*177fcc06SChinmay Rath 79*177fcc06SChinmay Rathstatic bool do_helper_ac(DisasContext *ctx, arg_A_tac *a, 80*177fcc06SChinmay Rath void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64, 81*177fcc06SChinmay Rath TCGv_i64)) 82*177fcc06SChinmay Rath{ 83*177fcc06SChinmay Rath TCGv_i64 t0, t1, t2; 84*177fcc06SChinmay Rath REQUIRE_INSNS_FLAGS(ctx, FLOAT); 85*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 86*177fcc06SChinmay Rath t0 = tcg_temp_new_i64(); 87*177fcc06SChinmay Rath t1 = tcg_temp_new_i64(); 88*177fcc06SChinmay Rath t2 = tcg_temp_new_i64(); 89*177fcc06SChinmay Rath gen_reset_fpstatus(); 90*177fcc06SChinmay Rath get_fpr(t0, a->fra); 91*177fcc06SChinmay Rath get_fpr(t1, a->frc); 92*177fcc06SChinmay Rath helper(t2, tcg_env, t0, t1); 93*177fcc06SChinmay Rath set_fpr(a->frt, t2); 94*177fcc06SChinmay Rath gen_compute_fprf_float64(t2); 95*177fcc06SChinmay Rath if (unlikely(a->rc)) { 96*177fcc06SChinmay Rath gen_set_cr1_from_fpscr(ctx); 97*177fcc06SChinmay Rath } 98*177fcc06SChinmay Rath return true; 99*177fcc06SChinmay Rath} 100139c1837SPaolo Bonzini 101139c1837SPaolo Bonzini#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \ 102139c1837SPaolo Bonzinistatic void gen_f##name(DisasContext *ctx) \ 103139c1837SPaolo Bonzini{ \ 104139c1837SPaolo Bonzini TCGv_i64 t0; \ 105139c1837SPaolo Bonzini TCGv_i64 t1; \ 106139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { \ 107139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); \ 108139c1837SPaolo Bonzini return; \ 109139c1837SPaolo Bonzini } \ 110139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); \ 111139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); \ 112139c1837SPaolo Bonzini gen_reset_fpstatus(); \ 113139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); \ 114ad75a51eSRichard Henderson gen_helper_f##name(t1, tcg_env, t0); \ 115139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); \ 116139c1837SPaolo Bonzini if (set_fprf) { \ 117ad75a51eSRichard Henderson gen_helper_compute_fprf_float64(tcg_env, t1); \ 118139c1837SPaolo Bonzini } \ 119ad75a51eSRichard Henderson gen_helper_float_check_status(tcg_env); \ 120139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode) != 0)) { \ 121139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); \ 122139c1837SPaolo Bonzini } \ 123139c1837SPaolo Bonzini} 124139c1837SPaolo Bonzini 125*177fcc06SChinmay Rathstatic bool do_helper_bs(DisasContext *ctx, arg_A_tb *a, 126*177fcc06SChinmay Rath void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64)) 127139c1837SPaolo Bonzini{ 128*177fcc06SChinmay Rath TCGv_i64 t0, t1; 129*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 130139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 131139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 132139c1837SPaolo Bonzini gen_reset_fpstatus(); 133*177fcc06SChinmay Rath get_fpr(t0, a->frb); 134*177fcc06SChinmay Rath helper(t1, tcg_env, t0); 135*177fcc06SChinmay Rath set_fpr(a->frt, t1); 136139c1837SPaolo Bonzini gen_compute_fprf_float64(t1); 137*177fcc06SChinmay Rath if (unlikely(a->rc)) { 138139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 139139c1837SPaolo Bonzini } 140*177fcc06SChinmay Rath return true; 141139c1837SPaolo Bonzini} 142139c1837SPaolo Bonzini 143eb69a84bSMatheus Ferststatic bool trans_FSEL(DisasContext *ctx, arg_A *a) 144eb69a84bSMatheus Ferst{ 145eb69a84bSMatheus Ferst TCGv_i64 t0, t1, t2; 146eb69a84bSMatheus Ferst 147eb69a84bSMatheus Ferst REQUIRE_INSNS_FLAGS(ctx, FLOAT_FSEL); 148eb69a84bSMatheus Ferst REQUIRE_FPU(ctx); 149eb69a84bSMatheus Ferst 150eb69a84bSMatheus Ferst t0 = tcg_temp_new_i64(); 151eb69a84bSMatheus Ferst t1 = tcg_temp_new_i64(); 152eb69a84bSMatheus Ferst t2 = tcg_temp_new_i64(); 153eb69a84bSMatheus Ferst 154eb69a84bSMatheus Ferst get_fpr(t0, a->fra); 155eb69a84bSMatheus Ferst get_fpr(t1, a->frb); 156eb69a84bSMatheus Ferst get_fpr(t2, a->frc); 157eb69a84bSMatheus Ferst 158eb69a84bSMatheus Ferst gen_helper_FSEL(t0, t0, t1, t2); 159eb69a84bSMatheus Ferst set_fpr(a->frt, t0); 160eb69a84bSMatheus Ferst if (a->rc) { 161eb69a84bSMatheus Ferst gen_set_cr1_from_fpscr(ctx); 162eb69a84bSMatheus Ferst } 163eb69a84bSMatheus Ferst return true; 164eb69a84bSMatheus Ferst} 165eb69a84bSMatheus Ferst 1666a8654d6SVíctor Colombostatic bool do_helper_fsqrt(DisasContext *ctx, arg_A_tb *a, 1676a8654d6SVíctor Colombo void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64)) 168139c1837SPaolo Bonzini{ 1696a8654d6SVíctor Colombo TCGv_i64 t0, t1; 1706a8654d6SVíctor Colombo 1716a8654d6SVíctor Colombo REQUIRE_INSNS_FLAGS(ctx, FLOAT_FSQRT); 1726a8654d6SVíctor Colombo REQUIRE_FPU(ctx); 1736a8654d6SVíctor Colombo 174139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 175139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 1766a8654d6SVíctor Colombo 177139c1837SPaolo Bonzini gen_reset_fpstatus(); 1786a8654d6SVíctor Colombo get_fpr(t0, a->frb); 179ad75a51eSRichard Henderson helper(t1, tcg_env, t0); 1806a8654d6SVíctor Colombo set_fpr(a->frt, t1); 181139c1837SPaolo Bonzini gen_compute_fprf_float64(t1); 1826a8654d6SVíctor Colombo if (unlikely(a->rc != 0)) { 183139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 184139c1837SPaolo Bonzini } 1856a8654d6SVíctor Colombo return true; 186139c1837SPaolo Bonzini} 187139c1837SPaolo Bonzini 188*177fcc06SChinmay RathTRANS(FADD, do_helper_ab, gen_helper_FADD); 189*177fcc06SChinmay RathTRANS(FADDS, do_helper_ab, gen_helper_FADDS); 190*177fcc06SChinmay RathTRANS(FSUB, do_helper_ab, gen_helper_FSUB); 191*177fcc06SChinmay RathTRANS(FSUBS, do_helper_ab, gen_helper_FSUBS); 192*177fcc06SChinmay RathTRANS(FDIV, do_helper_ab, gen_helper_FDIV); 193*177fcc06SChinmay RathTRANS(FDIVS, do_helper_ab, gen_helper_FDIVS); 194*177fcc06SChinmay RathTRANS(FMUL, do_helper_ac, gen_helper_FMUL); 195*177fcc06SChinmay RathTRANS(FMULS, do_helper_ac, gen_helper_FMULS); 196*177fcc06SChinmay Rath 197*177fcc06SChinmay RathTRANS(FMADD, do_helper_acb, gen_helper_FMADD); 198*177fcc06SChinmay RathTRANS(FMADDS, do_helper_acb, gen_helper_FMADDS); 199*177fcc06SChinmay RathTRANS(FMSUB, do_helper_acb, gen_helper_FMSUB); 200*177fcc06SChinmay RathTRANS(FMSUBS, do_helper_acb, gen_helper_FMSUBS); 201*177fcc06SChinmay Rath 202*177fcc06SChinmay RathTRANS(FNMADD, do_helper_acb, gen_helper_FNMADD); 203*177fcc06SChinmay RathTRANS(FNMADDS, do_helper_acb, gen_helper_FNMADDS); 204*177fcc06SChinmay RathTRANS(FNMSUB, do_helper_acb, gen_helper_FNMSUB); 205*177fcc06SChinmay RathTRANS(FNMSUBS, do_helper_acb, gen_helper_FNMSUBS); 206*177fcc06SChinmay Rath 207*177fcc06SChinmay RathTRANS_FLAGS(FLOAT_EXT, FRE, do_helper_bs, gen_helper_FRE); 208*177fcc06SChinmay RathTRANS_FLAGS(FLOAT_FRES, FRES, do_helper_bs, gen_helper_FRES); 209*177fcc06SChinmay RathTRANS_FLAGS(FLOAT_FRSQRTE, FRSQRTE, do_helper_bs, gen_helper_FRSQRTE); 210*177fcc06SChinmay RathTRANS_FLAGS(FLOAT_FRSQRTES, FRSQRTES, do_helper_bs, gen_helper_FRSQRTES); 211*177fcc06SChinmay Rath 21274177ec6SVíctor ColomboTRANS(FSQRT, do_helper_fsqrt, gen_helper_FSQRT); 21374177ec6SVíctor ColomboTRANS(FSQRTS, do_helper_fsqrt, gen_helper_FSQRTS); 214139c1837SPaolo Bonzini 215139c1837SPaolo Bonzini/*** Floating-Point round & convert ***/ 216139c1837SPaolo Bonzini/* fctiw */ 217139c1837SPaolo BonziniGEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT); 218139c1837SPaolo Bonzini/* fctiwu */ 219139c1837SPaolo BonziniGEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206); 220139c1837SPaolo Bonzini/* fctiwz */ 221139c1837SPaolo BonziniGEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT); 222139c1837SPaolo Bonzini/* fctiwuz */ 223139c1837SPaolo BonziniGEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206); 224139c1837SPaolo Bonzini/* frsp */ 225139c1837SPaolo BonziniGEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT); 226139c1837SPaolo Bonzini/* fcfid */ 227139c1837SPaolo BonziniGEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC2_FP_CVT_S64); 228139c1837SPaolo Bonzini/* fcfids */ 229139c1837SPaolo BonziniGEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206); 230139c1837SPaolo Bonzini/* fcfidu */ 231139c1837SPaolo BonziniGEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206); 232139c1837SPaolo Bonzini/* fcfidus */ 233139c1837SPaolo BonziniGEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206); 234139c1837SPaolo Bonzini/* fctid */ 235139c1837SPaolo BonziniGEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC2_FP_CVT_S64); 236139c1837SPaolo Bonzini/* fctidu */ 237139c1837SPaolo BonziniGEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206); 238139c1837SPaolo Bonzini/* fctidz */ 239139c1837SPaolo BonziniGEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC2_FP_CVT_S64); 240139c1837SPaolo Bonzini/* fctidu */ 241139c1837SPaolo BonziniGEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206); 242139c1837SPaolo Bonzini 243139c1837SPaolo Bonzini/* frin */ 244139c1837SPaolo BonziniGEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT); 245139c1837SPaolo Bonzini/* friz */ 246139c1837SPaolo BonziniGEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT); 247139c1837SPaolo Bonzini/* frip */ 248139c1837SPaolo BonziniGEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT); 249139c1837SPaolo Bonzini/* frim */ 250139c1837SPaolo BonziniGEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT); 251139c1837SPaolo Bonzini 252*177fcc06SChinmay Rathstatic bool trans_FTDIV(DisasContext *ctx, arg_X_bf *a) 253139c1837SPaolo Bonzini{ 254*177fcc06SChinmay Rath TCGv_i64 t0, t1; 255*177fcc06SChinmay Rath REQUIRE_INSNS_FLAGS2(ctx, FP_TST_ISA206); 256*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 257139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 258139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 259*177fcc06SChinmay Rath get_fpr(t0, a->ra); 260*177fcc06SChinmay Rath get_fpr(t1, a->rb); 261*177fcc06SChinmay Rath gen_helper_FTDIV(cpu_crf[a->bf], t0, t1); 262*177fcc06SChinmay Rath return true; 263139c1837SPaolo Bonzini} 264139c1837SPaolo Bonzini 265*177fcc06SChinmay Rathstatic bool trans_FTSQRT(DisasContext *ctx, arg_X_bf_b *a) 266139c1837SPaolo Bonzini{ 267139c1837SPaolo Bonzini TCGv_i64 t0; 268*177fcc06SChinmay Rath REQUIRE_INSNS_FLAGS2(ctx, FP_TST_ISA206); 269*177fcc06SChinmay Rath REQUIRE_FPU(ctx); 270139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 271*177fcc06SChinmay Rath get_fpr(t0, a->rb); 272*177fcc06SChinmay Rath gen_helper_FTSQRT(cpu_crf[a->bf], t0); 273*177fcc06SChinmay Rath return true; 274139c1837SPaolo Bonzini} 275139c1837SPaolo Bonzini 276139c1837SPaolo Bonzini/*** Floating-Point compare ***/ 277139c1837SPaolo Bonzini 278139c1837SPaolo Bonzini/* fcmpo */ 279139c1837SPaolo Bonzinistatic void gen_fcmpo(DisasContext *ctx) 280139c1837SPaolo Bonzini{ 281139c1837SPaolo Bonzini TCGv_i32 crf; 282139c1837SPaolo Bonzini TCGv_i64 t0; 283139c1837SPaolo Bonzini TCGv_i64 t1; 284139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 285139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 286139c1837SPaolo Bonzini return; 287139c1837SPaolo Bonzini } 288139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 289139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 290139c1837SPaolo Bonzini gen_reset_fpstatus(); 29161d4bf33SRichard Henderson crf = tcg_constant_i32(crfD(ctx->opcode)); 292139c1837SPaolo Bonzini get_fpr(t0, rA(ctx->opcode)); 293139c1837SPaolo Bonzini get_fpr(t1, rB(ctx->opcode)); 294ad75a51eSRichard Henderson gen_helper_fcmpo(tcg_env, t0, t1, crf); 295ad75a51eSRichard Henderson gen_helper_float_check_status(tcg_env); 296139c1837SPaolo Bonzini} 297139c1837SPaolo Bonzini 298139c1837SPaolo Bonzini/* fcmpu */ 299139c1837SPaolo Bonzinistatic void gen_fcmpu(DisasContext *ctx) 300139c1837SPaolo Bonzini{ 301139c1837SPaolo Bonzini TCGv_i32 crf; 302139c1837SPaolo Bonzini TCGv_i64 t0; 303139c1837SPaolo Bonzini TCGv_i64 t1; 304139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 305139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 306139c1837SPaolo Bonzini return; 307139c1837SPaolo Bonzini } 308139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 309139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 310139c1837SPaolo Bonzini gen_reset_fpstatus(); 31161d4bf33SRichard Henderson crf = tcg_constant_i32(crfD(ctx->opcode)); 312139c1837SPaolo Bonzini get_fpr(t0, rA(ctx->opcode)); 313139c1837SPaolo Bonzini get_fpr(t1, rB(ctx->opcode)); 314ad75a51eSRichard Henderson gen_helper_fcmpu(tcg_env, t0, t1, crf); 315ad75a51eSRichard Henderson gen_helper_float_check_status(tcg_env); 316139c1837SPaolo Bonzini} 317139c1837SPaolo Bonzini 318139c1837SPaolo Bonzini/*** Floating-point move ***/ 319139c1837SPaolo Bonzini/* fabs */ 320139c1837SPaolo Bonzini/* XXX: beware that fabs never checks for NaNs nor update FPSCR */ 321139c1837SPaolo Bonzinistatic void gen_fabs(DisasContext *ctx) 322139c1837SPaolo Bonzini{ 323139c1837SPaolo Bonzini TCGv_i64 t0; 324139c1837SPaolo Bonzini TCGv_i64 t1; 325139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 326139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 327139c1837SPaolo Bonzini return; 328139c1837SPaolo Bonzini } 329139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 330139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 331139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 332139c1837SPaolo Bonzini tcg_gen_andi_i64(t1, t0, ~(1ULL << 63)); 333139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); 334139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode))) { 335139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 336139c1837SPaolo Bonzini } 337139c1837SPaolo Bonzini} 338139c1837SPaolo Bonzini 339139c1837SPaolo Bonzini/* fmr - fmr. */ 340139c1837SPaolo Bonzini/* XXX: beware that fmr never checks for NaNs nor update FPSCR */ 341139c1837SPaolo Bonzinistatic void gen_fmr(DisasContext *ctx) 342139c1837SPaolo Bonzini{ 343139c1837SPaolo Bonzini TCGv_i64 t0; 344139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 345139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 346139c1837SPaolo Bonzini return; 347139c1837SPaolo Bonzini } 348139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 349139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 350139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 351139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode))) { 352139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 353139c1837SPaolo Bonzini } 354139c1837SPaolo Bonzini} 355139c1837SPaolo Bonzini 356139c1837SPaolo Bonzini/* fnabs */ 357139c1837SPaolo Bonzini/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */ 358139c1837SPaolo Bonzinistatic void gen_fnabs(DisasContext *ctx) 359139c1837SPaolo Bonzini{ 360139c1837SPaolo Bonzini TCGv_i64 t0; 361139c1837SPaolo Bonzini TCGv_i64 t1; 362139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 363139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 364139c1837SPaolo Bonzini return; 365139c1837SPaolo Bonzini } 366139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 367139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 368139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 369139c1837SPaolo Bonzini tcg_gen_ori_i64(t1, t0, 1ULL << 63); 370139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); 371139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode))) { 372139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 373139c1837SPaolo Bonzini } 374139c1837SPaolo Bonzini} 375139c1837SPaolo Bonzini 376139c1837SPaolo Bonzini/* fneg */ 377139c1837SPaolo Bonzini/* XXX: beware that fneg never checks for NaNs nor update FPSCR */ 378139c1837SPaolo Bonzinistatic void gen_fneg(DisasContext *ctx) 379139c1837SPaolo Bonzini{ 380139c1837SPaolo Bonzini TCGv_i64 t0; 381139c1837SPaolo Bonzini TCGv_i64 t1; 382139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 383139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 384139c1837SPaolo Bonzini return; 385139c1837SPaolo Bonzini } 386139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 387139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 388139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 389139c1837SPaolo Bonzini tcg_gen_xori_i64(t1, t0, 1ULL << 63); 390139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); 391139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode))) { 392139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 393139c1837SPaolo Bonzini } 394139c1837SPaolo Bonzini} 395139c1837SPaolo Bonzini 396139c1837SPaolo Bonzini/* fcpsgn: PowerPC 2.05 specification */ 397139c1837SPaolo Bonzini/* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */ 398139c1837SPaolo Bonzinistatic void gen_fcpsgn(DisasContext *ctx) 399139c1837SPaolo Bonzini{ 400139c1837SPaolo Bonzini TCGv_i64 t0; 401139c1837SPaolo Bonzini TCGv_i64 t1; 402139c1837SPaolo Bonzini TCGv_i64 t2; 403139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 404139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 405139c1837SPaolo Bonzini return; 406139c1837SPaolo Bonzini } 407139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 408139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 409139c1837SPaolo Bonzini t2 = tcg_temp_new_i64(); 410139c1837SPaolo Bonzini get_fpr(t0, rA(ctx->opcode)); 411139c1837SPaolo Bonzini get_fpr(t1, rB(ctx->opcode)); 412139c1837SPaolo Bonzini tcg_gen_deposit_i64(t2, t0, t1, 0, 63); 413139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t2); 414139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode))) { 415139c1837SPaolo Bonzini gen_set_cr1_from_fpscr(ctx); 416139c1837SPaolo Bonzini } 417139c1837SPaolo Bonzini} 418139c1837SPaolo Bonzini 419139c1837SPaolo Bonzinistatic void gen_fmrgew(DisasContext *ctx) 420139c1837SPaolo Bonzini{ 421139c1837SPaolo Bonzini TCGv_i64 b0; 422139c1837SPaolo Bonzini TCGv_i64 t0; 423139c1837SPaolo Bonzini TCGv_i64 t1; 424139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 425139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 426139c1837SPaolo Bonzini return; 427139c1837SPaolo Bonzini } 428139c1837SPaolo Bonzini b0 = tcg_temp_new_i64(); 429139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 430139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 431139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 432139c1837SPaolo Bonzini tcg_gen_shri_i64(b0, t0, 32); 433139c1837SPaolo Bonzini get_fpr(t0, rA(ctx->opcode)); 434139c1837SPaolo Bonzini tcg_gen_deposit_i64(t1, t0, b0, 0, 32); 435139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); 436139c1837SPaolo Bonzini} 437139c1837SPaolo Bonzini 438139c1837SPaolo Bonzinistatic void gen_fmrgow(DisasContext *ctx) 439139c1837SPaolo Bonzini{ 440139c1837SPaolo Bonzini TCGv_i64 t0; 441139c1837SPaolo Bonzini TCGv_i64 t1; 442139c1837SPaolo Bonzini TCGv_i64 t2; 443139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 444139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 445139c1837SPaolo Bonzini return; 446139c1837SPaolo Bonzini } 447139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 448139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 449139c1837SPaolo Bonzini t2 = tcg_temp_new_i64(); 450139c1837SPaolo Bonzini get_fpr(t0, rB(ctx->opcode)); 451139c1837SPaolo Bonzini get_fpr(t1, rA(ctx->opcode)); 452139c1837SPaolo Bonzini tcg_gen_deposit_i64(t2, t0, t1, 32, 32); 453139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t2); 454139c1837SPaolo Bonzini} 455139c1837SPaolo Bonzini 456139c1837SPaolo Bonzini/*** Floating-Point status & ctrl register ***/ 457139c1837SPaolo Bonzini 458139c1837SPaolo Bonzini/* mcrfs */ 459139c1837SPaolo Bonzinistatic void gen_mcrfs(DisasContext *ctx) 460139c1837SPaolo Bonzini{ 461139c1837SPaolo Bonzini TCGv tmp = tcg_temp_new(); 462139c1837SPaolo Bonzini TCGv_i32 tmask; 463139c1837SPaolo Bonzini TCGv_i64 tnew_fpscr = tcg_temp_new_i64(); 464139c1837SPaolo Bonzini int bfa; 465139c1837SPaolo Bonzini int nibble; 466139c1837SPaolo Bonzini int shift; 467139c1837SPaolo Bonzini 468139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 469139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 470139c1837SPaolo Bonzini return; 471139c1837SPaolo Bonzini } 472139c1837SPaolo Bonzini bfa = crfS(ctx->opcode); 473139c1837SPaolo Bonzini nibble = 7 - bfa; 474139c1837SPaolo Bonzini shift = 4 * nibble; 475139c1837SPaolo Bonzini tcg_gen_shri_tl(tmp, cpu_fpscr, shift); 476139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp); 477139c1837SPaolo Bonzini tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 478139c1837SPaolo Bonzini 0xf); 479139c1837SPaolo Bonzini tcg_gen_extu_tl_i64(tnew_fpscr, cpu_fpscr); 480139c1837SPaolo Bonzini /* Only the exception bits (including FX) should be cleared if read */ 481139c1837SPaolo Bonzini tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr, 482139c1837SPaolo Bonzini ~((0xF << shift) & FP_EX_CLEAR_BITS)); 483139c1837SPaolo Bonzini /* FEX and VX need to be updated, so don't set fpscr directly */ 48461d4bf33SRichard Henderson tmask = tcg_constant_i32(1 << nibble); 485ad75a51eSRichard Henderson gen_helper_store_fpscr(tcg_env, tnew_fpscr, tmask); 486139c1837SPaolo Bonzini} 487139c1837SPaolo Bonzini 488bf8adfd8SVíctor Colombostatic TCGv_i64 place_from_fpscr(int rt, uint64_t mask) 489139c1837SPaolo Bonzini{ 490bf8adfd8SVíctor Colombo TCGv_i64 fpscr = tcg_temp_new_i64(); 491bf8adfd8SVíctor Colombo TCGv_i64 fpscr_masked = tcg_temp_new_i64(); 492139c1837SPaolo Bonzini 493bf8adfd8SVíctor Colombo tcg_gen_extu_tl_i64(fpscr, cpu_fpscr); 494bf8adfd8SVíctor Colombo tcg_gen_andi_i64(fpscr_masked, fpscr, mask); 495bf8adfd8SVíctor Colombo set_fpr(rt, fpscr_masked); 496139c1837SPaolo Bonzini 497bf8adfd8SVíctor Colombo return fpscr; 498139c1837SPaolo Bonzini} 499139c1837SPaolo Bonzini 500bf8adfd8SVíctor Colombostatic void store_fpscr_masked(TCGv_i64 fpscr, uint64_t clear_mask, 501bf8adfd8SVíctor Colombo TCGv_i64 set_mask, uint32_t store_mask) 502139c1837SPaolo Bonzini{ 503bf8adfd8SVíctor Colombo TCGv_i64 fpscr_masked = tcg_temp_new_i64(); 504bf8adfd8SVíctor Colombo TCGv_i32 st_mask = tcg_constant_i32(store_mask); 505139c1837SPaolo Bonzini 506bf8adfd8SVíctor Colombo tcg_gen_andi_i64(fpscr_masked, fpscr, ~clear_mask); 507bf8adfd8SVíctor Colombo tcg_gen_or_i64(fpscr_masked, fpscr_masked, set_mask); 508ad75a51eSRichard Henderson gen_helper_store_fpscr(tcg_env, fpscr_masked, st_mask); 509139c1837SPaolo Bonzini} 510139c1837SPaolo Bonzini 5115260ecffSRichard Purdiestatic bool trans_MFFS_ISA207(DisasContext *ctx, arg_X_t_rc *a) 5125260ecffSRichard Purdie{ 5135260ecffSRichard Purdie if (!(ctx->insns_flags2 & PPC2_ISA300)) { 5145260ecffSRichard Purdie /* 5155260ecffSRichard Purdie * Before Power ISA v3.0, MFFS bits 11~15 were reserved, any instruction 5165260ecffSRichard Purdie * with OPCD=63 and XO=583 should be decoded as MFFS. 5175260ecffSRichard Purdie */ 5185260ecffSRichard Purdie return trans_MFFS(ctx, a); 5195260ecffSRichard Purdie } 5205260ecffSRichard Purdie /* 5215260ecffSRichard Purdie * For Power ISA v3.0+, return false and let the pattern group 5225260ecffSRichard Purdie * select the correct instruction. 5235260ecffSRichard Purdie */ 5245260ecffSRichard Purdie return false; 5255260ecffSRichard Purdie} 5265260ecffSRichard Purdie 527f80d04d5SVíctor Colombostatic bool trans_MFFS(DisasContext *ctx, arg_X_t_rc *a) 528f80d04d5SVíctor Colombo{ 529f80d04d5SVíctor Colombo REQUIRE_FPU(ctx); 530f80d04d5SVíctor Colombo 531f80d04d5SVíctor Colombo gen_reset_fpstatus(); 532571f8507SRichard Henderson place_from_fpscr(a->rt, UINT64_MAX); 533f80d04d5SVíctor Colombo if (a->rc) { 534f80d04d5SVíctor Colombo gen_set_cr1_from_fpscr(ctx); 535f80d04d5SVíctor Colombo } 536f80d04d5SVíctor Colombo return true; 537f80d04d5SVíctor Colombo} 538f80d04d5SVíctor Colombo 539394c2e2fSVíctor Colombostatic bool trans_MFFSCE(DisasContext *ctx, arg_X_t *a) 540394c2e2fSVíctor Colombo{ 541394c2e2fSVíctor Colombo TCGv_i64 fpscr; 542394c2e2fSVíctor Colombo 543394c2e2fSVíctor Colombo REQUIRE_FPU(ctx); 544394c2e2fSVíctor Colombo 545394c2e2fSVíctor Colombo gen_reset_fpstatus(); 546394c2e2fSVíctor Colombo fpscr = place_from_fpscr(a->rt, UINT64_MAX); 547394c2e2fSVíctor Colombo store_fpscr_masked(fpscr, FP_ENABLES, tcg_constant_i64(0), 0x0003); 548394c2e2fSVíctor Colombo return true; 549394c2e2fSVíctor Colombo} 550394c2e2fSVíctor Colombo 551bf8adfd8SVíctor Colombostatic bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a) 552bf8adfd8SVíctor Colombo{ 553bf8adfd8SVíctor Colombo TCGv_i64 t1, fpscr; 554bf8adfd8SVíctor Colombo 555bf8adfd8SVíctor Colombo REQUIRE_FPU(ctx); 556139c1837SPaolo Bonzini 557139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 558bf8adfd8SVíctor Colombo get_fpr(t1, a->rb); 559139c1837SPaolo Bonzini tcg_gen_andi_i64(t1, t1, FP_RN); 560139c1837SPaolo Bonzini 561bf8adfd8SVíctor Colombo gen_reset_fpstatus(); 562bf8adfd8SVíctor Colombo fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); 563bf8adfd8SVíctor Colombo store_fpscr_masked(fpscr, FP_RN, t1, 0x0001); 564bf8adfd8SVíctor Colombo return true; 565139c1837SPaolo Bonzini} 566139c1837SPaolo Bonzini 5676cef305fSVíctor Colombostatic bool trans_MFFSCDRN(DisasContext *ctx, arg_X_tb *a) 5686cef305fSVíctor Colombo{ 5696cef305fSVíctor Colombo TCGv_i64 t1, fpscr; 5706cef305fSVíctor Colombo 5716cef305fSVíctor Colombo REQUIRE_FPU(ctx); 5726cef305fSVíctor Colombo 5736cef305fSVíctor Colombo t1 = tcg_temp_new_i64(); 5746cef305fSVíctor Colombo get_fpr(t1, a->rb); 5756cef305fSVíctor Colombo tcg_gen_andi_i64(t1, t1, FP_DRN); 5766cef305fSVíctor Colombo 5776cef305fSVíctor Colombo gen_reset_fpstatus(); 5786cef305fSVíctor Colombo fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); 5796cef305fSVíctor Colombo store_fpscr_masked(fpscr, FP_DRN, t1, 0x0100); 5806cef305fSVíctor Colombo return true; 5816cef305fSVíctor Colombo} 5826cef305fSVíctor Colombo 583bf8adfd8SVíctor Colombostatic bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) 584139c1837SPaolo Bonzini{ 585bf8adfd8SVíctor Colombo TCGv_i64 t1, fpscr; 586139c1837SPaolo Bonzini 587bf8adfd8SVíctor Colombo REQUIRE_FPU(ctx); 588139c1837SPaolo Bonzini 589bf8adfd8SVíctor Colombo t1 = tcg_temp_new_i64(); 590bf8adfd8SVíctor Colombo tcg_gen_movi_i64(t1, a->imm); 591139c1837SPaolo Bonzini 592bf8adfd8SVíctor Colombo gen_reset_fpstatus(); 593bf8adfd8SVíctor Colombo fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); 594bf8adfd8SVíctor Colombo store_fpscr_masked(fpscr, FP_RN, t1, 0x0001); 595bf8adfd8SVíctor Colombo return true; 596139c1837SPaolo Bonzini} 597139c1837SPaolo Bonzini 5986cef305fSVíctor Colombostatic bool trans_MFFSCDRNI(DisasContext *ctx, arg_X_imm3 *a) 5996cef305fSVíctor Colombo{ 6006cef305fSVíctor Colombo TCGv_i64 t1, fpscr; 6016cef305fSVíctor Colombo 6026cef305fSVíctor Colombo REQUIRE_FPU(ctx); 6036cef305fSVíctor Colombo 6046cef305fSVíctor Colombo t1 = tcg_temp_new_i64(); 6056cef305fSVíctor Colombo tcg_gen_movi_i64(t1, (uint64_t)a->imm << FPSCR_DRN0); 6066cef305fSVíctor Colombo 6076cef305fSVíctor Colombo gen_reset_fpstatus(); 6086cef305fSVíctor Colombo fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); 6096cef305fSVíctor Colombo store_fpscr_masked(fpscr, FP_DRN, t1, 0x0100); 6106cef305fSVíctor Colombo return true; 6116cef305fSVíctor Colombo} 6126cef305fSVíctor Colombo 6133e5bce70SVíctor Colombostatic bool trans_MFFSL(DisasContext *ctx, arg_X_t *a) 6143e5bce70SVíctor Colombo{ 6153e5bce70SVíctor Colombo REQUIRE_FPU(ctx); 6163e5bce70SVíctor Colombo 6173e5bce70SVíctor Colombo gen_reset_fpstatus(); 618571f8507SRichard Henderson place_from_fpscr(a->rt, FP_DRN | FP_STATUS | FP_ENABLES | FP_NI | FP_RN); 6193e5bce70SVíctor Colombo return true; 6203e5bce70SVíctor Colombo} 6213e5bce70SVíctor Colombo 622139c1837SPaolo Bonzini/* mtfsb0 */ 623139c1837SPaolo Bonzinistatic void gen_mtfsb0(DisasContext *ctx) 624139c1837SPaolo Bonzini{ 625139c1837SPaolo Bonzini uint8_t crb; 626139c1837SPaolo Bonzini 627139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 628139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 629139c1837SPaolo Bonzini return; 630139c1837SPaolo Bonzini } 631139c1837SPaolo Bonzini crb = 31 - crbD(ctx->opcode); 632139c1837SPaolo Bonzini gen_reset_fpstatus(); 633139c1837SPaolo Bonzini if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) { 634ad75a51eSRichard Henderson gen_helper_fpscr_clrbit(tcg_env, tcg_constant_i32(crb)); 635139c1837SPaolo Bonzini } 636139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode) != 0)) { 637139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); 638139c1837SPaolo Bonzini tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX); 639139c1837SPaolo Bonzini } 640139c1837SPaolo Bonzini} 641139c1837SPaolo Bonzini 642139c1837SPaolo Bonzini/* mtfsb1 */ 643139c1837SPaolo Bonzinistatic void gen_mtfsb1(DisasContext *ctx) 644139c1837SPaolo Bonzini{ 645139c1837SPaolo Bonzini uint8_t crb; 646139c1837SPaolo Bonzini 647139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 648139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 649139c1837SPaolo Bonzini return; 650139c1837SPaolo Bonzini } 651139c1837SPaolo Bonzini crb = 31 - crbD(ctx->opcode); 652139c1837SPaolo Bonzini /* XXX: we pretend we can only do IEEE floating-point computations */ 653139c1837SPaolo Bonzini if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) { 654ad75a51eSRichard Henderson gen_helper_fpscr_setbit(tcg_env, tcg_constant_i32(crb)); 655139c1837SPaolo Bonzini } 656139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode) != 0)) { 657139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); 658139c1837SPaolo Bonzini tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX); 659139c1837SPaolo Bonzini } 660139c1837SPaolo Bonzini /* We can raise a deferred exception */ 661ad75a51eSRichard Henderson gen_helper_fpscr_check_status(tcg_env); 662139c1837SPaolo Bonzini} 663139c1837SPaolo Bonzini 664139c1837SPaolo Bonzini/* mtfsf */ 665139c1837SPaolo Bonzinistatic void gen_mtfsf(DisasContext *ctx) 666139c1837SPaolo Bonzini{ 667139c1837SPaolo Bonzini TCGv_i32 t0; 668139c1837SPaolo Bonzini TCGv_i64 t1; 669139c1837SPaolo Bonzini int flm, l, w; 670139c1837SPaolo Bonzini 671139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 672139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 673139c1837SPaolo Bonzini return; 674139c1837SPaolo Bonzini } 675139c1837SPaolo Bonzini flm = FPFLM(ctx->opcode); 676139c1837SPaolo Bonzini l = FPL(ctx->opcode); 677139c1837SPaolo Bonzini w = FPW(ctx->opcode); 678139c1837SPaolo Bonzini if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) { 679139c1837SPaolo Bonzini gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 680139c1837SPaolo Bonzini return; 681139c1837SPaolo Bonzini } 68261d4bf33SRichard Henderson if (!l) { 68361d4bf33SRichard Henderson t0 = tcg_constant_i32(flm << (w * 8)); 68461d4bf33SRichard Henderson } else if (ctx->insns_flags2 & PPC2_ISA205) { 68561d4bf33SRichard Henderson t0 = tcg_constant_i32(0xffff); 686139c1837SPaolo Bonzini } else { 68761d4bf33SRichard Henderson t0 = tcg_constant_i32(0xff); 688139c1837SPaolo Bonzini } 689139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 690139c1837SPaolo Bonzini get_fpr(t1, rB(ctx->opcode)); 691ad75a51eSRichard Henderson gen_helper_store_fpscr(tcg_env, t1, t0); 692139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode) != 0)) { 693139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); 694139c1837SPaolo Bonzini tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX); 695139c1837SPaolo Bonzini } 696139c1837SPaolo Bonzini /* We can raise a deferred exception */ 697ad75a51eSRichard Henderson gen_helper_fpscr_check_status(tcg_env); 698139c1837SPaolo Bonzini} 699139c1837SPaolo Bonzini 700139c1837SPaolo Bonzini/* mtfsfi */ 701139c1837SPaolo Bonzinistatic void gen_mtfsfi(DisasContext *ctx) 702139c1837SPaolo Bonzini{ 703139c1837SPaolo Bonzini int bf, sh, w; 704139c1837SPaolo Bonzini TCGv_i64 t0; 705139c1837SPaolo Bonzini TCGv_i32 t1; 706139c1837SPaolo Bonzini 707139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 708139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 709139c1837SPaolo Bonzini return; 710139c1837SPaolo Bonzini } 711139c1837SPaolo Bonzini w = FPW(ctx->opcode); 712139c1837SPaolo Bonzini bf = FPBF(ctx->opcode); 713139c1837SPaolo Bonzini if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) { 714139c1837SPaolo Bonzini gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 715139c1837SPaolo Bonzini return; 716139c1837SPaolo Bonzini } 717139c1837SPaolo Bonzini sh = (8 * w) + 7 - bf; 71861d4bf33SRichard Henderson t0 = tcg_constant_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); 71961d4bf33SRichard Henderson t1 = tcg_constant_i32(1 << sh); 720ad75a51eSRichard Henderson gen_helper_store_fpscr(tcg_env, t0, t1); 721139c1837SPaolo Bonzini if (unlikely(Rc(ctx->opcode) != 0)) { 722139c1837SPaolo Bonzini tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr); 723139c1837SPaolo Bonzini tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX); 724139c1837SPaolo Bonzini } 725139c1837SPaolo Bonzini /* We can raise a deferred exception */ 726ad75a51eSRichard Henderson gen_helper_fpscr_check_status(tcg_env); 727139c1837SPaolo Bonzini} 728139c1837SPaolo Bonzini 729139c1837SPaolo Bonzinistatic void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 dest, TCGv addr) 730139c1837SPaolo Bonzini{ 731139c1837SPaolo Bonzini TCGv_i32 tmp = tcg_temp_new_i32(); 732139c1837SPaolo Bonzini tcg_gen_qemu_ld_i32(tmp, addr, ctx->mem_idx, DEF_MEMOP(MO_UL)); 733139c1837SPaolo Bonzini gen_helper_todouble(dest, tmp); 734139c1837SPaolo Bonzini} 735139c1837SPaolo Bonzini 736139c1837SPaolo Bonzini/* lfdepx (external PID lfdx) */ 737139c1837SPaolo Bonzinistatic void gen_lfdepx(DisasContext *ctx) 738139c1837SPaolo Bonzini{ 739139c1837SPaolo Bonzini TCGv EA; 740139c1837SPaolo Bonzini TCGv_i64 t0; 7419f0cf041SMatheus Ferst CHK_SV(ctx); 742139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 743139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 744139c1837SPaolo Bonzini return; 745139c1837SPaolo Bonzini } 746139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 747139c1837SPaolo Bonzini EA = tcg_temp_new(); 748139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 749139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 750fc313c64SFrédéric Pétrot tcg_gen_qemu_ld_i64(t0, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UQ)); 751139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 752139c1837SPaolo Bonzini} 753139c1837SPaolo Bonzini 754139c1837SPaolo Bonzini/* lfdp */ 755139c1837SPaolo Bonzinistatic void gen_lfdp(DisasContext *ctx) 756139c1837SPaolo Bonzini{ 757139c1837SPaolo Bonzini TCGv EA; 758139c1837SPaolo Bonzini TCGv_i64 t0; 759139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 760139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 761139c1837SPaolo Bonzini return; 762139c1837SPaolo Bonzini } 763139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 764139c1837SPaolo Bonzini EA = tcg_temp_new(); 765139c1837SPaolo Bonzini gen_addr_imm_index(ctx, EA, 0); 766139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 767139c1837SPaolo Bonzini /* 768139c1837SPaolo Bonzini * We only need to swap high and low halves. gen_qemu_ld64_i64 769139c1837SPaolo Bonzini * does necessary 64-bit byteswap already. 770139c1837SPaolo Bonzini */ 771139c1837SPaolo Bonzini if (unlikely(ctx->le_mode)) { 772139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 773139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode) + 1, t0); 774139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 775139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 776139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 777139c1837SPaolo Bonzini } else { 778139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 779139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 780139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 781139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 782139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode) + 1, t0); 783139c1837SPaolo Bonzini } 784139c1837SPaolo Bonzini} 785139c1837SPaolo Bonzini 786139c1837SPaolo Bonzini/* lfdpx */ 787139c1837SPaolo Bonzinistatic void gen_lfdpx(DisasContext *ctx) 788139c1837SPaolo Bonzini{ 789139c1837SPaolo Bonzini TCGv EA; 790139c1837SPaolo Bonzini TCGv_i64 t0; 791139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 792139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 793139c1837SPaolo Bonzini return; 794139c1837SPaolo Bonzini } 795139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 796139c1837SPaolo Bonzini EA = tcg_temp_new(); 797139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 798139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 799139c1837SPaolo Bonzini /* 800139c1837SPaolo Bonzini * We only need to swap high and low halves. gen_qemu_ld64_i64 801139c1837SPaolo Bonzini * does necessary 64-bit byteswap already. 802139c1837SPaolo Bonzini */ 803139c1837SPaolo Bonzini if (unlikely(ctx->le_mode)) { 804139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 805139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode) + 1, t0); 806139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 807139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 808139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 809139c1837SPaolo Bonzini } else { 810139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 811139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 812139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 813139c1837SPaolo Bonzini gen_qemu_ld64_i64(ctx, t0, EA); 814139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode) + 1, t0); 815139c1837SPaolo Bonzini } 816139c1837SPaolo Bonzini} 817139c1837SPaolo Bonzini 818139c1837SPaolo Bonzini/* lfiwax */ 819139c1837SPaolo Bonzinistatic void gen_lfiwax(DisasContext *ctx) 820139c1837SPaolo Bonzini{ 821139c1837SPaolo Bonzini TCGv EA; 822139c1837SPaolo Bonzini TCGv t0; 823139c1837SPaolo Bonzini TCGv_i64 t1; 824139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 825139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 826139c1837SPaolo Bonzini return; 827139c1837SPaolo Bonzini } 828139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 829139c1837SPaolo Bonzini EA = tcg_temp_new(); 830139c1837SPaolo Bonzini t0 = tcg_temp_new(); 831139c1837SPaolo Bonzini t1 = tcg_temp_new_i64(); 832139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 833139c1837SPaolo Bonzini gen_qemu_ld32s(ctx, t0, EA); 834139c1837SPaolo Bonzini tcg_gen_ext_tl_i64(t1, t0); 835139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t1); 836139c1837SPaolo Bonzini} 837139c1837SPaolo Bonzini 838139c1837SPaolo Bonzini/* lfiwzx */ 839139c1837SPaolo Bonzinistatic void gen_lfiwzx(DisasContext *ctx) 840139c1837SPaolo Bonzini{ 841139c1837SPaolo Bonzini TCGv EA; 842139c1837SPaolo Bonzini TCGv_i64 t0; 843139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 844139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 845139c1837SPaolo Bonzini return; 846139c1837SPaolo Bonzini } 847139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 848139c1837SPaolo Bonzini EA = tcg_temp_new(); 849139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 850139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 851139c1837SPaolo Bonzini gen_qemu_ld32u_i64(ctx, t0, EA); 852139c1837SPaolo Bonzini set_fpr(rD(ctx->opcode), t0); 853139c1837SPaolo Bonzini} 854139c1837SPaolo Bonzini 855139c1837SPaolo Bonzini#define GEN_STXF(name, stop, opc2, opc3, type) \ 856139c1837SPaolo Bonzinistatic void glue(gen_, name##x)(DisasContext *ctx) \ 857139c1837SPaolo Bonzini{ \ 858139c1837SPaolo Bonzini TCGv EA; \ 859139c1837SPaolo Bonzini TCGv_i64 t0; \ 860139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { \ 861139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); \ 862139c1837SPaolo Bonzini return; \ 863139c1837SPaolo Bonzini } \ 864139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); \ 865139c1837SPaolo Bonzini EA = tcg_temp_new(); \ 866139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); \ 867139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); \ 868139c1837SPaolo Bonzini get_fpr(t0, rS(ctx->opcode)); \ 869139c1837SPaolo Bonzini gen_qemu_##stop(ctx, t0, EA); \ 870139c1837SPaolo Bonzini} 871139c1837SPaolo Bonzini 872139c1837SPaolo Bonzinistatic void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 src, TCGv addr) 873139c1837SPaolo Bonzini{ 874139c1837SPaolo Bonzini TCGv_i32 tmp = tcg_temp_new_i32(); 875139c1837SPaolo Bonzini gen_helper_tosingle(tmp, src); 876139c1837SPaolo Bonzini tcg_gen_qemu_st_i32(tmp, addr, ctx->mem_idx, DEF_MEMOP(MO_UL)); 877139c1837SPaolo Bonzini} 878139c1837SPaolo Bonzini 879139c1837SPaolo Bonzini/* stfdepx (external PID lfdx) */ 880139c1837SPaolo Bonzinistatic void gen_stfdepx(DisasContext *ctx) 881139c1837SPaolo Bonzini{ 882139c1837SPaolo Bonzini TCGv EA; 883139c1837SPaolo Bonzini TCGv_i64 t0; 8849f0cf041SMatheus Ferst CHK_SV(ctx); 885139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 886139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 887139c1837SPaolo Bonzini return; 888139c1837SPaolo Bonzini } 889139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 890139c1837SPaolo Bonzini EA = tcg_temp_new(); 891139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 892139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 893139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode)); 894fc313c64SFrédéric Pétrot tcg_gen_qemu_st_i64(t0, EA, PPC_TLB_EPID_STORE, DEF_MEMOP(MO_UQ)); 895139c1837SPaolo Bonzini} 896139c1837SPaolo Bonzini 897139c1837SPaolo Bonzini/* stfdp */ 898139c1837SPaolo Bonzinistatic void gen_stfdp(DisasContext *ctx) 899139c1837SPaolo Bonzini{ 900139c1837SPaolo Bonzini TCGv EA; 901139c1837SPaolo Bonzini TCGv_i64 t0; 902139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 903139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 904139c1837SPaolo Bonzini return; 905139c1837SPaolo Bonzini } 906139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 907139c1837SPaolo Bonzini EA = tcg_temp_new(); 908139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 909139c1837SPaolo Bonzini gen_addr_imm_index(ctx, EA, 0); 910139c1837SPaolo Bonzini /* 911139c1837SPaolo Bonzini * We only need to swap high and low halves. gen_qemu_st64_i64 912139c1837SPaolo Bonzini * does necessary 64-bit byteswap already. 913139c1837SPaolo Bonzini */ 914139c1837SPaolo Bonzini if (unlikely(ctx->le_mode)) { 915139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode) + 1); 916139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 917139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 918139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode)); 919139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 920139c1837SPaolo Bonzini } else { 921139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode)); 922139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 923139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 924139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode) + 1); 925139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 926139c1837SPaolo Bonzini } 927139c1837SPaolo Bonzini} 928139c1837SPaolo Bonzini 929139c1837SPaolo Bonzini/* stfdpx */ 930139c1837SPaolo Bonzinistatic void gen_stfdpx(DisasContext *ctx) 931139c1837SPaolo Bonzini{ 932139c1837SPaolo Bonzini TCGv EA; 933139c1837SPaolo Bonzini TCGv_i64 t0; 934139c1837SPaolo Bonzini if (unlikely(!ctx->fpu_enabled)) { 935139c1837SPaolo Bonzini gen_exception(ctx, POWERPC_EXCP_FPU); 936139c1837SPaolo Bonzini return; 937139c1837SPaolo Bonzini } 938139c1837SPaolo Bonzini gen_set_access_type(ctx, ACCESS_FLOAT); 939139c1837SPaolo Bonzini EA = tcg_temp_new(); 940139c1837SPaolo Bonzini t0 = tcg_temp_new_i64(); 941139c1837SPaolo Bonzini gen_addr_reg_index(ctx, EA); 942139c1837SPaolo Bonzini /* 943139c1837SPaolo Bonzini * We only need to swap high and low halves. gen_qemu_st64_i64 944139c1837SPaolo Bonzini * does necessary 64-bit byteswap already. 945139c1837SPaolo Bonzini */ 946139c1837SPaolo Bonzini if (unlikely(ctx->le_mode)) { 947139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode) + 1); 948139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 949139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 950139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode)); 951139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 952139c1837SPaolo Bonzini } else { 953139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode)); 954139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 955139c1837SPaolo Bonzini tcg_gen_addi_tl(EA, EA, 8); 956139c1837SPaolo Bonzini get_fpr(t0, rD(ctx->opcode) + 1); 957139c1837SPaolo Bonzini gen_qemu_st64_i64(ctx, t0, EA); 958139c1837SPaolo Bonzini } 959139c1837SPaolo Bonzini} 960139c1837SPaolo Bonzini 961139c1837SPaolo Bonzini/* Optional: */ 962139c1837SPaolo Bonzinistatic inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2) 963139c1837SPaolo Bonzini{ 964139c1837SPaolo Bonzini TCGv t0 = tcg_temp_new(); 965139c1837SPaolo Bonzini tcg_gen_trunc_i64_tl(t0, arg1), 966139c1837SPaolo Bonzini gen_qemu_st32(ctx, t0, arg2); 967139c1837SPaolo Bonzini} 968139c1837SPaolo Bonzini/* stfiwx */ 969139c1837SPaolo BonziniGEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX); 970139c1837SPaolo Bonzini 971fbd2e60eSFernando Eckhardt Valle/* Floating-point Load/Store Instructions */ 972fbd2e60eSFernando Eckhardt Vallestatic bool do_lsfpsd(DisasContext *ctx, int rt, int ra, TCGv displ, 973fbd2e60eSFernando Eckhardt Valle bool update, bool store, bool single) 974fbd2e60eSFernando Eckhardt Valle{ 975fbd2e60eSFernando Eckhardt Valle TCGv ea; 976fbd2e60eSFernando Eckhardt Valle TCGv_i64 t0; 977fbd2e60eSFernando Eckhardt Valle REQUIRE_INSNS_FLAGS(ctx, FLOAT); 978fbd2e60eSFernando Eckhardt Valle REQUIRE_FPU(ctx); 979fbd2e60eSFernando Eckhardt Valle if (update && ra == 0) { 980fbd2e60eSFernando Eckhardt Valle gen_invalid(ctx); 981fbd2e60eSFernando Eckhardt Valle return true; 982fbd2e60eSFernando Eckhardt Valle } 983fbd2e60eSFernando Eckhardt Valle gen_set_access_type(ctx, ACCESS_FLOAT); 984fbd2e60eSFernando Eckhardt Valle t0 = tcg_temp_new_i64(); 985fbd2e60eSFernando Eckhardt Valle ea = do_ea_calc(ctx, ra, displ); 986fbd2e60eSFernando Eckhardt Valle if (store) { 987fbd2e60eSFernando Eckhardt Valle get_fpr(t0, rt); 988fbd2e60eSFernando Eckhardt Valle if (single) { 989fbd2e60eSFernando Eckhardt Valle gen_qemu_st32fs(ctx, t0, ea); 990fbd2e60eSFernando Eckhardt Valle } else { 991fbd2e60eSFernando Eckhardt Valle gen_qemu_st64_i64(ctx, t0, ea); 992fbd2e60eSFernando Eckhardt Valle } 993fbd2e60eSFernando Eckhardt Valle } else { 994fbd2e60eSFernando Eckhardt Valle if (single) { 995fbd2e60eSFernando Eckhardt Valle gen_qemu_ld32fs(ctx, t0, ea); 996fbd2e60eSFernando Eckhardt Valle } else { 997fbd2e60eSFernando Eckhardt Valle gen_qemu_ld64_i64(ctx, t0, ea); 998fbd2e60eSFernando Eckhardt Valle } 999fbd2e60eSFernando Eckhardt Valle set_fpr(rt, t0); 1000fbd2e60eSFernando Eckhardt Valle } 1001fbd2e60eSFernando Eckhardt Valle if (update) { 10023620328fSMatheus Ferst tcg_gen_mov_tl(cpu_gpr[ra], ea); 1003fbd2e60eSFernando Eckhardt Valle } 1004fbd2e60eSFernando Eckhardt Valle return true; 1005fbd2e60eSFernando Eckhardt Valle} 1006fbd2e60eSFernando Eckhardt Valle 1007fbd2e60eSFernando Eckhardt Vallestatic bool do_lsfp_D(DisasContext *ctx, arg_D *a, bool update, bool store, 1008fbd2e60eSFernando Eckhardt Valle bool single) 1009fbd2e60eSFernando Eckhardt Valle{ 1010fbd2e60eSFernando Eckhardt Valle return do_lsfpsd(ctx, a->rt, a->ra, tcg_constant_tl(a->si), update, store, 1011fbd2e60eSFernando Eckhardt Valle single); 1012fbd2e60eSFernando Eckhardt Valle} 1013fbd2e60eSFernando Eckhardt Valle 1014dcb4e5b7SFernando Eckhardt Vallestatic bool do_lsfp_PLS_D(DisasContext *ctx, arg_PLS_D *a, bool update, 1015dcb4e5b7SFernando Eckhardt Valle bool store, bool single) 1016dcb4e5b7SFernando Eckhardt Valle{ 1017dcb4e5b7SFernando Eckhardt Valle arg_D d; 1018dcb4e5b7SFernando Eckhardt Valle if (!resolve_PLS_D(ctx, &d, a)) { 1019dcb4e5b7SFernando Eckhardt Valle return true; 1020dcb4e5b7SFernando Eckhardt Valle } 1021dcb4e5b7SFernando Eckhardt Valle return do_lsfp_D(ctx, &d, update, store, single); 1022dcb4e5b7SFernando Eckhardt Valle} 1023dcb4e5b7SFernando Eckhardt Valle 1024fbd2e60eSFernando Eckhardt Vallestatic bool do_lsfp_X(DisasContext *ctx, arg_X *a, bool update, 1025fbd2e60eSFernando Eckhardt Valle bool store, bool single) 1026fbd2e60eSFernando Eckhardt Valle{ 1027fbd2e60eSFernando Eckhardt Valle return do_lsfpsd(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, single); 1028fbd2e60eSFernando Eckhardt Valle} 1029fbd2e60eSFernando Eckhardt Valle 1030fbd2e60eSFernando Eckhardt ValleTRANS(LFS, do_lsfp_D, false, false, true) 1031fbd2e60eSFernando Eckhardt ValleTRANS(LFSU, do_lsfp_D, true, false, true) 1032fbd2e60eSFernando Eckhardt ValleTRANS(LFSX, do_lsfp_X, false, false, true) 1033fbd2e60eSFernando Eckhardt ValleTRANS(LFSUX, do_lsfp_X, true, false, true) 1034dcb4e5b7SFernando Eckhardt ValleTRANS(PLFS, do_lsfp_PLS_D, false, false, true) 1035fbd2e60eSFernando Eckhardt Valle 1036fbd2e60eSFernando Eckhardt ValleTRANS(LFD, do_lsfp_D, false, false, false) 1037fbd2e60eSFernando Eckhardt ValleTRANS(LFDU, do_lsfp_D, true, false, false) 1038fbd2e60eSFernando Eckhardt ValleTRANS(LFDX, do_lsfp_X, false, false, false) 1039fbd2e60eSFernando Eckhardt ValleTRANS(LFDUX, do_lsfp_X, true, false, false) 1040dcb4e5b7SFernando Eckhardt ValleTRANS(PLFD, do_lsfp_PLS_D, false, false, false) 1041fbd2e60eSFernando Eckhardt Valle 1042fbd2e60eSFernando Eckhardt ValleTRANS(STFS, do_lsfp_D, false, true, true) 1043fbd2e60eSFernando Eckhardt ValleTRANS(STFSU, do_lsfp_D, true, true, true) 1044fbd2e60eSFernando Eckhardt ValleTRANS(STFSX, do_lsfp_X, false, true, true) 1045fbd2e60eSFernando Eckhardt ValleTRANS(STFSUX, do_lsfp_X, true, true, true) 1046dcb4e5b7SFernando Eckhardt ValleTRANS(PSTFS, do_lsfp_PLS_D, false, true, true) 1047fbd2e60eSFernando Eckhardt Valle 1048fbd2e60eSFernando Eckhardt ValleTRANS(STFD, do_lsfp_D, false, true, false) 1049fbd2e60eSFernando Eckhardt ValleTRANS(STFDU, do_lsfp_D, true, true, false) 1050fbd2e60eSFernando Eckhardt ValleTRANS(STFDX, do_lsfp_X, false, true, false) 1051fbd2e60eSFernando Eckhardt ValleTRANS(STFDUX, do_lsfp_X, true, true, false) 1052dcb4e5b7SFernando Eckhardt ValleTRANS(PSTFD, do_lsfp_PLS_D, false, true, false) 1053fbd2e60eSFernando Eckhardt Valle 1054139c1837SPaolo Bonzini#undef GEN_FLOAT_B 1055139c1837SPaolo Bonzini 1056139c1837SPaolo Bonzini#undef GEN_LDF 1057139c1837SPaolo Bonzini#undef GEN_LDUF 1058139c1837SPaolo Bonzini#undef GEN_LDUXF 1059139c1837SPaolo Bonzini#undef GEN_LDXF 1060139c1837SPaolo Bonzini#undef GEN_LDFS 1061139c1837SPaolo Bonzini 1062139c1837SPaolo Bonzini#undef GEN_STF 1063139c1837SPaolo Bonzini#undef GEN_STUF 1064139c1837SPaolo Bonzini#undef GEN_STUXF 1065139c1837SPaolo Bonzini#undef GEN_STXF 1066139c1837SPaolo Bonzini#undef GEN_STFS 1067