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