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 gen_rr(DisasContext *ctx, arg_rr *a, 7*5c23704eSSong Gao DisasExtend src_ext, DisasExtend dst_ext, 8*5c23704eSSong Gao void (*func)(TCGv, TCGv)) 9*5c23704eSSong Gao{ 10*5c23704eSSong Gao TCGv dest = gpr_dst(ctx, a->rd, dst_ext); 11*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, src_ext); 12*5c23704eSSong Gao 13*5c23704eSSong Gao func(dest, src1); 14*5c23704eSSong Gao gen_set_gpr(a->rd, dest, dst_ext); 15*5c23704eSSong Gao 16*5c23704eSSong Gao return true; 17*5c23704eSSong Gao} 18*5c23704eSSong Gao 19*5c23704eSSong Gaostatic void gen_bytepick_w(TCGv dest, TCGv src1, TCGv src2, target_long sa) 20*5c23704eSSong Gao{ 21*5c23704eSSong Gao tcg_gen_concat_tl_i64(dest, src1, src2); 22*5c23704eSSong Gao tcg_gen_sextract_i64(dest, dest, (32 - sa * 8), 32); 23*5c23704eSSong Gao} 24*5c23704eSSong Gao 25*5c23704eSSong Gaostatic void gen_bytepick_d(TCGv dest, TCGv src1, TCGv src2, target_long sa) 26*5c23704eSSong Gao{ 27*5c23704eSSong Gao tcg_gen_extract2_i64(dest, src1, src2, (64 - sa * 8)); 28*5c23704eSSong Gao} 29*5c23704eSSong Gao 30*5c23704eSSong Gaostatic bool gen_bstrins(DisasContext *ctx, arg_rr_ms_ls *a, 31*5c23704eSSong Gao DisasExtend dst_ext) 32*5c23704eSSong Gao{ 33*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rd, EXT_NONE); 34*5c23704eSSong Gao TCGv src2 = gpr_src(ctx, a->rj, EXT_NONE); 35*5c23704eSSong Gao TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); 36*5c23704eSSong Gao 37*5c23704eSSong Gao if (a->ls > a->ms) { 38*5c23704eSSong Gao return false; 39*5c23704eSSong Gao } 40*5c23704eSSong Gao 41*5c23704eSSong Gao tcg_gen_deposit_tl(dest, src1, src2, a->ls, a->ms - a->ls + 1); 42*5c23704eSSong Gao gen_set_gpr(a->rd, dest, dst_ext); 43*5c23704eSSong Gao return true; 44*5c23704eSSong Gao} 45*5c23704eSSong Gao 46*5c23704eSSong Gaostatic bool gen_bstrpick(DisasContext *ctx, arg_rr_ms_ls *a, 47*5c23704eSSong Gao DisasExtend dst_ext) 48*5c23704eSSong Gao{ 49*5c23704eSSong Gao TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); 50*5c23704eSSong Gao TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); 51*5c23704eSSong Gao 52*5c23704eSSong Gao if (a->ls > a->ms) { 53*5c23704eSSong Gao return false; 54*5c23704eSSong Gao } 55*5c23704eSSong Gao 56*5c23704eSSong Gao tcg_gen_extract_tl(dest, src1, a->ls, a->ms - a->ls + 1); 57*5c23704eSSong Gao gen_set_gpr(a->rd, dest, dst_ext); 58*5c23704eSSong Gao return true; 59*5c23704eSSong Gao} 60*5c23704eSSong Gao 61*5c23704eSSong Gaostatic void gen_clz_w(TCGv dest, TCGv src1) 62*5c23704eSSong Gao{ 63*5c23704eSSong Gao tcg_gen_clzi_tl(dest, src1, TARGET_LONG_BITS); 64*5c23704eSSong Gao tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32); 65*5c23704eSSong Gao} 66*5c23704eSSong Gao 67*5c23704eSSong Gaostatic void gen_clo_w(TCGv dest, TCGv src1) 68*5c23704eSSong Gao{ 69*5c23704eSSong Gao tcg_gen_not_tl(dest, src1); 70*5c23704eSSong Gao tcg_gen_ext32u_tl(dest, dest); 71*5c23704eSSong Gao gen_clz_w(dest, dest); 72*5c23704eSSong Gao} 73*5c23704eSSong Gao 74*5c23704eSSong Gaostatic void gen_ctz_w(TCGv dest, TCGv src1) 75*5c23704eSSong Gao{ 76*5c23704eSSong Gao tcg_gen_ori_tl(dest, src1, (target_ulong)MAKE_64BIT_MASK(32, 32)); 77*5c23704eSSong Gao tcg_gen_ctzi_tl(dest, dest, TARGET_LONG_BITS); 78*5c23704eSSong Gao} 79*5c23704eSSong Gao 80*5c23704eSSong Gaostatic void gen_cto_w(TCGv dest, TCGv src1) 81*5c23704eSSong Gao{ 82*5c23704eSSong Gao tcg_gen_not_tl(dest, src1); 83*5c23704eSSong Gao gen_ctz_w(dest, dest); 84*5c23704eSSong Gao} 85*5c23704eSSong Gao 86*5c23704eSSong Gaostatic void gen_clz_d(TCGv dest, TCGv src1) 87*5c23704eSSong Gao{ 88*5c23704eSSong Gao tcg_gen_clzi_i64(dest, src1, TARGET_LONG_BITS); 89*5c23704eSSong Gao} 90*5c23704eSSong Gao 91*5c23704eSSong Gaostatic void gen_clo_d(TCGv dest, TCGv src1) 92*5c23704eSSong Gao{ 93*5c23704eSSong Gao tcg_gen_not_tl(dest, src1); 94*5c23704eSSong Gao gen_clz_d(dest, dest); 95*5c23704eSSong Gao} 96*5c23704eSSong Gao 97*5c23704eSSong Gaostatic void gen_ctz_d(TCGv dest, TCGv src1) 98*5c23704eSSong Gao{ 99*5c23704eSSong Gao tcg_gen_ctzi_tl(dest, src1, TARGET_LONG_BITS); 100*5c23704eSSong Gao} 101*5c23704eSSong Gao 102*5c23704eSSong Gaostatic void gen_cto_d(TCGv dest, TCGv src1) 103*5c23704eSSong Gao{ 104*5c23704eSSong Gao tcg_gen_not_tl(dest, src1); 105*5c23704eSSong Gao gen_ctz_d(dest, dest); 106*5c23704eSSong Gao} 107*5c23704eSSong Gao 108*5c23704eSSong Gaostatic void gen_revb_2w(TCGv dest, TCGv src1) 109*5c23704eSSong Gao{ 110*5c23704eSSong Gao tcg_gen_bswap64_i64(dest, src1); 111*5c23704eSSong Gao tcg_gen_rotri_i64(dest, dest, 32); 112*5c23704eSSong Gao} 113*5c23704eSSong Gao 114*5c23704eSSong Gaostatic void gen_revb_2h(TCGv dest, TCGv src1) 115*5c23704eSSong Gao{ 116*5c23704eSSong Gao TCGv mask = tcg_constant_tl(0x00FF00FF); 117*5c23704eSSong Gao TCGv t0 = tcg_temp_new(); 118*5c23704eSSong Gao TCGv t1 = tcg_temp_new(); 119*5c23704eSSong Gao 120*5c23704eSSong Gao tcg_gen_shri_tl(t0, src1, 8); 121*5c23704eSSong Gao tcg_gen_and_tl(t0, t0, mask); 122*5c23704eSSong Gao tcg_gen_and_tl(t1, src1, mask); 123*5c23704eSSong Gao tcg_gen_shli_tl(t1, t1, 8); 124*5c23704eSSong Gao tcg_gen_or_tl(dest, t0, t1); 125*5c23704eSSong Gao} 126*5c23704eSSong Gao 127*5c23704eSSong Gaostatic void gen_revb_4h(TCGv dest, TCGv src1) 128*5c23704eSSong Gao{ 129*5c23704eSSong Gao TCGv mask = tcg_constant_tl(0x00FF00FF00FF00FFULL); 130*5c23704eSSong Gao TCGv t0 = tcg_temp_new(); 131*5c23704eSSong Gao TCGv t1 = tcg_temp_new(); 132*5c23704eSSong Gao 133*5c23704eSSong Gao tcg_gen_shri_tl(t0, src1, 8); 134*5c23704eSSong Gao tcg_gen_and_tl(t0, t0, mask); 135*5c23704eSSong Gao tcg_gen_and_tl(t1, src1, mask); 136*5c23704eSSong Gao tcg_gen_shli_tl(t1, t1, 8); 137*5c23704eSSong Gao tcg_gen_or_tl(dest, t0, t1); 138*5c23704eSSong Gao} 139*5c23704eSSong Gao 140*5c23704eSSong Gaostatic void gen_revh_2w(TCGv dest, TCGv src1) 141*5c23704eSSong Gao{ 142*5c23704eSSong Gao TCGv_i64 t0 = tcg_temp_new_i64(); 143*5c23704eSSong Gao TCGv_i64 t1 = tcg_temp_new_i64(); 144*5c23704eSSong Gao TCGv_i64 mask = tcg_constant_i64(0x0000ffff0000ffffull); 145*5c23704eSSong Gao 146*5c23704eSSong Gao tcg_gen_shri_i64(t0, src1, 16); 147*5c23704eSSong Gao tcg_gen_and_i64(t1, src1, mask); 148*5c23704eSSong Gao tcg_gen_and_i64(t0, t0, mask); 149*5c23704eSSong Gao tcg_gen_shli_i64(t1, t1, 16); 150*5c23704eSSong Gao tcg_gen_or_i64(dest, t1, t0); 151*5c23704eSSong Gao} 152*5c23704eSSong Gao 153*5c23704eSSong Gaostatic void gen_revh_d(TCGv dest, TCGv src1) 154*5c23704eSSong Gao{ 155*5c23704eSSong Gao TCGv t0 = tcg_temp_new(); 156*5c23704eSSong Gao TCGv t1 = tcg_temp_new(); 157*5c23704eSSong Gao TCGv mask = tcg_constant_tl(0x0000FFFF0000FFFFULL); 158*5c23704eSSong Gao 159*5c23704eSSong Gao tcg_gen_shri_tl(t1, src1, 16); 160*5c23704eSSong Gao tcg_gen_and_tl(t1, t1, mask); 161*5c23704eSSong Gao tcg_gen_and_tl(t0, src1, mask); 162*5c23704eSSong Gao tcg_gen_shli_tl(t0, t0, 16); 163*5c23704eSSong Gao tcg_gen_or_tl(t0, t0, t1); 164*5c23704eSSong Gao tcg_gen_rotri_tl(dest, t0, 32); 165*5c23704eSSong Gao} 166*5c23704eSSong Gao 167*5c23704eSSong Gaostatic void gen_maskeqz(TCGv dest, TCGv src1, TCGv src2) 168*5c23704eSSong Gao{ 169*5c23704eSSong Gao TCGv zero = tcg_constant_tl(0); 170*5c23704eSSong Gao 171*5c23704eSSong Gao tcg_gen_movcond_tl(TCG_COND_EQ, dest, src2, zero, zero, src1); 172*5c23704eSSong Gao} 173*5c23704eSSong Gao 174*5c23704eSSong Gaostatic void gen_masknez(TCGv dest, TCGv src1, TCGv src2) 175*5c23704eSSong Gao{ 176*5c23704eSSong Gao TCGv zero = tcg_constant_tl(0); 177*5c23704eSSong Gao 178*5c23704eSSong Gao tcg_gen_movcond_tl(TCG_COND_NE, dest, src2, zero, zero, src1); 179*5c23704eSSong Gao} 180*5c23704eSSong Gao 181*5c23704eSSong GaoTRANS(ext_w_h, ALL, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext16s_tl) 182*5c23704eSSong GaoTRANS(ext_w_b, ALL, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext8s_tl) 183*5c23704eSSong GaoTRANS(clo_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_clo_w) 184*5c23704eSSong GaoTRANS(clz_w, ALL, gen_rr, EXT_ZERO, EXT_NONE, gen_clz_w) 185*5c23704eSSong GaoTRANS(cto_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_cto_w) 186*5c23704eSSong GaoTRANS(ctz_w, ALL, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_w) 187*5c23704eSSong GaoTRANS(clo_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_clo_d) 188*5c23704eSSong GaoTRANS(clz_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_clz_d) 189*5c23704eSSong GaoTRANS(cto_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_cto_d) 190*5c23704eSSong GaoTRANS(ctz_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_d) 191*5c23704eSSong GaoTRANS(revb_2h, ALL, gen_rr, EXT_NONE, EXT_SIGN, gen_revb_2h) 192*5c23704eSSong GaoTRANS(revb_4h, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revb_4h) 193*5c23704eSSong GaoTRANS(revb_2w, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revb_2w) 194*5c23704eSSong GaoTRANS(revb_d, 64, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_bswap64_i64) 195*5c23704eSSong GaoTRANS(revh_2w, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revh_2w) 196*5c23704eSSong GaoTRANS(revh_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_revh_d) 197*5c23704eSSong GaoTRANS(bitrev_4b, ALL, gen_rr, EXT_ZERO, EXT_SIGN, gen_helper_bitswap) 198*5c23704eSSong GaoTRANS(bitrev_8b, 64, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitswap) 199*5c23704eSSong GaoTRANS(bitrev_w, ALL, gen_rr, EXT_NONE, EXT_SIGN, gen_helper_bitrev_w) 200*5c23704eSSong GaoTRANS(bitrev_d, 64, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitrev_d) 201*5c23704eSSong GaoTRANS(maskeqz, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_maskeqz) 202*5c23704eSSong GaoTRANS(masknez, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_masknez) 203*5c23704eSSong GaoTRANS(bytepick_w, ALL, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_w) 204*5c23704eSSong GaoTRANS(bytepick_d, 64, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_bytepick_d) 205*5c23704eSSong GaoTRANS(bstrins_w, ALL, gen_bstrins, EXT_SIGN) 206*5c23704eSSong GaoTRANS(bstrins_d, 64, gen_bstrins, EXT_NONE) 207*5c23704eSSong GaoTRANS(bstrpick_w, ALL, gen_bstrpick, EXT_SIGN) 208*5c23704eSSong GaoTRANS(bstrpick_d, 64, gen_bstrpick, EXT_NONE) 209