1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (c) 2021 Loongson Technology Corporation Limited
4 */
5
6/* bit0(signaling/quiet) bit1(lt) bit2(eq) bit3(un) bit4(neq) */
7static uint32_t get_fcmp_flags(int cond)
8{
9    uint32_t flags = 0;
10
11    if (cond & 0x1) {
12        flags |= FCMP_LT;
13    }
14    if (cond & 0x2) {
15        flags |= FCMP_EQ;
16    }
17    if (cond & 0x4) {
18        flags |= FCMP_UN;
19    }
20    if (cond & 0x8) {
21        flags |= FCMP_GT | FCMP_LT;
22    }
23    return flags;
24}
25
26static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
27{
28    TCGv var, src1, src2;
29    uint32_t flags;
30    void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
31
32    if (!avail_FP_SP(ctx)) {
33        return false;
34    }
35
36    CHECK_FPE;
37
38    var = tcg_temp_new();
39    src1 = get_fpr(ctx, a->fj);
40    src2 = get_fpr(ctx, a->fk);
41    fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
42    flags = get_fcmp_flags(a->fcond >> 1);
43
44    fn(var, tcg_env, src1, src2, tcg_constant_i32(flags));
45
46    tcg_gen_st8_tl(var, tcg_env, offsetof(CPULoongArchState, cf[a->cd]));
47    return true;
48}
49
50static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
51{
52    TCGv var, src1, src2;
53    uint32_t flags;
54    void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
55
56    if (!avail_FP_DP(ctx)) {
57        return false;
58    }
59
60    CHECK_FPE;
61
62    var = tcg_temp_new();
63    src1 = get_fpr(ctx, a->fj);
64    src2 = get_fpr(ctx, a->fk);
65    fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
66    flags = get_fcmp_flags(a->fcond >> 1);
67
68    fn(var, tcg_env, src1, src2, tcg_constant_i32(flags));
69
70    tcg_gen_st8_tl(var, tcg_env, offsetof(CPULoongArchState, cf[a->cd]));
71    return true;
72}
73