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