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