1*5c23704eSSong Gao/* SPDX-License-Identifier: GPL-2.0-or-later */ 2*5c23704eSSong Gao/* 3*5c23704eSSong Gao * Copyright (c) 2021 Loongson Technology Corporation Limited 4*5c23704eSSong Gao */ 5*5c23704eSSong Gao 6*5c23704eSSong Gaostatic void maybe_nanbox_load(TCGv freg, MemOp mop) 7*5c23704eSSong Gao{ 8*5c23704eSSong Gao if ((mop & MO_SIZE) == MO_32) { 9*5c23704eSSong Gao gen_nanbox_s(freg, freg); 10*5c23704eSSong Gao } 11*5c23704eSSong Gao} 12*5c23704eSSong Gao 13*5c23704eSSong Gaostatic bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) 14*5c23704eSSong Gao{ 15*5c23704eSSong Gao TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); 16*5c23704eSSong Gao TCGv dest = get_fpr(ctx, a->fd); 17*5c23704eSSong Gao 18*5c23704eSSong Gao CHECK_FPE; 19*5c23704eSSong Gao 20*5c23704eSSong Gao addr = make_address_i(ctx, addr, a->imm); 21*5c23704eSSong Gao 22*5c23704eSSong Gao tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); 23*5c23704eSSong Gao maybe_nanbox_load(dest, mop); 24*5c23704eSSong Gao set_fpr(a->fd, dest); 25*5c23704eSSong Gao 26*5c23704eSSong Gao return true; 27*5c23704eSSong Gao} 28*5c23704eSSong Gao 29*5c23704eSSong Gaostatic bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) 30*5c23704eSSong Gao{ 31*5c23704eSSong Gao TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); 32*5c23704eSSong Gao TCGv src = get_fpr(ctx, a->fd); 33*5c23704eSSong Gao 34*5c23704eSSong Gao CHECK_FPE; 35*5c23704eSSong Gao 36*5c23704eSSong Gao addr = make_address_i(ctx, addr, a->imm); 37*5c23704eSSong Gao 38*5c23704eSSong Gao tcg_gen_qemu_st_tl(src, addr, ctx->mem_idx, mop); 39*5c23704eSSong Gao 40*5c23704eSSong Gao return true; 41*5c23704eSSong Gao} 42*5c23704eSSong Gao 43*5c23704eSSong Gaostatic bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop) 44*5c23704eSSong Gao{ 45*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 46*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 47*5c23704eSSong Gao TCGv dest = get_fpr(ctx, a->fd); 48*5c23704eSSong Gao TCGv addr; 49*5c23704eSSong Gao 50*5c23704eSSong Gao CHECK_FPE; 51*5c23704eSSong Gao 52*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 53*5c23704eSSong Gao tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); 54*5c23704eSSong Gao maybe_nanbox_load(dest, mop); 55*5c23704eSSong Gao set_fpr(a->fd, dest); 56*5c23704eSSong Gao 57*5c23704eSSong Gao return true; 58*5c23704eSSong Gao} 59*5c23704eSSong Gao 60*5c23704eSSong Gaostatic bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop) 61*5c23704eSSong Gao{ 62*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 63*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 64*5c23704eSSong Gao TCGv src3 = get_fpr(ctx, a->fd); 65*5c23704eSSong Gao TCGv addr; 66*5c23704eSSong Gao 67*5c23704eSSong Gao CHECK_FPE; 68*5c23704eSSong Gao 69*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 70*5c23704eSSong Gao tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop); 71*5c23704eSSong Gao 72*5c23704eSSong Gao return true; 73*5c23704eSSong Gao} 74*5c23704eSSong Gao 75*5c23704eSSong Gaostatic bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop) 76*5c23704eSSong Gao{ 77*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 78*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 79*5c23704eSSong Gao TCGv dest = get_fpr(ctx, a->fd); 80*5c23704eSSong Gao TCGv addr; 81*5c23704eSSong Gao 82*5c23704eSSong Gao CHECK_FPE; 83*5c23704eSSong Gao 84*5c23704eSSong Gao gen_helper_asrtgt_d(tcg_env, src1, src2); 85*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 86*5c23704eSSong Gao tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); 87*5c23704eSSong Gao maybe_nanbox_load(dest, mop); 88*5c23704eSSong Gao set_fpr(a->fd, dest); 89*5c23704eSSong Gao 90*5c23704eSSong Gao return true; 91*5c23704eSSong Gao} 92*5c23704eSSong Gao 93*5c23704eSSong Gaostatic bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop) 94*5c23704eSSong Gao{ 95*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 96*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 97*5c23704eSSong Gao TCGv src3 = get_fpr(ctx, a->fd); 98*5c23704eSSong Gao TCGv addr; 99*5c23704eSSong Gao 100*5c23704eSSong Gao CHECK_FPE; 101*5c23704eSSong Gao 102*5c23704eSSong Gao gen_helper_asrtgt_d(tcg_env, src1, src2); 103*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 104*5c23704eSSong Gao tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop); 105*5c23704eSSong Gao 106*5c23704eSSong Gao return true; 107*5c23704eSSong Gao} 108*5c23704eSSong Gao 109*5c23704eSSong Gaostatic bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop) 110*5c23704eSSong Gao{ 111*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 112*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 113*5c23704eSSong Gao TCGv dest = get_fpr(ctx, a->fd); 114*5c23704eSSong Gao TCGv addr; 115*5c23704eSSong Gao 116*5c23704eSSong Gao CHECK_FPE; 117*5c23704eSSong Gao 118*5c23704eSSong Gao gen_helper_asrtle_d(tcg_env, src1, src2); 119*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 120*5c23704eSSong Gao tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); 121*5c23704eSSong Gao maybe_nanbox_load(dest, mop); 122*5c23704eSSong Gao set_fpr(a->fd, dest); 123*5c23704eSSong Gao 124*5c23704eSSong Gao return true; 125*5c23704eSSong Gao} 126*5c23704eSSong Gao 127*5c23704eSSong Gaostatic bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop) 128*5c23704eSSong Gao{ 129*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 130*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 131*5c23704eSSong Gao TCGv src3 = get_fpr(ctx, a->fd); 132*5c23704eSSong Gao TCGv addr; 133*5c23704eSSong Gao 134*5c23704eSSong Gao CHECK_FPE; 135*5c23704eSSong Gao 136*5c23704eSSong Gao gen_helper_asrtle_d(tcg_env, src1, src2); 137*5c23704eSSong Gao addr = make_address_x(ctx, src1, src2); 138*5c23704eSSong Gao tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop); 139*5c23704eSSong Gao 140*5c23704eSSong Gao return true; 141*5c23704eSSong Gao} 142*5c23704eSSong Gao 143*5c23704eSSong GaoTRANS(fld_s, FP_SP, gen_fload_i, MO_TEUL) 144*5c23704eSSong GaoTRANS(fst_s, FP_SP, gen_fstore_i, MO_TEUL) 145*5c23704eSSong GaoTRANS(fld_d, FP_DP, gen_fload_i, MO_TEUQ) 146*5c23704eSSong GaoTRANS(fst_d, FP_DP, gen_fstore_i, MO_TEUQ) 147*5c23704eSSong GaoTRANS(fldx_s, FP_SP, gen_floadx, MO_TEUL) 148*5c23704eSSong GaoTRANS(fldx_d, FP_DP, gen_floadx, MO_TEUQ) 149*5c23704eSSong GaoTRANS(fstx_s, FP_SP, gen_fstorex, MO_TEUL) 150*5c23704eSSong GaoTRANS(fstx_d, FP_DP, gen_fstorex, MO_TEUQ) 151*5c23704eSSong GaoTRANS(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL) 152*5c23704eSSong GaoTRANS(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ) 153*5c23704eSSong GaoTRANS(fldle_s, FP_SP, gen_fload_le, MO_TEUL) 154*5c23704eSSong GaoTRANS(fldle_d, FP_DP, gen_fload_le, MO_TEUQ) 155*5c23704eSSong GaoTRANS(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL) 156*5c23704eSSong GaoTRANS(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ) 157*5c23704eSSong GaoTRANS(fstle_s, FP_SP, gen_fstore_le, MO_TEUL) 158*5c23704eSSong GaoTRANS(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ) 159