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 bool trans_b(DisasContext *ctx, arg_b *a)
7*5c23704eSSong Gao{
8*5c23704eSSong Gao    gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
9*5c23704eSSong Gao    ctx->base.is_jmp = DISAS_NORETURN;
10*5c23704eSSong Gao    return true;
11*5c23704eSSong Gao}
12*5c23704eSSong Gao
13*5c23704eSSong Gaostatic bool trans_bl(DisasContext *ctx, arg_bl *a)
14*5c23704eSSong Gao{
15*5c23704eSSong Gao    tcg_gen_movi_tl(cpu_gpr[1], make_address_pc(ctx, ctx->base.pc_next + 4));
16*5c23704eSSong Gao    gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
17*5c23704eSSong Gao    ctx->base.is_jmp = DISAS_NORETURN;
18*5c23704eSSong Gao    return true;
19*5c23704eSSong Gao}
20*5c23704eSSong Gao
21*5c23704eSSong Gaostatic bool trans_jirl(DisasContext *ctx, arg_jirl *a)
22*5c23704eSSong Gao{
23*5c23704eSSong Gao    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
24*5c23704eSSong Gao    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
25*5c23704eSSong Gao
26*5c23704eSSong Gao    TCGv addr = make_address_i(ctx, src1, a->imm);
27*5c23704eSSong Gao    tcg_gen_mov_tl(cpu_pc, addr);
28*5c23704eSSong Gao    tcg_gen_movi_tl(dest, make_address_pc(ctx, ctx->base.pc_next + 4));
29*5c23704eSSong Gao    gen_set_gpr(a->rd, dest, EXT_NONE);
30*5c23704eSSong Gao    tcg_gen_lookup_and_goto_ptr();
31*5c23704eSSong Gao    ctx->base.is_jmp = DISAS_NORETURN;
32*5c23704eSSong Gao    return true;
33*5c23704eSSong Gao}
34*5c23704eSSong Gao
35*5c23704eSSong Gaostatic void gen_bc(DisasContext *ctx, TCGv src1, TCGv src2,
36*5c23704eSSong Gao                   target_long offs, TCGCond cond)
37*5c23704eSSong Gao{
38*5c23704eSSong Gao    TCGLabel *l = gen_new_label();
39*5c23704eSSong Gao    tcg_gen_brcond_tl(cond, src1, src2, l);
40*5c23704eSSong Gao    gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
41*5c23704eSSong Gao    gen_set_label(l);
42*5c23704eSSong Gao    gen_goto_tb(ctx, 0, ctx->base.pc_next + offs);
43*5c23704eSSong Gao    ctx->base.is_jmp = DISAS_NORETURN;
44*5c23704eSSong Gao}
45*5c23704eSSong Gao
46*5c23704eSSong Gaostatic bool gen_rr_bc(DisasContext *ctx, arg_rr_offs *a, TCGCond cond)
47*5c23704eSSong Gao{
48*5c23704eSSong Gao    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
49*5c23704eSSong Gao    TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
50*5c23704eSSong Gao
51*5c23704eSSong Gao    gen_bc(ctx, src1, src2, a->offs, cond);
52*5c23704eSSong Gao    return true;
53*5c23704eSSong Gao}
54*5c23704eSSong Gao
55*5c23704eSSong Gaostatic bool gen_rz_bc(DisasContext *ctx, arg_r_offs *a, TCGCond cond)
56*5c23704eSSong Gao{
57*5c23704eSSong Gao    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
58*5c23704eSSong Gao    TCGv src2 = tcg_constant_tl(0);
59*5c23704eSSong Gao
60*5c23704eSSong Gao    gen_bc(ctx, src1, src2, a->offs, cond);
61*5c23704eSSong Gao    return true;
62*5c23704eSSong Gao}
63*5c23704eSSong Gao
64*5c23704eSSong Gaostatic bool gen_cz_bc(DisasContext *ctx, arg_c_offs *a, TCGCond cond)
65*5c23704eSSong Gao{
66*5c23704eSSong Gao    TCGv src1 = tcg_temp_new();
67*5c23704eSSong Gao    TCGv src2 = tcg_constant_tl(0);
68*5c23704eSSong Gao
69*5c23704eSSong Gao    tcg_gen_ld8u_tl(src1, tcg_env,
70*5c23704eSSong Gao                    offsetof(CPULoongArchState, cf[a->cj]));
71*5c23704eSSong Gao    gen_bc(ctx, src1, src2, a->offs, cond);
72*5c23704eSSong Gao    return true;
73*5c23704eSSong Gao}
74*5c23704eSSong Gao
75*5c23704eSSong GaoTRANS(beq, ALL, gen_rr_bc, TCG_COND_EQ)
76*5c23704eSSong GaoTRANS(bne, ALL, gen_rr_bc, TCG_COND_NE)
77*5c23704eSSong GaoTRANS(blt, ALL, gen_rr_bc, TCG_COND_LT)
78*5c23704eSSong GaoTRANS(bge, ALL, gen_rr_bc, TCG_COND_GE)
79*5c23704eSSong GaoTRANS(bltu, ALL, gen_rr_bc, TCG_COND_LTU)
80*5c23704eSSong GaoTRANS(bgeu, ALL, gen_rr_bc, TCG_COND_GEU)
81*5c23704eSSong GaoTRANS(beqz, ALL, gen_rz_bc, TCG_COND_EQ)
82*5c23704eSSong GaoTRANS(bnez, ALL, gen_rz_bc, TCG_COND_NE)
83*5c23704eSSong GaoTRANS(bceqz, 64, gen_cz_bc, TCG_COND_EQ)
84*5c23704eSSong GaoTRANS(bcnez, 64, gen_cz_bc, TCG_COND_NE)
85