mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 15:34:56 +00:00 
			
		
		
		
	target/arm: Implement SVE Index Generation Group
Backports commit 9a56c9c3a955b77fe436beef7ac03c76a65fa32d from qemu
This commit is contained in:
		
							parent
							
								
									390bd68287
								
							
						
					
					
						commit
						45a09e2f25
					
				| 
						 | 
					@ -3346,6 +3346,10 @@
 | 
				
			||||||
#define helper_sve_fneg_d helper_sve_fneg_d_aarch64
 | 
					#define helper_sve_fneg_d helper_sve_fneg_d_aarch64
 | 
				
			||||||
#define helper_sve_fneg_h helper_sve_fneg_h_aarch64
 | 
					#define helper_sve_fneg_h helper_sve_fneg_h_aarch64
 | 
				
			||||||
#define helper_sve_fneg_s helper_sve_fneg_s_aarch64
 | 
					#define helper_sve_fneg_s helper_sve_fneg_s_aarch64
 | 
				
			||||||
 | 
					#define helper_sve_index_b helper_sve_index_b_aarch64
 | 
				
			||||||
 | 
					#define helper_sve_index_d helper_sve_index_d_aarch64
 | 
				
			||||||
 | 
					#define helper_sve_index_h helper_sve_index_h_aarch64
 | 
				
			||||||
 | 
					#define helper_sve_index_s helper_sve_index_s_aarch64
 | 
				
			||||||
#define helper_sve_lsl_zpzi_b helper_sve_lsl_zpzi_b_aarch64
 | 
					#define helper_sve_lsl_zpzi_b helper_sve_lsl_zpzi_b_aarch64
 | 
				
			||||||
#define helper_sve_lsl_zpzi_d helper_sve_lsl_zpzi_d_aarch64
 | 
					#define helper_sve_lsl_zpzi_d helper_sve_lsl_zpzi_d_aarch64
 | 
				
			||||||
#define helper_sve_lsl_zpzi_h helper_sve_lsl_zpzi_h_aarch64
 | 
					#define helper_sve_lsl_zpzi_h helper_sve_lsl_zpzi_h_aarch64
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3346,6 +3346,10 @@
 | 
				
			||||||
#define helper_sve_fneg_d helper_sve_fneg_d_aarch64eb
 | 
					#define helper_sve_fneg_d helper_sve_fneg_d_aarch64eb
 | 
				
			||||||
#define helper_sve_fneg_h helper_sve_fneg_h_aarch64eb
 | 
					#define helper_sve_fneg_h helper_sve_fneg_h_aarch64eb
 | 
				
			||||||
#define helper_sve_fneg_s helper_sve_fneg_s_aarch64eb
 | 
					#define helper_sve_fneg_s helper_sve_fneg_s_aarch64eb
 | 
				
			||||||
 | 
					#define helper_sve_index_b helper_sve_index_b_aarch64eb
 | 
				
			||||||
 | 
					#define helper_sve_index_d helper_sve_index_d_aarch64eb
 | 
				
			||||||
 | 
					#define helper_sve_index_h helper_sve_index_h_aarch64eb
 | 
				
			||||||
 | 
					#define helper_sve_index_s helper_sve_index_s_aarch64eb
 | 
				
			||||||
#define helper_sve_lsl_zpzi_b helper_sve_lsl_zpzi_b_aarch64eb
 | 
					#define helper_sve_lsl_zpzi_b helper_sve_lsl_zpzi_b_aarch64eb
 | 
				
			||||||
#define helper_sve_lsl_zpzi_d helper_sve_lsl_zpzi_d_aarch64eb
 | 
					#define helper_sve_lsl_zpzi_d helper_sve_lsl_zpzi_d_aarch64eb
 | 
				
			||||||
#define helper_sve_lsl_zpzi_h helper_sve_lsl_zpzi_h_aarch64eb
 | 
					#define helper_sve_lsl_zpzi_h helper_sve_lsl_zpzi_h_aarch64eb
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3367,6 +3367,10 @@ aarch64_symbols = (
 | 
				
			||||||
    'helper_sve_fneg_d',
 | 
					    'helper_sve_fneg_d',
 | 
				
			||||||
    'helper_sve_fneg_h',
 | 
					    'helper_sve_fneg_h',
 | 
				
			||||||
    'helper_sve_fneg_s',
 | 
					    'helper_sve_fneg_s',
 | 
				
			||||||
 | 
					    'helper_sve_index_b',
 | 
				
			||||||
 | 
					    'helper_sve_index_d',
 | 
				
			||||||
 | 
					    'helper_sve_index_h',
 | 
				
			||||||
 | 
					    'helper_sve_index_s',
 | 
				
			||||||
    'helper_sve_lsl_zpzi_b',
 | 
					    'helper_sve_lsl_zpzi_b',
 | 
				
			||||||
    'helper_sve_lsl_zpzi_d',
 | 
					    'helper_sve_lsl_zpzi_d',
 | 
				
			||||||
    'helper_sve_lsl_zpzi_h',
 | 
					    'helper_sve_lsl_zpzi_h',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -363,6 +363,11 @@ DEF_HELPER_FLAGS_6(sve_mls_s, TCG_CALL_NO_RWG,
 | 
				
			||||||
DEF_HELPER_FLAGS_6(sve_mls_d, TCG_CALL_NO_RWG,
 | 
					DEF_HELPER_FLAGS_6(sve_mls_d, TCG_CALL_NO_RWG,
 | 
				
			||||||
                   void, ptr, ptr, ptr, ptr, ptr, i32)
 | 
					                   void, ptr, ptr, ptr, ptr, ptr, i32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_FLAGS_4(sve_index_b, TCG_CALL_NO_RWG, void, ptr, i32, i32, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_FLAGS_4(sve_index_h, TCG_CALL_NO_RWG, void, ptr, i32, i32, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_FLAGS_4(sve_index_s, TCG_CALL_NO_RWG, void, ptr, i32, i32, i32)
 | 
				
			||||||
 | 
					DEF_HELPER_FLAGS_4(sve_index_d, TCG_CALL_NO_RWG, void, ptr, i64, i64, i32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
					DEF_HELPER_FLAGS_5(sve_and_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
				
			||||||
DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
					DEF_HELPER_FLAGS_5(sve_bic_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
				
			||||||
DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
					DEF_HELPER_FLAGS_5(sve_eor_pppp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,6 +224,20 @@ ORR_zzz         00000100 01 1 ..... 001 100 ..... .....         @rd_rn_rm_e0
 | 
				
			||||||
EOR_zzz         00000100 10 1 ..... 001 100 ..... .....         @rd_rn_rm_e0
 | 
					EOR_zzz         00000100 10 1 ..... 001 100 ..... .....         @rd_rn_rm_e0
 | 
				
			||||||
BIC_zzz         00000100 11 1 ..... 001 100 ..... .....         @rd_rn_rm_e0
 | 
					BIC_zzz         00000100 11 1 ..... 001 100 ..... .....         @rd_rn_rm_e0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### SVE Index Generation Group
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SVE index generation (immediate start, immediate increment)
 | 
				
			||||||
 | 
					INDEX_ii        00000100 esz:2 1 imm2:s5 010000 imm1:s5 rd:5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SVE index generation (immediate start, register increment)
 | 
				
			||||||
 | 
					INDEX_ir        00000100 esz:2 1 rm:5 010010 imm:s5 rd:5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SVE index generation (register start, immediate increment)
 | 
				
			||||||
 | 
					INDEX_ri        00000100 esz:2 1 imm:s5 010001 rn:5 rd:5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SVE index generation (register start, register increment)
 | 
				
			||||||
 | 
					INDEX_rr        00000100 .. 1 ..... 010011 ..... .....          @rd_rn_rm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### SVE Predicate Logical Operations Group
 | 
					### SVE Predicate Logical Operations Group
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SVE predicate logical operations
 | 
					# SVE predicate logical operations
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -991,3 +991,43 @@ DO_ZPZZZ_D(sve_mls_d, uint64_t, DO_MLS)
 | 
				
			||||||
#undef DO_MLS
 | 
					#undef DO_MLS
 | 
				
			||||||
#undef DO_ZPZZZ
 | 
					#undef DO_ZPZZZ
 | 
				
			||||||
#undef DO_ZPZZZ_D
 | 
					#undef DO_ZPZZZ_D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(sve_index_b)(void *vd, uint32_t start,
 | 
				
			||||||
 | 
					                         uint32_t incr, uint32_t desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    intptr_t i, opr_sz = simd_oprsz(desc);
 | 
				
			||||||
 | 
					    uint8_t *d = vd;
 | 
				
			||||||
 | 
					    for (i = 0; i < opr_sz; i += 1) {
 | 
				
			||||||
 | 
					        d[H1(i)] = start + i * incr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(sve_index_h)(void *vd, uint32_t start,
 | 
				
			||||||
 | 
					                         uint32_t incr, uint32_t desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    intptr_t i, opr_sz = simd_oprsz(desc) / 2;
 | 
				
			||||||
 | 
					    uint16_t *d = vd;
 | 
				
			||||||
 | 
					    for (i = 0; i < opr_sz; i += 1) {
 | 
				
			||||||
 | 
					        d[H2(i)] = start + i * incr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(sve_index_s)(void *vd, uint32_t start,
 | 
				
			||||||
 | 
					                         uint32_t incr, uint32_t desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    intptr_t i, opr_sz = simd_oprsz(desc) / 4;
 | 
				
			||||||
 | 
					    uint32_t *d = vd;
 | 
				
			||||||
 | 
					    for (i = 0; i < opr_sz; i += 1) {
 | 
				
			||||||
 | 
					        d[H4(i)] = start + i * incr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(sve_index_d)(void *vd, uint64_t start,
 | 
				
			||||||
 | 
					                         uint64_t incr, uint32_t desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    intptr_t i, opr_sz = simd_oprsz(desc) / 8;
 | 
				
			||||||
 | 
					    uint64_t *d = vd;
 | 
				
			||||||
 | 
					    for (i = 0; i < opr_sz; i += 1) {
 | 
				
			||||||
 | 
					        d[i] = start + i * incr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -713,6 +713,89 @@ DO_ZPZZZ(MLS, mls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef DO_ZPZZZ
 | 
					#undef DO_ZPZZZ
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *** SVE Index Generation Group
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void do_index(DisasContext *s, int esz, int rd,
 | 
				
			||||||
 | 
					                     TCGv_i64 start, TCGv_i64 incr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
				
			||||||
 | 
					    unsigned vsz = vec_full_reg_size(s);
 | 
				
			||||||
 | 
					    TCGv_i32 desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0));
 | 
				
			||||||
 | 
					    TCGv_ptr t_zd = tcg_temp_new_ptr(tcg_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tcg_gen_addi_ptr(tcg_ctx, t_zd, tcg_ctx->cpu_env, vec_full_reg_offset(s, rd));
 | 
				
			||||||
 | 
					    if (esz == 3) {
 | 
				
			||||||
 | 
					        gen_helper_sve_index_d(tcg_ctx, t_zd, start, incr, desc);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        typedef void index_fn(TCGContext *, TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
 | 
				
			||||||
 | 
					        static index_fn * const fns[3] = {
 | 
				
			||||||
 | 
					            gen_helper_sve_index_b,
 | 
				
			||||||
 | 
					            gen_helper_sve_index_h,
 | 
				
			||||||
 | 
					            gen_helper_sve_index_s,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        TCGv_i32 s32 = tcg_temp_new_i32(tcg_ctx);
 | 
				
			||||||
 | 
					        TCGv_i32 i32 = tcg_temp_new_i32(tcg_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tcg_gen_extrl_i64_i32(tcg_ctx, s32, start);
 | 
				
			||||||
 | 
					        tcg_gen_extrl_i64_i32(tcg_ctx, i32, incr);
 | 
				
			||||||
 | 
					        fns[esz](tcg_ctx, t_zd, s32, i32, desc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(tcg_ctx, s32);
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(tcg_ctx, i32);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    tcg_temp_free_ptr(tcg_ctx, t_zd);
 | 
				
			||||||
 | 
					    tcg_temp_free_i32(tcg_ctx, desc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool trans_INDEX_ii(DisasContext *s, arg_INDEX_ii *a, uint32_t insn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (sve_access_check(s)) {
 | 
				
			||||||
 | 
					        TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
				
			||||||
 | 
					        TCGv_i64 start = tcg_const_i64(tcg_ctx, a->imm1);
 | 
				
			||||||
 | 
					        TCGv_i64 incr = tcg_const_i64(tcg_ctx, a->imm2);
 | 
				
			||||||
 | 
					        do_index(s, a->esz, a->rd, start, incr);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(tcg_ctx, start);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(tcg_ctx, incr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool trans_INDEX_ir(DisasContext *s, arg_INDEX_ir *a, uint32_t insn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (sve_access_check(s)) {
 | 
				
			||||||
 | 
					        TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
				
			||||||
 | 
					        TCGv_i64 start = tcg_const_i64(tcg_ctx, a->imm);
 | 
				
			||||||
 | 
					        TCGv_i64 incr = cpu_reg(s, a->rm);
 | 
				
			||||||
 | 
					        do_index(s, a->esz, a->rd, start, incr);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(tcg_ctx, start);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool trans_INDEX_ri(DisasContext *s, arg_INDEX_ri *a, uint32_t insn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (sve_access_check(s)) {
 | 
				
			||||||
 | 
					        TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
				
			||||||
 | 
					        TCGv_i64 start = cpu_reg(s, a->rn);
 | 
				
			||||||
 | 
					        TCGv_i64 incr = tcg_const_i64(tcg_ctx, a->imm);
 | 
				
			||||||
 | 
					        do_index(s, a->esz, a->rd, start, incr);
 | 
				
			||||||
 | 
					        tcg_temp_free_i64(tcg_ctx, incr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool trans_INDEX_rr(DisasContext *s, arg_INDEX_rr *a, uint32_t insn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (sve_access_check(s)) {
 | 
				
			||||||
 | 
					        TCGv_i64 start = cpu_reg(s, a->rn);
 | 
				
			||||||
 | 
					        TCGv_i64 incr = cpu_reg(s, a->rm);
 | 
				
			||||||
 | 
					        do_index(s, a->esz, a->rd, start, incr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *** SVE Predicate Logical Operations Group
 | 
					 *** SVE Predicate Logical Operations Group
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue