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