1 /* 2 * Constants for memory operations 3 * 4 * Authors: 5 * Richard Henderson <rth@twiddle.net> 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2 or later. 8 * See the COPYING file in the top-level directory. 9 * 10 */ 11 12 #ifndef MEMOP_H 13 #define MEMOP_H 14 15 typedef enum MemOp { 16 MO_8 = 0, 17 MO_16 = 1, 18 MO_32 = 2, 19 MO_64 = 3, 20 MO_SIZE = 3, /* Mask for the above. */ 21 22 MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */ 23 24 MO_BSWAP = 8, /* Host reverse endian. */ 25 #ifdef HOST_WORDS_BIGENDIAN 26 MO_LE = MO_BSWAP, 27 MO_BE = 0, 28 #else 29 MO_LE = 0, 30 MO_BE = MO_BSWAP, 31 #endif 32 #ifdef NEED_CPU_H 33 #ifdef TARGET_WORDS_BIGENDIAN 34 MO_TE = MO_BE, 35 #else 36 MO_TE = MO_LE, 37 #endif 38 #endif 39 40 /* 41 * MO_UNALN accesses are never checked for alignment. 42 * MO_ALIGN accesses will result in a call to the CPU's 43 * do_unaligned_access hook if the guest address is not aligned. 44 * The default depends on whether the target CPU defines 45 * TARGET_ALIGNED_ONLY. 46 * 47 * Some architectures (e.g. ARMv8) need the address which is aligned 48 * to a size more than the size of the memory access. 49 * Some architectures (e.g. SPARCv9) need an address which is aligned, 50 * but less strictly than the natural alignment. 51 * 52 * MO_ALIGN supposes the alignment size is the size of a memory access. 53 * 54 * There are three options: 55 * - unaligned access permitted (MO_UNALN). 56 * - an alignment to the size of an access (MO_ALIGN); 57 * - an alignment to a specified size, which may be more or less than 58 * the access size (MO_ALIGN_x where 'x' is a size in bytes); 59 */ 60 MO_ASHIFT = 4, 61 MO_AMASK = 7 << MO_ASHIFT, 62 #ifdef NEED_CPU_H 63 #ifdef TARGET_ALIGNED_ONLY 64 MO_ALIGN = 0, 65 MO_UNALN = MO_AMASK, 66 #else 67 MO_ALIGN = MO_AMASK, 68 MO_UNALN = 0, 69 #endif 70 #endif 71 MO_ALIGN_2 = 1 << MO_ASHIFT, 72 MO_ALIGN_4 = 2 << MO_ASHIFT, 73 MO_ALIGN_8 = 3 << MO_ASHIFT, 74 MO_ALIGN_16 = 4 << MO_ASHIFT, 75 MO_ALIGN_32 = 5 << MO_ASHIFT, 76 MO_ALIGN_64 = 6 << MO_ASHIFT, 77 78 /* Combinations of the above, for ease of use. */ 79 MO_UB = MO_8, 80 MO_UW = MO_16, 81 MO_UL = MO_32, 82 MO_SB = MO_SIGN | MO_8, 83 MO_SW = MO_SIGN | MO_16, 84 MO_SL = MO_SIGN | MO_32, 85 MO_Q = MO_64, 86 87 MO_LEUW = MO_LE | MO_UW, 88 MO_LEUL = MO_LE | MO_UL, 89 MO_LESW = MO_LE | MO_SW, 90 MO_LESL = MO_LE | MO_SL, 91 MO_LEQ = MO_LE | MO_Q, 92 93 MO_BEUW = MO_BE | MO_UW, 94 MO_BEUL = MO_BE | MO_UL, 95 MO_BESW = MO_BE | MO_SW, 96 MO_BESL = MO_BE | MO_SL, 97 MO_BEQ = MO_BE | MO_Q, 98 99 #ifdef NEED_CPU_H 100 MO_TEUW = MO_TE | MO_UW, 101 MO_TEUL = MO_TE | MO_UL, 102 MO_TESW = MO_TE | MO_SW, 103 MO_TESL = MO_TE | MO_SL, 104 MO_TEQ = MO_TE | MO_Q, 105 #endif 106 107 MO_SSIZE = MO_SIZE | MO_SIGN, 108 } MemOp; 109 110 /* Size in bytes to MemOp. */ 111 static inline unsigned size_memop(unsigned size) 112 { 113 /* 114 * FIXME: No-op to aid conversion of memory_region_dispatch_{read|write} 115 * "unsigned size" operand into a "MemOp op". 116 */ 117 return size; 118 } 119 120 #endif 121