mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 14:14:57 +00:00 
			
		
		
		
	tcg: Adjust simd_desc size encoding
With larger vector sizes, it turns out oprsz == maxsz, and we only need to represent mismatch for oprsz <= 32. We do, however, need to represent larger oprsz and do so without reducing SIMD_DATA_BITS. Reduce the size of the oprsz field and increase the maxsz field. Steal the oprsz value of 24 to indicate equality with maxsz. Backports e2e7168a214b0ed98dc357bba96816486a289762
This commit is contained in:
		
							parent
							
								
									567fa21c65
								
							
						
					
					
						commit
						1551f6be9d
					
				| 
						 | 
					@ -20,29 +20,41 @@
 | 
				
			||||||
#ifndef TCG_TCG_GVEC_DESC_H
 | 
					#ifndef TCG_TCG_GVEC_DESC_H
 | 
				
			||||||
#define TCG_TCG_GVEC_DESC_H
 | 
					#define TCG_TCG_GVEC_DESC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ??? These bit widths are set for ARM SVE, maxing out at 256 byte vectors. */
 | 
					/*
 | 
				
			||||||
#define SIMD_OPRSZ_SHIFT   0
 | 
					 * This configuration allows MAXSZ to represent 2048 bytes, and
 | 
				
			||||||
#define SIMD_OPRSZ_BITS    5
 | 
					 * OPRSZ to match MAXSZ, or represent the smaller values 8, 16, or 32.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Encode this with:
 | 
				
			||||||
 | 
					 *   0, 1, 3 -> 8, 16, 32
 | 
				
			||||||
 | 
					 *   2       -> maxsz
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This steals the input that would otherwise map to 24 to match maxsz.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SIMD_MAXSZ_SHIFT   0
 | 
				
			||||||
 | 
					#define SIMD_MAXSZ_BITS    8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SIMD_MAXSZ_SHIFT   (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
 | 
					#define SIMD_OPRSZ_SHIFT   (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
 | 
				
			||||||
#define SIMD_MAXSZ_BITS    5
 | 
					#define SIMD_OPRSZ_BITS    2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SIMD_DATA_SHIFT    (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
 | 
					#define SIMD_DATA_SHIFT    (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
 | 
				
			||||||
#define SIMD_DATA_BITS     (32 - SIMD_DATA_SHIFT)
 | 
					#define SIMD_DATA_BITS     (32 - SIMD_DATA_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Create a descriptor from components.  */
 | 
					/* Create a descriptor from components.  */
 | 
				
			||||||
uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data);
 | 
					uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Extract the operation size from a descriptor.  */
 | 
					 | 
				
			||||||
static inline intptr_t simd_oprsz(uint32_t desc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS) + 1) * 8;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Extract the max vector size from a descriptor.  */
 | 
					/* Extract the max vector size from a descriptor.  */
 | 
				
			||||||
static inline intptr_t simd_maxsz(uint32_t desc)
 | 
					static inline intptr_t simd_maxsz(uint32_t desc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return (extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) + 1) * 8;
 | 
					    return extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) * 8 + 8;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract the operation size from a descriptor.  */
 | 
				
			||||||
 | 
					static inline intptr_t simd_oprsz(uint32_t desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t f = extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS);
 | 
				
			||||||
 | 
					    intptr_t o = f * 8 + 8;
 | 
				
			||||||
 | 
					    intptr_t m = simd_maxsz(desc);
 | 
				
			||||||
 | 
					    return f == 2 ? m : o;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Extract the operation-specific data from a descriptor.  */
 | 
					/* Extract the operation-specific data from a descriptor.  */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,11 +37,21 @@ static const TCGOpcode vecop_list_empty[1] = { 0 };
 | 
				
			||||||
   of the operand offsets so that we can check them all at once.  */
 | 
					   of the operand offsets so that we can check them all at once.  */
 | 
				
			||||||
static void check_size_align(uint32_t oprsz, uint32_t maxsz, uint32_t ofs)
 | 
					static void check_size_align(uint32_t oprsz, uint32_t maxsz, uint32_t ofs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t opr_align = oprsz >= 16 ? 15 : 7;
 | 
					    uint32_t max_align;
 | 
				
			||||||
    uint32_t max_align = maxsz >= 16 || oprsz >= 16 ? 15 : 7;
 | 
					
 | 
				
			||||||
    tcg_debug_assert(oprsz > 0);
 | 
					    switch (oprsz) {
 | 
				
			||||||
    tcg_debug_assert(oprsz <= maxsz);
 | 
					    case 8:
 | 
				
			||||||
    tcg_debug_assert((oprsz & opr_align) == 0);
 | 
					    case 16:
 | 
				
			||||||
 | 
					    case 32:
 | 
				
			||||||
 | 
					        tcg_debug_assert(oprsz <= maxsz);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        tcg_debug_assert(oprsz == maxsz);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    tcg_debug_assert(maxsz <= (8 << SIMD_MAXSZ_BITS));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    max_align = maxsz >= 16 ? 15 : 7;
 | 
				
			||||||
    tcg_debug_assert((maxsz & max_align) == 0);
 | 
					    tcg_debug_assert((maxsz & max_align) == 0);
 | 
				
			||||||
    tcg_debug_assert((ofs & max_align) == 0);
 | 
					    tcg_debug_assert((ofs & max_align) == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue