Lines Matching +full:- +full:a
2 * RISC-V translation routines for the T-Head vendor extensions (xthead*).
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
20 if (!ctx->cfg_ptr->ext_xtheadba) { \
26 if (!ctx->cfg_ptr->ext_xtheadbb) { \
32 if (!ctx->cfg_ptr->ext_xtheadbs) { \
38 if (!ctx->cfg_ptr->ext_xtheadcmo) { \
44 if (!ctx->cfg_ptr->ext_xtheadcondmov) { \
50 if (!ctx->cfg_ptr->ext_xtheadfmemidx) { \
56 if (!ctx->cfg_ptr->ext_xtheadfmv) { \
62 if (!ctx->cfg_ptr->ext_xtheadmac) { \
68 if (!ctx->cfg_ptr->ext_xtheadmemidx) { \
74 if (!ctx->cfg_ptr->ext_xtheadmempair) { \
80 if (!ctx->cfg_ptr->ext_xtheadsync) { \
128 arg_th_addsl##SHAMT * a) \
131 return gen_arith(ctx, a, EXT_NONE, gen_th_addsl##SHAMT, NULL); \
141 static bool trans_th_srri(DisasContext *ctx, arg_th_srri * a)
144 return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
149 static bool trans_th_srriw(DisasContext *ctx, arg_th_srriw *a)
153 ctx->ol = MXL_RV32;
154 return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
158 static bool gen_th_bfextract(DisasContext *ctx, arg_th_bfext *a,
161 TCGv dest = dest_gpr(ctx, a->rd);
162 TCGv source = get_gpr(ctx, a->rs1, EXT_ZERO);
164 if (a->lsb <= a->msb) {
165 f(dest, source, a->lsb, a->msb - a->lsb + 1);
166 gen_set_gpr(ctx, a->rd, dest);
171 static bool trans_th_ext(DisasContext *ctx, arg_th_ext *a)
174 return gen_th_bfextract(ctx, a, tcg_gen_sextract_tl);
177 static bool trans_th_extu(DisasContext *ctx, arg_th_extu *a)
180 return gen_th_bfextract(ctx, a, tcg_gen_extract_tl);
184 static bool gen_th_ff0(DisasContext *ctx, arg_th_ff0 *a, DisasExtend ext)
186 TCGv dest = dest_gpr(ctx, a->rd);
187 TCGv src1 = get_gpr(ctx, a->rs1, ext);
203 gen_set_gpr(ctx, a->rd, dest);
208 static bool trans_th_ff0(DisasContext *ctx, arg_th_ff0 *a)
211 return gen_th_ff0(ctx, a, EXT_NONE);
215 static bool trans_th_ff1(DisasContext *ctx, arg_th_ff1 *a)
218 return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
227 static bool trans_th_rev(DisasContext *ctx, arg_th_rev *a)
231 return gen_unary_per_ol(ctx, a, EXT_NONE, tcg_gen_bswap_tl, gen_th_revw);
234 /* th.revw is a sign-extended byte-swap of the lower word */
235 static bool trans_th_revw(DisasContext *ctx, arg_th_revw *a)
239 return gen_unary(ctx, a, EXT_NONE, gen_th_revw);
249 static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
252 return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
258 static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
261 return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
272 if (ctx->priv == PRV_U) { \
278 static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
280 (void) a; \
312 static bool gen_th_condmove(DisasContext *ctx, arg_r *a, TCGCond cond)
314 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
315 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
316 TCGv old = get_gpr(ctx, a->rd, EXT_NONE);
317 TCGv dest = dest_gpr(ctx, a->rd);
319 tcg_gen_movcond_tl(cond, dest, src2, ctx->zero, src1, old);
321 gen_set_gpr(ctx, a->rd, dest);
326 static bool trans_th_mveqz(DisasContext *ctx, arg_th_mveqz *a)
329 return gen_th_condmove(ctx, a, TCG_COND_EQ);
333 static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
336 return gen_th_condmove(ctx, a, TCG_COND_NE);
342 * Load 64-bit float from indexed address.
346 static bool gen_fload_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
349 TCGv_i64 rd = cpu_fpr[a->rd];
350 TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
352 tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop);
362 * Store 64-bit float to indexed address.
366 static bool gen_fstore_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
369 TCGv_i64 rd = cpu_fpr[a->rd];
370 TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
372 tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop);
377 static bool trans_th_flrd(DisasContext *ctx, arg_th_memidx *a)
382 return gen_fload_idx(ctx, a, MO_TEUQ, false);
385 static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a)
390 return gen_fload_idx(ctx, a, MO_TEUL, false);
393 static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a)
398 return gen_fload_idx(ctx, a, MO_TEUQ, true);
401 static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a)
406 return gen_fload_idx(ctx, a, MO_TEUL, true);
409 static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a)
414 return gen_fstore_idx(ctx, a, MO_TEUQ, false);
417 static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a)
422 return gen_fstore_idx(ctx, a, MO_TEUL, false);
425 static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a)
430 return gen_fstore_idx(ctx, a, MO_TEUQ, true);
433 static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a)
438 return gen_fstore_idx(ctx, a, MO_TEUL, true);
443 static bool trans_th_fmv_hw_x(DisasContext *ctx, arg_th_fmv_hw_x *a)
450 TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
454 tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], t1, 32, 32);
459 static bool trans_th_fmv_x_hw(DisasContext *ctx, arg_th_fmv_x_hw *a)
468 dst = dest_gpr(ctx, a->rd);
471 tcg_gen_extract_i64(t1, cpu_fpr[a->rs1], 32, 32);
473 gen_set_gpr(ctx, a->rd, dst);
480 static bool gen_th_mac(DisasContext *ctx, arg_r *a,
484 TCGv dest = dest_gpr(ctx, a->rd);
485 TCGv src0 = get_gpr(ctx, a->rd, EXT_NONE);
486 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
487 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
500 gen_set_gpr(ctx, a->rd, dest);
505 static bool trans_th_mula(DisasContext *ctx, arg_th_mula *a)
508 return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
512 static bool trans_th_mulah(DisasContext *ctx, arg_th_mulah *a)
515 ctx->ol = MXL_RV32;
516 return gen_th_mac(ctx, a, tcg_gen_add_tl, tcg_gen_ext16s_tl);
520 static bool trans_th_mulaw(DisasContext *ctx, arg_th_mulaw *a)
524 ctx->ol = MXL_RV32;
525 return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
528 /* th.muls: "rd = rd - rs1 * rs2" */
529 static bool trans_th_muls(DisasContext *ctx, arg_th_muls *a)
532 return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
535 /* th.mulsh: "rd = sext.w(rd - sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
536 static bool trans_th_mulsh(DisasContext *ctx, arg_th_mulsh *a)
539 ctx->ol = MXL_RV32;
540 return gen_th_mac(ctx, a, tcg_gen_sub_tl, tcg_gen_ext16s_tl);
543 /* th.mulsw: "rd = sext.w(rd - rs1 * rs2)" */
544 static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
548 ctx->ol = MXL_RV32;
549 return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
559 static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
562 if (a->rs1 == a->rd) {
566 int imm = a->imm5 << a->imm2;
567 TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
568 TCGv rd = dest_gpr(ctx, a->rd);
569 TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
571 tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
573 gen_set_gpr(ctx, a->rd, rd);
574 gen_set_gpr(ctx, a->rs1, rs1);
583 static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
586 int imm = a->imm5 << a->imm2;
587 TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
588 TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
589 TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
591 tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
593 gen_set_gpr(ctx, a->rs1, rs1);
597 static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a)
601 return gen_load_inc(ctx, a, MO_TESQ, false);
604 static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a)
608 return gen_load_inc(ctx, a, MO_TESQ, true);
611 static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a)
614 return gen_load_inc(ctx, a, MO_TESL, false);
617 static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a)
620 return gen_load_inc(ctx, a, MO_TESL, true);
623 static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a)
627 return gen_load_inc(ctx, a, MO_TEUL, false);
630 static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a)
634 return gen_load_inc(ctx, a, MO_TEUL, true);
637 static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a)
640 return gen_load_inc(ctx, a, MO_TESW, false);
643 static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a)
646 return gen_load_inc(ctx, a, MO_TESW, true);
649 static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a)
652 return gen_load_inc(ctx, a, MO_TEUW, false);
655 static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a)
658 return gen_load_inc(ctx, a, MO_TEUW, true);
661 static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a)
664 return gen_load_inc(ctx, a, MO_SB, false);
667 static bool trans_th_lbib(DisasContext *ctx, arg_th_meminc *a)
670 return gen_load_inc(ctx, a, MO_SB, true);
673 static bool trans_th_lbuia(DisasContext *ctx, arg_th_meminc *a)
676 return gen_load_inc(ctx, a, MO_UB, false);
679 static bool trans_th_lbuib(DisasContext *ctx, arg_th_meminc *a)
682 return gen_load_inc(ctx, a, MO_UB, true);
685 static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a)
689 return gen_store_inc(ctx, a, MO_TESQ, false);
692 static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a)
696 return gen_store_inc(ctx, a, MO_TESQ, true);
699 static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a)
702 return gen_store_inc(ctx, a, MO_TESL, false);
705 static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a)
708 return gen_store_inc(ctx, a, MO_TESL, true);
711 static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a)
714 return gen_store_inc(ctx, a, MO_TESW, false);
717 static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a)
720 return gen_store_inc(ctx, a, MO_TESW, true);
723 static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a)
726 return gen_store_inc(ctx, a, MO_SB, false);
729 static bool trans_th_sbib(DisasContext *ctx, arg_th_meminc *a)
732 return gen_store_inc(ctx, a, MO_SB, true);
740 static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
743 TCGv rd = dest_gpr(ctx, a->rd);
744 TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
746 tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
747 gen_set_gpr(ctx, a->rd, rd);
757 static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
760 TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
761 TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
763 tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
768 static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a)
772 return gen_load_idx(ctx, a, MO_TESQ, false);
775 static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a)
778 return gen_load_idx(ctx, a, MO_TESL, false);
781 static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a)
785 return gen_load_idx(ctx, a, MO_TEUL, false);
788 static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a)
791 return gen_load_idx(ctx, a, MO_TESW, false);
794 static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a)
797 return gen_load_idx(ctx, a, MO_TEUW, false);
800 static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a)
803 return gen_load_idx(ctx, a, MO_SB, false);
806 static bool trans_th_lrbu(DisasContext *ctx, arg_th_memidx *a)
809 return gen_load_idx(ctx, a, MO_UB, false);
812 static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a)
816 return gen_store_idx(ctx, a, MO_TESQ, false);
819 static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a)
822 return gen_store_idx(ctx, a, MO_TESL, false);
825 static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a)
828 return gen_store_idx(ctx, a, MO_TESW, false);
831 static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a)
834 return gen_store_idx(ctx, a, MO_SB, false);
836 static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a)
840 return gen_load_idx(ctx, a, MO_TESQ, true);
843 static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a)
846 return gen_load_idx(ctx, a, MO_TESL, true);
849 static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a)
853 return gen_load_idx(ctx, a, MO_TEUL, true);
856 static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a)
859 return gen_load_idx(ctx, a, MO_TESW, true);
862 static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a)
865 return gen_load_idx(ctx, a, MO_TEUW, true);
868 static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a)
871 return gen_load_idx(ctx, a, MO_SB, true);
874 static bool trans_th_lurbu(DisasContext *ctx, arg_th_memidx *a)
877 return gen_load_idx(ctx, a, MO_UB, true);
880 static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a)
884 return gen_store_idx(ctx, a, MO_TESQ, true);
887 static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a)
890 return gen_store_idx(ctx, a, MO_TESL, true);
893 static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a)
896 return gen_store_idx(ctx, a, MO_TESW, true);
899 static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a)
902 return gen_store_idx(ctx, a, MO_SB, true);
907 static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
910 if (a->rs == a->rd1 || a->rs == a->rd2 || a->rd1 == a->rd2) {
918 int imm = a->sh2 << shamt;
920 addr1 = get_address(ctx, a->rs, imm);
921 addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
923 tcg_gen_qemu_ld_tl(t1, addr1, ctx->mem_idx, memop);
924 tcg_gen_qemu_ld_tl(t2, addr2, ctx->mem_idx, memop);
925 gen_set_gpr(ctx, a->rd1, t1);
926 gen_set_gpr(ctx, a->rd2, t2);
930 static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a)
934 return gen_loadpair_tl(ctx, a, MO_TESQ, 4);
937 static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a)
940 return gen_loadpair_tl(ctx, a, MO_TESL, 3);
943 static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a)
946 return gen_loadpair_tl(ctx, a, MO_TEUL, 3);
949 static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
952 TCGv data1 = get_gpr(ctx, a->rd1, EXT_NONE);
953 TCGv data2 = get_gpr(ctx, a->rd2, EXT_NONE);
956 int imm = a->sh2 << shamt;
958 addr1 = get_address(ctx, a->rs, imm);
959 addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
961 tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop);
962 tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop);
966 static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a)
970 return gen_storepair_tl(ctx, a, MO_TESQ, 4);
973 static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a)
976 return gen_storepair_tl(ctx, a, MO_TESL, 3);
981 static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
983 (void) a;
998 * Emulate out-of-order barriers with pipeline flush
1001 gen_update_pc(ctx, ctx->cur_insn_len);
1003 ctx->base.is_jmp = DISAS_NORETURN;
1006 static bool trans_th_sync(DisasContext *ctx, arg_th_sync *a)
1008 (void) a;
1014 * th.sync is an out-of-order barrier.
1021 static bool trans_th_sync_i(DisasContext *ctx, arg_th_sync_i *a)
1023 (void) a;
1036 static bool trans_th_sync_is(DisasContext *ctx, arg_th_sync_is *a)
1039 return trans_th_sync_i(ctx, a);
1042 static bool trans_th_sync_s(DisasContext *ctx, arg_th_sync_s *a)
1045 return trans_th_sync(ctx, a);