 be5c4787e9
			
		
	
	
		be5c4787e9
		
	
	
	
	
		
			
			Preparation for collapsing the two byte swaps adjust_endianness and handle_bswap into the former. Signed-off-by: Tony Nguyen <tony.nguyen@bt.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <755b7104410956b743e1f1e9c34ab87db113360f.1566466906.git.tony.nguyen@bt.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Constants for memory operations
 | |
|  *
 | |
|  * Authors:
 | |
|  *  Richard Henderson <rth@twiddle.net>
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | |
|  * See the COPYING file in the top-level directory.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef MEMOP_H
 | |
| #define MEMOP_H
 | |
| 
 | |
| #include "qemu/host-utils.h"
 | |
| 
 | |
| typedef enum MemOp {
 | |
|     MO_8     = 0,
 | |
|     MO_16    = 1,
 | |
|     MO_32    = 2,
 | |
|     MO_64    = 3,
 | |
|     MO_SIZE  = 3,   /* Mask for the above.  */
 | |
| 
 | |
|     MO_SIGN  = 4,   /* Sign-extended, otherwise zero-extended.  */
 | |
| 
 | |
|     MO_BSWAP = 8,   /* Host reverse endian.  */
 | |
| #ifdef HOST_WORDS_BIGENDIAN
 | |
|     MO_LE    = MO_BSWAP,
 | |
|     MO_BE    = 0,
 | |
| #else
 | |
|     MO_LE    = 0,
 | |
|     MO_BE    = MO_BSWAP,
 | |
| #endif
 | |
| #ifdef NEED_CPU_H
 | |
| #ifdef TARGET_WORDS_BIGENDIAN
 | |
|     MO_TE    = MO_BE,
 | |
| #else
 | |
|     MO_TE    = MO_LE,
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
|     /*
 | |
|      * MO_UNALN accesses are never checked for alignment.
 | |
|      * MO_ALIGN accesses will result in a call to the CPU's
 | |
|      * do_unaligned_access hook if the guest address is not aligned.
 | |
|      * The default depends on whether the target CPU defines
 | |
|      * TARGET_ALIGNED_ONLY.
 | |
|      *
 | |
|      * Some architectures (e.g. ARMv8) need the address which is aligned
 | |
|      * to a size more than the size of the memory access.
 | |
|      * Some architectures (e.g. SPARCv9) need an address which is aligned,
 | |
|      * but less strictly than the natural alignment.
 | |
|      *
 | |
|      * MO_ALIGN supposes the alignment size is the size of a memory access.
 | |
|      *
 | |
|      * There are three options:
 | |
|      * - unaligned access permitted (MO_UNALN).
 | |
|      * - an alignment to the size of an access (MO_ALIGN);
 | |
|      * - an alignment to a specified size, which may be more or less than
 | |
|      *   the access size (MO_ALIGN_x where 'x' is a size in bytes);
 | |
|      */
 | |
|     MO_ASHIFT = 4,
 | |
|     MO_AMASK = 7 << MO_ASHIFT,
 | |
| #ifdef NEED_CPU_H
 | |
| #ifdef TARGET_ALIGNED_ONLY
 | |
|     MO_ALIGN = 0,
 | |
|     MO_UNALN = MO_AMASK,
 | |
| #else
 | |
|     MO_ALIGN = MO_AMASK,
 | |
|     MO_UNALN = 0,
 | |
| #endif
 | |
| #endif
 | |
|     MO_ALIGN_2  = 1 << MO_ASHIFT,
 | |
|     MO_ALIGN_4  = 2 << MO_ASHIFT,
 | |
|     MO_ALIGN_8  = 3 << MO_ASHIFT,
 | |
|     MO_ALIGN_16 = 4 << MO_ASHIFT,
 | |
|     MO_ALIGN_32 = 5 << MO_ASHIFT,
 | |
|     MO_ALIGN_64 = 6 << MO_ASHIFT,
 | |
| 
 | |
|     /* Combinations of the above, for ease of use.  */
 | |
|     MO_UB    = MO_8,
 | |
|     MO_UW    = MO_16,
 | |
|     MO_UL    = MO_32,
 | |
|     MO_SB    = MO_SIGN | MO_8,
 | |
|     MO_SW    = MO_SIGN | MO_16,
 | |
|     MO_SL    = MO_SIGN | MO_32,
 | |
|     MO_Q     = MO_64,
 | |
| 
 | |
|     MO_LEUW  = MO_LE | MO_UW,
 | |
|     MO_LEUL  = MO_LE | MO_UL,
 | |
|     MO_LESW  = MO_LE | MO_SW,
 | |
|     MO_LESL  = MO_LE | MO_SL,
 | |
|     MO_LEQ   = MO_LE | MO_Q,
 | |
| 
 | |
|     MO_BEUW  = MO_BE | MO_UW,
 | |
|     MO_BEUL  = MO_BE | MO_UL,
 | |
|     MO_BESW  = MO_BE | MO_SW,
 | |
|     MO_BESL  = MO_BE | MO_SL,
 | |
|     MO_BEQ   = MO_BE | MO_Q,
 | |
| 
 | |
| #ifdef NEED_CPU_H
 | |
|     MO_TEUW  = MO_TE | MO_UW,
 | |
|     MO_TEUL  = MO_TE | MO_UL,
 | |
|     MO_TESW  = MO_TE | MO_SW,
 | |
|     MO_TESL  = MO_TE | MO_SL,
 | |
|     MO_TEQ   = MO_TE | MO_Q,
 | |
| #endif
 | |
| 
 | |
|     MO_SSIZE = MO_SIZE | MO_SIGN,
 | |
| } MemOp;
 | |
| 
 | |
| /* MemOp to size in bytes.  */
 | |
| static inline unsigned memop_size(MemOp op)
 | |
| {
 | |
|     return 1 << (op & MO_SIZE);
 | |
| }
 | |
| 
 | |
| /* Size in bytes to MemOp.  */
 | |
| static inline MemOp size_memop(unsigned size)
 | |
| {
 | |
| #ifdef CONFIG_DEBUG_TCG
 | |
|     /* Power of 2 up to 8.  */
 | |
|     assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
 | |
| #endif
 | |
|     return ctz32(size);
 | |
| }
 | |
| 
 | |
| /* Big endianness from MemOp.  */
 | |
| static inline bool memop_big_endian(MemOp op)
 | |
| {
 | |
|     return (op & MO_BSWAP) == MO_BE;
 | |
| }
 | |
| 
 | |
| #endif
 |