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 if (a->imm) { 19 temp = tcg_temp_new(); 20 tcg_gen_addi_tl(temp, addr, a->imm); 21 addr = temp; 22 } 23 24 tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 25 maybe_nanbox_load(cpu_fpr[a->fd], mop); 26 27 if (temp) { 28 tcg_temp_free(temp); 29 } 30 31 return true; 32} 33 34static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) 35{ 36 TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); 37 TCGv temp = NULL; 38 39 if (a->imm) { 40 temp = tcg_temp_new(); 41 tcg_gen_addi_tl(temp, addr, a->imm); 42 addr = temp; 43 } 44 45 tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 46 47 if (temp) { 48 tcg_temp_free(temp); 49 } 50 return true; 51} 52 53static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop) 54{ 55 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 56 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 57 TCGv addr = tcg_temp_new(); 58 59 tcg_gen_add_tl(addr, src1, src2); 60 tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 61 maybe_nanbox_load(cpu_fpr[a->fd], mop); 62 tcg_temp_free(addr); 63 64 return true; 65} 66 67static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop) 68{ 69 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 70 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 71 TCGv addr = tcg_temp_new(); 72 73 tcg_gen_add_tl(addr, src1, src2); 74 tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 75 tcg_temp_free(addr); 76 77 return true; 78} 79 80static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop) 81{ 82 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 83 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 84 TCGv addr = tcg_temp_new(); 85 86 gen_helper_asrtgt_d(cpu_env, src1, src2); 87 tcg_gen_add_tl(addr, src1, src2); 88 tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 89 maybe_nanbox_load(cpu_fpr[a->fd], mop); 90 tcg_temp_free(addr); 91 92 return true; 93} 94 95static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop) 96{ 97 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 98 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 99 TCGv addr = tcg_temp_new(); 100 101 gen_helper_asrtgt_d(cpu_env, src1, src2); 102 tcg_gen_add_tl(addr, src1, src2); 103 tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 104 tcg_temp_free(addr); 105 106 return true; 107} 108 109static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop) 110{ 111 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 112 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 113 TCGv addr = tcg_temp_new(); 114 115 gen_helper_asrtle_d(cpu_env, src1, src2); 116 tcg_gen_add_tl(addr, src1, src2); 117 tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 118 maybe_nanbox_load(cpu_fpr[a->fd], mop); 119 tcg_temp_free(addr); 120 121 return true; 122} 123 124static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop) 125{ 126 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 127 TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); 128 TCGv addr = tcg_temp_new(); 129 130 gen_helper_asrtle_d(cpu_env, src1, src2); 131 tcg_gen_add_tl(addr, src1, src2); 132 tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); 133 tcg_temp_free(addr); 134 135 return true; 136} 137 138TRANS(fld_s, gen_fload_i, MO_TEUL) 139TRANS(fst_s, gen_fstore_i, MO_TEUL) 140TRANS(fld_d, gen_fload_i, MO_TEUQ) 141TRANS(fst_d, gen_fstore_i, MO_TEUQ) 142TRANS(fldx_s, gen_floadx, MO_TEUL) 143TRANS(fldx_d, gen_floadx, MO_TEUQ) 144TRANS(fstx_s, gen_fstorex, MO_TEUL) 145TRANS(fstx_d, gen_fstorex, MO_TEUQ) 146TRANS(fldgt_s, gen_fload_gt, MO_TEUL) 147TRANS(fldgt_d, gen_fload_gt, MO_TEUQ) 148TRANS(fldle_s, gen_fload_le, MO_TEUL) 149TRANS(fldle_d, gen_fload_le, MO_TEUQ) 150TRANS(fstgt_s, gen_fstore_gt, MO_TEUL) 151TRANS(fstgt_d, gen_fstore_gt, MO_TEUQ) 152TRANS(fstle_s, gen_fstore_le, MO_TEUL) 153TRANS(fstle_d, gen_fstore_le, MO_TEUQ) 154