xref: /openbmc/qemu/include/exec/memop.h (revision 4cbb198e)
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