2 * Constants for memory operations
5 * Richard Henderson <rth@twiddle.net>
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.
15 #include "qemu/host-utils.h"
26 MO_SIZE
= 0x07, /* Mask for the above. */
28 MO_SIGN
= 0x08, /* Sign-extended, otherwise zero-extended. */
30 MO_BSWAP
= 0x10, /* Host reverse endian. */
47 * MO_UNALN accesses are never checked for alignment.
48 * MO_ALIGN accesses will result in a call to the CPU's
49 * do_unaligned_access hook if the guest address is not aligned.
51 * Some architectures (e.g. ARMv8) need the address which is aligned
52 * to a size more than the size of the memory access.
53 * Some architectures (e.g. SPARCv9) need an address which is aligned,
54 * but less strictly than the natural alignment.
56 * MO_ALIGN supposes the alignment size is the size of a memory access.
58 * There are three options:
59 * - unaligned access permitted (MO_UNALN).
60 * - an alignment to the size of an access (MO_ALIGN);
61 * - an alignment to a specified size, which may be more or less than
62 * the access size (MO_ALIGN_x where 'x' is a size in bytes);
65 MO_AMASK
= 0x7 << MO_ASHIFT
,
67 MO_ALIGN_2
= 1 << MO_ASHIFT
,
68 MO_ALIGN_4
= 2 << MO_ASHIFT
,
69 MO_ALIGN_8
= 3 << MO_ASHIFT
,
70 MO_ALIGN_16
= 4 << MO_ASHIFT
,
71 MO_ALIGN_32
= 5 << MO_ASHIFT
,
72 MO_ALIGN_64
= 6 << MO_ASHIFT
,
76 * MO_ATOM_* describes the atomicity requirements of the operation:
77 * MO_ATOM_IFALIGN: the operation must be single-copy atomic if it
78 * is aligned; if unaligned there is no atomicity.
79 * MO_ATOM_IFALIGN_PAIR: the entire operation may be considered to
80 * be a pair of half-sized operations which are packed together
81 * for convenience, with single-copy atomicity on each half if
82 * the half is aligned.
83 * This is the atomicity e.g. of Arm pre-FEAT_LSE2 LDP.
84 * MO_ATOM_WITHIN16: the operation is single-copy atomic, even if it
85 * is unaligned, so long as it does not cross a 16-byte boundary;
86 * if it crosses a 16-byte boundary there is no atomicity.
87 * This is the atomicity e.g. of Arm FEAT_LSE2 LDR.
88 * MO_ATOM_WITHIN16_PAIR: the entire operation is single-copy atomic,
89 * if it happens to be within a 16-byte boundary, otherwise it
90 * devolves to a pair of half-sized MO_ATOM_WITHIN16 operations.
91 * Depending on alignment, one or both will be single-copy atomic.
92 * This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
93 * MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
94 * by the alignment. E.g. if the address is 0 mod 4, then each
95 * 4-byte subobject is single-copy atomic.
96 * This is the atomicity e.g. of IBM Power.
97 * MO_ATOM_NONE: the operation has no atomicity requirements.
99 * Note the default (i.e. 0) value is single-copy atomic to the
100 * size of the operation, if aligned. This retains the behaviour
101 * from before this field was introduced.
104 MO_ATOM_IFALIGN
= 0 << MO_ATOM_SHIFT
,
105 MO_ATOM_IFALIGN_PAIR
= 1 << MO_ATOM_SHIFT
,
106 MO_ATOM_WITHIN16
= 2 << MO_ATOM_SHIFT
,
107 MO_ATOM_WITHIN16_PAIR
= 3 << MO_ATOM_SHIFT
,
108 MO_ATOM_SUBALIGN
= 4 << MO_ATOM_SHIFT
,
109 MO_ATOM_NONE
= 5 << MO_ATOM_SHIFT
,
110 MO_ATOM_MASK
= 7 << MO_ATOM_SHIFT
,
112 /* Combinations of the above, for ease of use. */
118 MO_SB
= MO_SIGN
| MO_8
,
119 MO_SW
= MO_SIGN
| MO_16
,
120 MO_SL
= MO_SIGN
| MO_32
,
121 MO_SQ
= MO_SIGN
| MO_64
,
122 MO_SO
= MO_SIGN
| MO_128
,
124 MO_LEUW
= MO_LE
| MO_UW
,
125 MO_LEUL
= MO_LE
| MO_UL
,
126 MO_LEUQ
= MO_LE
| MO_UQ
,
127 MO_LESW
= MO_LE
| MO_SW
,
128 MO_LESL
= MO_LE
| MO_SL
,
129 MO_LESQ
= MO_LE
| MO_SQ
,
131 MO_BEUW
= MO_BE
| MO_UW
,
132 MO_BEUL
= MO_BE
| MO_UL
,
133 MO_BEUQ
= MO_BE
| MO_UQ
,
134 MO_BESW
= MO_BE
| MO_SW
,
135 MO_BESL
= MO_BE
| MO_SL
,
136 MO_BESQ
= MO_BE
| MO_SQ
,
139 MO_TEUW
= MO_TE
| MO_UW
,
140 MO_TEUL
= MO_TE
| MO_UL
,
141 MO_TEUQ
= MO_TE
| MO_UQ
,
142 MO_TEUO
= MO_TE
| MO_UO
,
143 MO_TESW
= MO_TE
| MO_SW
,
144 MO_TESL
= MO_TE
| MO_SL
,
145 MO_TESQ
= MO_TE
| MO_SQ
,
148 MO_SSIZE
= MO_SIZE
| MO_SIGN
,
151 /* MemOp to size in bytes. */
152 static inline unsigned memop_size(MemOp op
)
154 return 1 << (op
& MO_SIZE
);
157 /* Size in bytes to MemOp. */
158 static inline MemOp
size_memop(unsigned size
)
160 #ifdef CONFIG_DEBUG_TCG
161 /* Power of 2 up to 8. */
162 assert((size
& (size
- 1)) == 0 && size
>= 1 && size
<= 8);
167 /* Big endianness from MemOp. */
168 static inline bool memop_big_endian(MemOp op
)
170 return (op
& MO_BSWAP
) == MO_BE
;