1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (c) 2021 Loongson Technology Corporation Limited
4 */
5
6static bool trans_break(DisasContext *ctx, arg_break *a)
7{
8    generate_exception(ctx, EXCCODE_BRK);
9    return true;
10}
11
12static bool trans_syscall(DisasContext *ctx, arg_syscall *a)
13{
14    generate_exception(ctx, EXCCODE_SYS);
15    return true;
16}
17
18static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a)
19{
20    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
21    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
22
23    if (!avail_64(ctx)) {
24        return false;
25    }
26
27    gen_helper_asrtle_d(tcg_env, src1, src2);
28    return true;
29}
30
31static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a)
32{
33    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
34    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
35
36    if (!avail_64(ctx)) {
37        return false;
38    }
39
40    gen_helper_asrtgt_d(tcg_env, src1, src2);
41    return true;
42}
43
44static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
45                       bool word, bool high)
46{
47    TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE);
48    TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE);
49
50    translator_io_start(&ctx->base);
51    gen_helper_rdtime_d(dst1, tcg_env);
52    if (word) {
53        tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
54    }
55    tcg_gen_ld_i64(dst2, tcg_env, offsetof(CPULoongArchState, CSR_TID));
56
57    return true;
58}
59
60static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a)
61{
62    return gen_rdtime(ctx, a, 1, 0);
63}
64
65static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
66{
67    return gen_rdtime(ctx, a, 1, 1);
68}
69
70static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
71{
72    return gen_rdtime(ctx, a, 0, 0);
73}
74
75static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
76{
77    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
78    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
79
80    gen_helper_cpucfg(dest, tcg_env, src1);
81    gen_set_gpr(a->rd, dest, EXT_NONE);
82
83    return true;
84}
85
86static bool gen_crc(DisasContext *ctx, arg_rrr *a,
87                    void (*func)(TCGv, TCGv, TCGv, TCGv),
88                    TCGv tsz)
89{
90    TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN);
91    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
92    TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
93
94    func(dest, src2, src1, tsz);
95    gen_set_gpr(a->rd, dest, EXT_SIGN);
96
97    return true;
98}
99
100TRANS(crc_w_b_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
101TRANS(crc_w_h_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
102TRANS(crc_w_w_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
103TRANS(crc_w_d_w, 64, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
104TRANS(crcc_w_b_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
105TRANS(crcc_w_h_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
106TRANS(crcc_w_w_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
107TRANS(crcc_w_d_w, 64, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
108