mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 14:14:57 +00:00 
			
		
		
		
	target/arm: Convert Neon VSWP to decodetree
Convert the Neon VSWP insn to decodetree. Since the new implementation doesn't have to share a pass-loop with the other 2-reg-misc operations we can implement the swap with 64-bit accesses rather than 32-bits (which brings us into line with the pseudocode and is more efficient). Backports commit 8ab3a227a0f13f0ff85846f36f7c466769aef4fc from qemu
This commit is contained in:
		
							parent
							
								
									73abdfea53
								
							
						
					
					
						commit
						b7584069dd
					
				| 
						 | 
				
			
			@ -488,6 +488,8 @@ Vimm_1r          1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
 | 
			
		|||
    VABS_F       1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
 | 
			
		||||
    VNEG_F       1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
 | 
			
		||||
 | 
			
		||||
    VSWP         1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
 | 
			
		||||
 | 
			
		||||
    VUZP         1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
 | 
			
		||||
    VZIP         1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3976,3 +3976,45 @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
 | 
			
		|||
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
 | 
			
		||||
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
 | 
			
		||||
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
 | 
			
		||||
 | 
			
		||||
static bool trans_VSWP(DisasContext *s, arg_2misc *a)
 | 
			
		||||
{
 | 
			
		||||
    TCGv_i64 rm, rd;
 | 
			
		||||
    int pass;
 | 
			
		||||
    TCGContext *tcg_ctx = s->uc->tcg_ctx;
 | 
			
		||||
 | 
			
		||||
    if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* UNDEF accesses to D16-D31 if they don't exist. */
 | 
			
		||||
    if (!dc_isar_feature(aa32_simd_r32, s) &&
 | 
			
		||||
        ((a->vd | a->vm) & 0x10)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (a->size != 0) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((a->vd | a->vm) & a->q) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!vfp_access_check(s)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rm = tcg_temp_new_i64(tcg_ctx);
 | 
			
		||||
    rd = tcg_temp_new_i64(tcg_ctx);
 | 
			
		||||
    for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
 | 
			
		||||
        neon_load_reg64(s, rm, a->vm + pass);
 | 
			
		||||
        neon_load_reg64(s, rd, a->vd + pass);
 | 
			
		||||
        neon_store_reg64(s, rm, a->vd + pass);
 | 
			
		||||
        neon_store_reg64(s, rd, a->vm + pass);
 | 
			
		||||
    }
 | 
			
		||||
    tcg_temp_free_i64(tcg_ctx, rm);
 | 
			
		||||
    tcg_temp_free_i64(tcg_ctx, rd);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5045,6 +5045,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
 | 
			
		|||
                case NEON_2RM_VCVTPS:
 | 
			
		||||
                case NEON_2RM_VCVTMU:
 | 
			
		||||
                case NEON_2RM_VCVTMS:
 | 
			
		||||
                case NEON_2RM_VSWP:
 | 
			
		||||
                    /* handled by decodetree */
 | 
			
		||||
                    return 1;
 | 
			
		||||
                case NEON_2RM_VTRN:
 | 
			
		||||
| 
						 | 
				
			
			@ -5066,10 +5067,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
 | 
			
		|||
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
 | 
			
		||||
                        tmp = neon_load_reg(s, rm, pass);
 | 
			
		||||
                        switch (op) {
 | 
			
		||||
                        case NEON_2RM_VSWP:
 | 
			
		||||
                            tmp2 = neon_load_reg(s, rd, pass);
 | 
			
		||||
                            neon_store_reg(s, rm, pass, tmp2);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case NEON_2RM_VTRN:
 | 
			
		||||
                            tmp2 = neon_load_reg(s, rd, pass);
 | 
			
		||||
                            switch (size) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue